-
Notifications
You must be signed in to change notification settings - Fork 0
Spending from cold storage, P2SH or other exotic inputs with CoinJoin
create-unsigned-tx.py is a bot that creates CoinJoin transactions that spend from user-given input UTXOs (Unspent Transaction Outputs). The script returns a partially-signed transaction which the user has to sign and broadcast themselves using other tools.
Example uses are for spending from cold storage where the private key must not be on an internet-connected machine, or for spending from a p2sh multisig address where multiple people must sign the transaction. The script obtains transaction inputs and signatures from makers. Note that makers are under no obligation not to double-spend their inputs until they see a complete transaction broadcast on the bitcoin network. If those makers get another coinjoin deal, they may use the same UTXOs. Therefore a user of create-unsigned-tx.py
must be quick in signing and broadcasting their transaction.
Warning: Directly manipulating ECDSA private keys and bitcoin raw transaction is dangerous and can result in losing money. See discussion here and here. This script is for advanced users only. Always carefully check transactions before signing and broadcasting them.
Testnet is used for all examples here. It's highly recommended to get comfortable with them before trying this with real bitcoins. Read python create-unsigned-tx.py --help
for a detailed view of the options and ordering of arguments. Many options are similar to ones used in sendpayment.py
In the JoinMarket protocol, communication is encrypted and authenticated between taker and maker. One of the pay-to-pubkey-hash inputs is used to authenticate the encrypted channel. The UTXO doesn't have to be worth much bitcoin but it and it's private key must be there. Note that the private key is prompted for on stdin to stop it appearing in .bash_history
or ps
.
For the auth UTXO we will use 0531dec28f2436787bb9c638779f8a46ffcb20fcc9360664a6353b57cbf7a2ad:2
which is on the address myLumLZykEuvNhL4WP4HJ5wkGZLRc55wih
and has a corresponding private key cPWeLjzahLWtx7Bq1ro7f5b2sikU7H3eJAFueGrWczanq4urg1Wr
.
We want to spend from the UTXO d056b6160f7181f61f3d3f85a187432b1cd4ba3f1bb32e24d414e0b659227a47:1
from cold storage. We'll be sending 1btc to mrooPrd91PauYzeW8ekLfEX9zdFwa8UBzk
with change going back to cold storage in mnGeND9aE14sdaSGu2XauHqwu3C5x52HDh
. These UTXOs can be found using a web API or the listunspent
command on many popular wallets like Bitcoin Core or Electrum.
Run the JoinMarket script.
$ python create-unsigned-tx.py -N 1 0531dec28f2436787bb9c638779f8a46ffcb20fcc9360664a6353b57cbf7a2ad:2 100000000 mrooPrd91PauYzeW8ekLfEX9zdFwa8UBzk mnGeND9aE14sdaSGu2XauHqwu3C5x52HDh d056b6160f7181f61f3d3f85a187432b1cd4ba3f1bb32e24d414e0b659227a47:1
Input the private key of the auth UTXO when prompted.
input private key for myLumLZykEuvNhL4WP4HJ5wkGZLRc55wih :cPWeLjzahLWtx7Bq1ro7f5b2sikU7H3eJAFueGrWczanq4urg1Wr
Allow the bot to connect to the marketplace and create the coinjoin deal. Finally we see
[2015/10/03 19:14:23] timeout thread woken by notify(), makers responded in time
unsigned tx =
0100000003ada2f7cb573b35a6640636c9fc20cbff468a9f7738c6b97b7836248fc2de3105040000006a473044022034516f89b849b97eb0ea373cc61563c193df77e2a8f1ceca6b83627cb41a71020220788495dc320076e6891ebd8b7ec27930f6f3ec71c24d369bf1eefb5e66877c46012102505afd8cf9f31b6fdd60d686a270a3fd1e2a9e5f266714184ac6c4e9d2f5db29ffffffffada2f7cb573b35a6640636c9fc20cbff468a9f7738c6b97b7836248fc2de3105020000006b483045022100fbd4235492e70ca10902046bdc98272d244d48010c2d603345cc0cca035bf775022062b8d5e979c34e71410351e202d8930d6d23b700ee0565dc68cc7099807792a8012102b6857d182cdf24ccd6d4e90590d846ec4fe8a4de3a1708b8c2c6d28f28c22465ffffffff477a2259b6e014d4242eb31b3fbad41c2b4387a1853f3d1ff681710f16b656d00100000000ffffffff0400e1f505000000001976a9147bd90691aa0c77ad65ca7258a4564ca02b9b9e4288ac00e1f505000000001976a9148796d5545d1141d44fa89b527f37112dc320719a88acd7cad802000000001976a9144a141758a37c5e39f97caef7becf5169fea27cd188ac3ac3a900000000001976a9140def9bc5fbcf0e103cc669f538ae73377f80e30688ac00000000
[2015/10/03 19:14:23] created unsigned tx, ending
That transaction hex string can be transfered to cold storage and signed in the usual way. After broadcasting the result is http://tbtc.blockr.io/tx/info/e5ec00488acee87927290d1fde9ac959d8ea0f2228ef581ec93ca3bf172a157f
It is worth understanding non-coinjoin multisig transactions first, read TwoOfThree.sh
A 2-of-3 multisig address is created from the public keys 03fade4e24512a85baf101e3c089d4c53f8c1ef75dbc5e78c6bb8af6c0444e2a56
, 03764d38ce619fb3bdc6af99a9adab7e2602beee0a49ba72af32cc5d754bca49b2
and 0245c2e341f758044c0ae46287d41e2d45489188f126bfdd469c73395cde18d344
. The corresponding private keys of the first two are cRgXFhZU1Nq6bBotwahUt6jqNzovsDyviRyZoVXkRqHCg1cH8QRF
and cPzhgGZHZBVsS9mi5c9tqB1EhZmz7Jcz566XTugSF3BDvKHHhhx6
. We use the Bitcoin Core RPC console.
createmultisig 2 '["03fade4e24512a85baf101e3c089d4c53f8c1ef75dbc5e78c6bb8af6c0444e2a56", "03764d38ce619fb3bdc6af99a9adab7e2602beee0a49ba72af32cc5d754bca49b2", "0245c2e341f758044c0ae46287d41e2d45489188f126bfdd469c73395cde18d344"]'
{
"address" : "2MwShYED1vTnMFvADW5W5be3XsBDutnmyP2",
"redeemScript" : "522103fade4e24512a85baf101e3c089d4c53f8c1ef75dbc5e78c6bb8af6c0444e2a562103764d38ce619fb3bdc6af99a9adab7e2602beee0a49ba72af32cc5d754bca49b2210245c2e341f758044c0ae46287d41e2d45489188f126bfdd469c73395cde18d34453ae"
}
We send 0.1btc to the address 2MwShYED1vTnMFvADW5W5be3XsBDutnmyP2
with a normal bitcoin wallet. The resulting UTXO is f7ac52d7b0fb19f8622205d2238b917e1519bd36af20b05e18fde4a319f33053:1
. We use f062fec8fbc50025762d112d3f4bd9981a88a94baea9cb6c4a60e978b404083a:0
as the auth_utxo for the JoinMarket protocol.
We run the JoinMarket script with amount = 0 to sweep the entire amount into the coinjoin address mjeYBCV8ZNmx5fkDe5f9z4fnroV3FCXgBt
without any remaining change.
python create-unsigned-tx.py -N 1 f062fec8fbc50025762d112d3f4bd9981a88a94baea9cb6c4a60e978b404083a:0 0 mjeYBCV8ZNmx5fkDe5f9z4fnroV3FCXgBt any-string-here f7ac52d7b0fb19f8622205d2238b917e1519bd36af20b05e18fde4a319f33053:1
The resulting unsigned transaction hex string is:
01000000035330f319a3e4fd185eb020af36bd19157e918b23d2052262f819fbb0d752acf70100000000ffffffff3a0804b478e9604a6ccba9ae4ba9881a98d94b3f2d112d762500c5fbc8fe62f0000000006b483045022100d28cddb67a942d118a1b1a85d670989ad7d6255210d4a504e0a24e5ae215566102207ff694b62f2c284a5aa38ea667e95d28b114318dad430b8c7872e7997499e9a50121037a2f98d23387b9cfafb6b311e9f222bb76466335334d8769fe647be57f036e11fffffffff2b72aa082e43e54bcc600d9653a82d979ae3231ac0722800d39b4febafd6ced000000006a47304402206523a8173d3cc05ddebe075425a8a19ad9097419a03693e6e5c8d4b738376b62022077ddf61f62b916d10caeeb150e39cc90417656e0e3801e09ed515208f59c8f9f01210223def164e930529eb9962eb3377fe3666e56755dbc05ed45ee36f9411e22414fffffffff03140be700000000001976a91412eef8dde4c5e4b6ea8e1499bc74d338b6772cd288acbe62c108000000001976a9143e95f4785e3f9ad6246b579d9db4f704726f595388ac140be700000000001976a9142d4fb2ae8c4d0994cf7c027db68fabae121fcdaa88ac00000000
We use Bitcoin Core RPC calls to sign the multisig input. Note that the scriptPubKey of the multisig address is a9142e0c13b238506bc58d1e62dfe89d0c4eb7f6ecff87
. It is simply the decoded bitcoin address, it can be found by using the gettxout
RPC call, or the address_to_script
method from pybitcointools.
Signing with the first private key:
signrawtransaction '01000000035330f319a3e4fd185eb020af36bd19157e918b23d2052262f819fbb0d752acf70100000000ffffffff3a0804b478e9604a6ccba9ae4ba9881a98d94b3f2d112d762500c5fbc8fe62f0000000006b483045022100d28cddb67a942d118a1b1a85d670989ad7d6255210d4a504e0a24e5ae215566102207ff694b62f2c284a5aa38ea667e95d28b114318dad430b8c7872e7997499e9a50121037a2f98d23387b9cfafb6b311e9f222bb76466335334d8769fe647be57f036e11fffffffff2b72aa082e43e54bcc600d9653a82d979ae3231ac0722800d39b4febafd6ced000000006a47304402206523a8173d3cc05ddebe075425a8a19ad9097419a03693e6e5c8d4b738376b62022077ddf61f62b916d10caeeb150e39cc90417656e0e3801e09ed515208f59c8f9f01210223def164e930529eb9962eb3377fe3666e56755dbc05ed45ee36f9411e22414fffffffff03140be700000000001976a91412eef8dde4c5e4b6ea8e1499bc74d338b6772cd288acbe62c108000000001976a9143e95f4785e3f9ad6246b579d9db4f704726f595388ac140be700000000001976a9142d4fb2ae8c4d0994cf7c027db68fabae121fcdaa88ac00000000' '[{"txid":"f7ac52d7b0fb19f8622205d2238b917e1519bd36af20b05e18fde4a319f33053","vout":1,"scriptPubKey":"a9142e0c13b238506bc58d1e62dfe89d0c4eb7f6ecff87","redeemScript":"522103fade4e24512a85baf101e3c089d4c53f8c1ef75dbc5e78c6bb8af6c0444e2a562103764d38ce619fb3bdc6af99a9adab7e2602beee0a49ba72af32cc5d754bca49b2210245c2e341f758044c0ae46287d41e2d45489188f126bfdd469c73395cde18d34453ae"}]' '["cRgXFhZU1Nq6bBotwahUt6jqNzovsDyviRyZoVXkRqHCg1cH8QRF"]'
{
"hex" : "01000000035330f319a3e4fd185eb020af36bd19157e918b23d2052262f819fbb0d752acf701000000b400473044022001d80b53c7dff703353c082a8507eae5a9779741ba17727a954b2a755af09bf402203a5df57af08f30bd9fbbbebb40fe74434538c494c98fccd63ddbd788d480550f014c69522103fade4e24512a85baf101e3c089d4c53f8c1ef75dbc5e78c6bb8af6c0444e2a562103764d38ce619fb3bdc6af99a9adab7e2602beee0a49ba72af32cc5d754bca49b2210245c2e341f758044c0ae46287d41e2d45489188f126bfdd469c73395cde18d34453aeffffffff3a0804b478e9604a6ccba9ae4ba9881a98d94b3f2d112d762500c5fbc8fe62f0000000006b483045022100d28cddb67a942d118a1b1a85d670989ad7d6255210d4a504e0a24e5ae215566102207ff694b62f2c284a5aa38ea667e95d28b114318dad430b8c7872e7997499e9a50121037a2f98d23387b9cfafb6b311e9f222bb76466335334d8769fe647be57f036e11fffffffff2b72aa082e43e54bcc600d9653a82d979ae3231ac0722800d39b4febafd6ced000000006a47304402206523a8173d3cc05ddebe075425a8a19ad9097419a03693e6e5c8d4b738376b62022077ddf61f62b916d10caeeb150e39cc90417656e0e3801e09ed515208f59c8f9f01210223def164e930529eb9962eb3377fe3666e56755dbc05ed45ee36f9411e22414fffffffff03140be700000000001976a91412eef8dde4c5e4b6ea8e1499bc74d338b6772cd288acbe62c108000000001976a9143e95f4785e3f9ad6246b579d9db4f704726f595388ac140be700000000001976a9142d4fb2ae8c4d0994cf7c027db68fabae121fcdaa88ac00000000",
"complete" : false
}
Signing with the second private key
signrawtransaction '01000000035330f319a3e4fd185eb020af36bd19157e918b23d2052262f819fbb0d752acf701000000b400473044022001d80b53c7dff703353c082a8507eae5a9779741ba17727a954b2a755af09bf402203a5df57af08f30bd9fbbbebb40fe74434538c494c98fccd63ddbd788d480550f014c69522103fade4e24512a85baf101e3c089d4c53f8c1ef75dbc5e78c6bb8af6c0444e2a562103764d38ce619fb3bdc6af99a9adab7e2602beee0a49ba72af32cc5d754bca49b2210245c2e341f758044c0ae46287d41e2d45489188f126bfdd469c73395cde18d34453aeffffffff3a0804b478e9604a6ccba9ae4ba9881a98d94b3f2d112d762500c5fbc8fe62f0000000006b483045022100d28cddb67a942d118a1b1a85d670989ad7d6255210d4a504e0a24e5ae215566102207ff694b62f2c284a5aa38ea667e95d28b114318dad430b8c7872e7997499e9a50121037a2f98d23387b9cfafb6b311e9f222bb76466335334d8769fe647be57f036e11fffffffff2b72aa082e43e54bcc600d9653a82d979ae3231ac0722800d39b4febafd6ced000000006a47304402206523a8173d3cc05ddebe075425a8a19ad9097419a03693e6e5c8d4b738376b62022077ddf61f62b916d10caeeb150e39cc90417656e0e3801e09ed515208f59c8f9f01210223def164e930529eb9962eb3377fe3666e56755dbc05ed45ee36f9411e22414fffffffff03140be700000000001976a91412eef8dde4c5e4b6ea8e1499bc74d338b6772cd288acbe62c108000000001976a9143e95f4785e3f9ad6246b579d9db4f704726f595388ac140be700000000001976a9142d4fb2ae8c4d0994cf7c027db68fabae121fcdaa88ac00000000' '[{"txid":"f7ac52d7b0fb19f8622205d2238b917e1519bd36af20b05e18fde4a319f33053","vout":1,"scriptPubKey":"a9142e0c13b238506bc58d1e62dfe89d0c4eb7f6ecff87","redeemScript":"522103fade4e24512a85baf101e3c089d4c53f8c1ef75dbc5e78c6bb8af6c0444e2a562103764d38ce619fb3bdc6af99a9adab7e2602beee0a49ba72af32cc5d754bca49b2210245c2e341f758044c0ae46287d41e2d45489188f126bfdd469c73395cde18d34453ae"}]' '["cPzhgGZHZBVsS9mi5c9tqB1EhZmz7Jcz566XTugSF3BDvKHHhhx6"]'
{
"hex" : "01000000035330f319a3e4fd185eb020af36bd19157e918b23d2052262f819fbb0d752acf701000000fc00473044022001d80b53c7dff703353c082a8507eae5a9779741ba17727a954b2a755af09bf402203a5df57af08f30bd9fbbbebb40fe74434538c494c98fccd63ddbd788d480550f01473044022043a98ae2197e38432218597ea9fd8c7201bc98b12eeeed1dabf37e1432e854820220030c7a4b56834f4016cb54b6e009b2e4846b8f9605b7ea4ed0fd7fca44008180014c69522103fade4e24512a85baf101e3c089d4c53f8c1ef75dbc5e78c6bb8af6c0444e2a562103764d38ce619fb3bdc6af99a9adab7e2602beee0a49ba72af32cc5d754bca49b2210245c2e341f758044c0ae46287d41e2d45489188f126bfdd469c73395cde18d34453aeffffffff3a0804b478e9604a6ccba9ae4ba9881a98d94b3f2d112d762500c5fbc8fe62f0000000006b483045022100d28cddb67a942d118a1b1a85d670989ad7d6255210d4a504e0a24e5ae215566102207ff694b62f2c284a5aa38ea667e95d28b114318dad430b8c7872e7997499e9a50121037a2f98d23387b9cfafb6b311e9f222bb76466335334d8769fe647be57f036e11fffffffff2b72aa082e43e54bcc600d9653a82d979ae3231ac0722800d39b4febafd6ced000000006a47304402206523a8173d3cc05ddebe075425a8a19ad9097419a03693e6e5c8d4b738376b62022077ddf61f62b916d10caeeb150e39cc90417656e0e3801e09ed515208f59c8f9f01210223def164e930529eb9962eb3377fe3666e56755dbc05ed45ee36f9411e22414fffffffff03140be700000000001976a91412eef8dde4c5e4b6ea8e1499bc74d338b6772cd288acbe62c108000000001976a9143e95f4785e3f9ad6246b579d9db4f704726f595388ac140be700000000001976a9142d4fb2ae8c4d0994cf7c027db68fabae121fcdaa88ac00000000",
"complete" : true
}
The transaction is fully-signed, note the "complete": true
. We now broadcast it.
sendrawtransaction 01000000035330f319a3e4fd185eb020af36bd19157e918b23d2052262f819fbb0d752acf701000000fc00473044022001d80b53c7dff703353c082a8507eae5a9779741ba17727a954b2a755af09bf402203a5df57af08f30bd9fbbbebb40fe74434538c494c98fccd63ddbd788d480550f01473044022043a98ae2197e38432218597ea9fd8c7201bc98b12eeeed1dabf37e1432e854820220030c7a4b56834f4016cb54b6e009b2e4846b8f9605b7ea4ed0fd7fca44008180014c69522103fade4e24512a85baf101e3c089d4c53f8c1ef75dbc5e78c6bb8af6c0444e2a562103764d38ce619fb3bdc6af99a9adab7e2602beee0a49ba72af32cc5d754bca49b2210245c2e341f758044c0ae46287d41e2d45489188f126bfdd469c73395cde18d34453aeffffffff3a0804b478e9604a6ccba9ae4ba9881a98d94b3f2d112d762500c5fbc8fe62f0000000006b483045022100d28cddb67a942d118a1b1a85d670989ad7d6255210d4a504e0a24e5ae215566102207ff694b62f2c284a5aa38ea667e95d28b114318dad430b8c7872e7997499e9a50121037a2f98d23387b9cfafb6b311e9f222bb76466335334d8769fe647be57f036e11fffffffff2b72aa082e43e54bcc600d9653a82d979ae3231ac0722800d39b4febafd6ced000000006a47304402206523a8173d3cc05ddebe075425a8a19ad9097419a03693e6e5c8d4b738376b62022077ddf61f62b916d10caeeb150e39cc90417656e0e3801e09ed515208f59c8f9f01210223def164e930529eb9962eb3377fe3666e56755dbc05ed45ee36f9411e22414fffffffff03140be700000000001976a91412eef8dde4c5e4b6ea8e1499bc74d338b6772cd288acbe62c108000000001976a9143e95f4785e3f9ad6246b579d9db4f704726f595388ac140be700000000001976a9142d4fb2ae8c4d0994cf7c027db68fabae121fcdaa88ac00000000
d056b6160f7181f61f3d3f85a187432b1cd4ba3f1bb32e24d414e0b659227a47
The confirmed transaction: http://tbtc.blockr.io/tx/info/d056b6160f7181f61f3d3f85a187432b1cd4ba3f1bb32e24d414e0b659227a47