Bug in 2-of-3 transaction signing in Bitcoind?

Bug in 2-of-3 transaction signing in Bitcoind?
2014-04-15 15:05 ` Mike Hearn
  
From: Matt Whitlock @ 2014-04-15 15:00 UTC (permalink / raw)
  To: bitcoin-development

For the life of me, I cannot figure out what's wrong with this. It seems like Bitcoind has lost its mind. I'm trying to redeem a 2-of-3 multisig P2SH output using a raw transaction.


Here's the address that the P2SH output was sent to:

$ bitcoind createmultisig 2 '["03566474f987a012a69a08097253394ebd681454df29c3f1fb0495a5b45490f928", "03927407ca158155d0d30366395ca9cdc7d93cfa0a5b22181374431c15aae7b358", "02cff98aba464f5d4ebac5e6417f142326235f5a0a59708ba6231471cce4ee0747"]'
{
    "address" : "33snuCcVUmn9iBG345keJRzMfVwz7Uo87C",
    "redeemScript" : "522103566474f987a012a69a08097253394ebd681454df29c3f1fb0495a5b45490f9282103927407ca158155d0d30366395ca9cdc7d93cfa0a5b22181374431c15aae7b3582102cff98aba464f5d4ebac5e6417f142326235f5a0a59708ba6231471cce4ee074753ae"
}


The transaction containing the output is ec7d985ae265a3a79c68d852e0e52cf4177c3362d7a25fb718be82f980f39285. It's the second output.


So I ask Bitcoind to create a raw transaction to spend the output:

$ bitcoind createrawtransaction '[{"txid":"ec7d985ae265a3a79c68d852e0e52cf4177c3362d7a25fb718be82f980f39285", "vout":1}]' '{"19YNEu4ZqX3nU9rJMuMcDy3pzFhactZPmk":0.00050000, "1J2qtR7HBbE4rkNAgZCo4hZUEd2Z4jtSgz":0.00040000}'
01000000018592f380f982be18b75fa2d762337c17f42ce5e052d8689ca7a365e25a987dec0100000000ffffffff0250c30000000000001976a9145dafa18ab21debe3d20f2c39e88d630f822bd29e88ac409c0000000000001976a914bad35cd767b657daa4a735b32e3d1f1dab52872d88ac00000000


And here is the decoded transaction, for completeness:

$ bitcoind decoderawtransaction 01000000018592f380f982be18b75fa2d762337c17f42ce5e052d8689ca7a365e25a987dec0100000000ffffffff0250c30000000000001976a9145dafa18ab21debe3d20f2c39e88d630f822bd29e88ac409c0000000000001976a914bad35cd767b657daa4a735b32e3d1f1dab52872d88ac00000000
{
    "txid" : "8d731e6e333d805f6c8b569e1a608d14127d61d3123b699355133b2c757c16fb",
    "version" : 1,
    "locktime" : 0,
    "vin" : [
        {
            "txid" : "ec7d985ae265a3a79c68d852e0e52cf4177c3362d7a25fb718be82f980f39285",
            "vout" : 1,
            "scriptSig" : {
                "asm" : "",
                "hex" : ""
            },
            "sequence" : 4294967295
        }
    ],
    "vout" : [
        {
            "value" : 0.00050000,
            "n" : 0,
            "scriptPubKey" : {
                "asm" : "OP_DUP OP_HASH160 5dafa18ab21debe3d20f2c39e88d630f822bd29e OP_EQUALVERIFY OP_CHECKSIG",
                "hex" : "76a9145dafa18ab21debe3d20f2c39e88d630f822bd29e88ac",
                "reqSigs" : 1,
                "type" : "pubkeyhash",
                "addresses" : [
                    "19YNEu4ZqX3nU9rJMuMcDy3pzFhactZPmk"
                ]
            }
        },
        {
            "value" : 0.00040000,
            "n" : 1,
            "scriptPubKey" : {
                "asm" : "OP_DUP OP_HASH160 bad35cd767b657daa4a735b32e3d1f1dab52872d OP_EQUALVERIFY OP_CHECKSIG",
                "hex" : "76a914bad35cd767b657daa4a735b32e3d1f1dab52872d88ac",
                "reqSigs" : 1,
                "type" : "pubkeyhash",
                "addresses" : [
                    "1J2qtR7HBbE4rkNAgZCo4hZUEd2Z4jtSgz"
                ]
            }
        }
    ]
}


Now I'll sign the transaction with 2 of 3 keys:

$ bitcoind signrawtransaction 01000000018592f380f982be18b75fa2d762337c17f42ce5e052d8689ca7a365e25a987dec0100000000ffffffff0250c30000000000001976a9145dafa18ab21debe3d20f2c39e88d630f822bd29e88ac409c0000000000001976a914bad35cd767b657daa4a735b32e3d1f1dab52872d88ac00000000 '[{"txid":"ec7d985ae265a3a79c68d852e0e52cf4177c3362d7a25fb718be82f980f39285", "vout":1, "scriptPubKey":"a91417f9f4ba5c2f2b9334805f91bbbf90a19aaa3d5687", "redeemScript":"522103566474f987a012a69a08097253394ebd681454df29c3f1fb0495a5b45490f9282103927407ca158155d0d30366395ca9cdc7d93cfa0a5b22181374431c15aae7b3582102cff98aba464f5d4ebac5e6417f142326235f5a0a59708ba6231471cce4ee074753ae"}]' '["Ky7EQeg71YHeftLc31tt8AoNSezFEgUCbvwYak1eKksg6gQww6FF", "KxAXrjTMZJN1Egqkckdz9TXyB2kyJ68wu7CiJk6Rygmr9zv2nScG"]'
{
    "hex" : "01000000018592f380f982be18b75fa2d762337c17f42ce5e052d8689ca7a365e25a987dec01000000fc004730440220781ae7e3e309289f53cc2c4016adfb5a1d0081157d4366b9f77f0358b7aeccbb022009c7297f60088b1815d6970c8e246e6b516ff8fce5e85de209004d8cc29e460201473044022018a23405ca72c52222577f78c2356bdb8ba36259edb1320b90e2c31188e6317602201972db07bf5ef8e30221d3707ce6eb7ab748527ec8e7ca14241350920f03257f014c69522103566474f987a012a69a08097253394ebd681454df29c3f1fb0495a5b45490f9282103927407ca158155d0d30366395ca9cdc7d93cfa0a5b22181374431c15aae7b3582102cff98aba464f5d4ebac5e6417f142326235f5a0a59708ba6231471cce4ee074753aeffffffff0250c30000000000001976a9145dafa18ab21debe3d20f2c39e88d630f822bd29e88ac409c0000000000001976a914bad35cd767b657daa4a735b32e3d1f1dab52872d88ac00000000",
    "complete" : true
}


And here's the decode of the signed transaction:

$ bitcoind decoderawtransaction 01000000018592f380f982be18b75fa2d762337c17f42ce5e052d8689ca7a365e25a987dec01000000fc004730440220781ae7e3e309289f53cc2c4016adfb5a1d0081157d4366b9f77f0358b7aeccbb022009c7297f60088b1815d6970c8e246e6b516ff8fce5e85de209004d8cc29e460201473044022018a23405ca72c52222577f78c2356bdb8ba36259edb1320b90e2c31188e6317602201972db07bf5ef8e30221d3707ce6eb7ab748527ec8e7ca14241350920f03257f014c69522103566474f987a012a69a08097253394ebd681454df29c3f1fb0495a5b45490f9282103927407ca158155d0d30366395ca9cdc7d93cfa0a5b22181374431c15aae7b3582102cff98aba464f5d4ebac5e6417f142326235f5a0a59708ba6231471cce4ee074753aeffffffff0250c30000000000001976a9145dafa18ab21debe3d20f2c39e88d630f822bd29e88ac409c0000000000001976a914bad35cd767b657daa4a735b32e3d1f1dab52872d88ac00000000
{
    "txid" : "a01bff867229de4bb622b0ebdd8cd293d6b9ad2fb576612974ae89ed5798eb3e",
    "version" : 1,
    "locktime" : 0,
    "vin" : [
        {
            "txid" : "ec7d985ae265a3a79c68d852e0e52cf4177c3362d7a25fb718be82f980f39285",
            "vout" : 1,
            "scriptSig" : {
                "asm" : "0 30440220781ae7e3e309289f53cc2c4016adfb5a1d0081157d4366b9f77f0358b7aeccbb022009c7297f60088b1815d6970c8e246e6b516ff8fce5e85de209004d8cc29e460201 3044022018a23405ca72c52222577f78c2356bdb8ba36259edb1320b90e2c31188e6317602201972db07bf5ef8e30221d3707ce6eb7ab748527ec8e7ca14241350920f03257f01 522103566474f987a012a69a08097253394ebd681454df29c3f1fb0495a5b45490f9282103927407ca158155d0d30366395ca9cdc7d93cfa0a5b22181374431c15aae7b3582102cff98aba464f5d4ebac5e6417f142326235f5a0a59708ba6231471cce4ee074753ae",
                "hex" : "004730440220781ae7e3e309289f53cc2c4016adfb5a1d0081157d4366b9f77f0358b7aeccbb022009c7297f60088b1815d6970c8e246e6b516ff8fce5e85de209004d8cc29e460201473044022018a23405ca72c52222577f78c2356bdb8ba36259edb1320b90e2c31188e6317602201972db07bf5ef8e30221d3707ce6eb7ab748527ec8e7ca14241350920f03257f014c69522103566474f987a012a69a08097253394ebd681454df29c3f1fb0495a5b45490f9282103927407ca158155d0d30366395ca9cdc7d93cfa0a5b22181374431c15aae7b3582102cff98aba464f5d4ebac5e6417f142326235f5a0a59708ba6231471cce4ee074753ae"
            },
            "sequence" : 4294967295
        }
    ],
    "vout" : [
        {
            "value" : 0.00050000,
            "n" : 0,
            "scriptPubKey" : {
                "asm" : "OP_DUP OP_HASH160 5dafa18ab21debe3d20f2c39e88d630f822bd29e OP_EQUALVERIFY OP_CHECKSIG",
                "hex" : "76a9145dafa18ab21debe3d20f2c39e88d630f822bd29e88ac",
                "reqSigs" : 1,
                "type" : "pubkeyhash",
                "addresses" : [
                    "19YNEu4ZqX3nU9rJMuMcDy3pzFhactZPmk"
                ]
            }
        },
        {
            "value" : 0.00040000,
            "n" : 1,
            "scriptPubKey" : {
                "asm" : "OP_DUP OP_HASH160 bad35cd767b657daa4a735b32e3d1f1dab52872d OP_EQUALVERIFY OP_CHECKSIG",
                "hex" : "76a914bad35cd767b657daa4a735b32e3d1f1dab52872d88ac",
                "reqSigs" : 1,
                "type" : "pubkeyhash",
                "addresses" : [
                    "1J2qtR7HBbE4rkNAgZCo4hZUEd2Z4jtSgz"
                ]
            }
        }
    ]
}


And now I'll try to transmit the transaction to the network:

$ bitcoind sendrawtransaction 01000000018592f380f982be18b75fa2d762337c17f42ce5e052d8689ca7a365e25a987dec01000000fc004730440220781ae7e3e309289f53cc2c4016adfb5a1d0081157d4366b9f77f0358b7aeccbb022009c7297f60088b1815d6970c8e246e6b516ff8fce5e85de209004d8cc29e460201473044022018a23405ca72c52222577f78c2356bdb8ba36259edb1320b90e2c31188e6317602201972db07bf5ef8e30221d3707ce6eb7ab748527ec8e7ca14241350920f03257f014c69522103566474f987a012a69a08097253394ebd681454df29c3f1fb0495a5b45490f9282103927407ca158155d0d30366395ca9cdc7d93cfa0a5b22181374431c15aae7b3582102cff98aba464f5d4ebac5e6417f142326235f5a0a59708ba6231471cce4ee074753aeffffffff0250c30000000000001976a9145dafa18ab21debe3d20f2c39e88d630f822bd29e88ac409c0000000000001976a914bad35cd767b657daa4a735b32e3d1f1dab52872d88ac00000000
error: {"code":-22,"message":"TX rejected"}


Whoops!

So, what gives?



 permalink raw reply	[|nested]
2014-04-15 15:00 [Bitcoin-development] Bug in 2-of-3 transaction signing in Bitcoind? Matt Whitlock

  2014-04-15 15:11   ` Pieter Wuille
  
From: Mike Hearn @ 2014-04-15 15:05 UTC (permalink / raw)
  To: Matt Whitlock;  Bitcoin Dev

[-- Attachment #1: Type: text/plain, Size: 56 bytes --]

Check debug.log to find out the reason it was rejected.

[-- Attachment #2: Type: text/html, Size: 116 bytes --]

 permalink raw reply	[|nested]
2014-04-15 15:05 ` Mike Hearn

  2014-04-15 15:22     ` Matt Whitlock
  
From: Pieter Wuille @ 2014-04-15 15:11 UTC (permalink / raw)
  To: Mike Hearn;  Bitcoin Dev

The first input seems to be already spent by another transaction
(which looks very similar).

0.9 should report a more detailed reason for rejection, by the way.



On Tue, Apr 15, 2014 at 5:05 PM, Mike Hearn <mike@plan99•net> wrote:
> Check debug.log to find out the reason it was rejected.
>
>
>
> ------------------------------------------------------------------------------
> Learn Graph Databases - Download FREE O'Reilly Book
> "Graph Databases" is the definitive new guide to graph databases and their
> applications. Written by three acclaimed leaders in the field,
> this first edition is now available. Download your free book today!
> http://p.sf.net/sfu/NeoTech
> _______________________________________________
> Bitcoin-development mailing list
> Bitcoin-development@lists•sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/bitcoin-development
>



 permalink raw reply	[|nested]
2014-04-15 15:11   ` Pieter Wuille

  2014-04-15 15:30       ` Mike Hearn
  
From: Matt Whitlock @ 2014-04-15 15:22 UTC (permalink / raw)
  To: Pieter Wuille, Mike Hearn, Bitcoin Dev

Thanks for the quick reply to both of you, Mike and Pieter.

I feel foolish for posting to this list, because the debug.log does indeed say "inputs already spent." That's so weird, though, because we haven't been able to get anything to accept the transaction, seemingly, and yet it was accepted into the block chain 15 blocks ago.

Anyway, I'm sorry for the noise.


On Tuesday, 15 April 2014, at 5:11 pm, Pieter Wuille wrote:
> The first input seems to be already spent by another transaction
> (which looks very similar).
> 
> 0.9 should report a more detailed reason for rejection, by the way.
> 
> 
> 
> On Tue, Apr 15, 2014 at 5:05 PM, Mike Hearn <mike@plan99•net> wrote:
> > Check debug.log to find out the reason it was rejected.
> >
> >
> >
> > ------------------------------------------------------------------------------
> > Learn Graph Databases - Download FREE O'Reilly Book
> > "Graph Databases" is the definitive new guide to graph databases and their
> > applications. Written by three acclaimed leaders in the field,
> > this first edition is now available. Download your free book today!
> > http://p.sf.net/sfu/NeoTech
> > _______________________________________________
> > Bitcoin-development mailing list
> > Bitcoin-development@lists•sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/bitcoin-development
> >



 permalink raw reply	[|nested]
2014-04-15 15:22     ` Matt Whitlock

  2014-04-15 15:42         ` Matt Whitlock
  
From: Mike Hearn @ 2014-04-15 15:30 UTC (permalink / raw)
  To: Matt Whitlock;  Bitcoin Dev

[-- Attachment #1: Type: text/plain, Size: 295 bytes --]

>
> That's so weird, though, because we haven't been able to get anything to
> accept the transaction, seemingly, and yet it was accepted into the block
> chain 15 blocks ago.


If the tx is already in the block chain then it won't be accepted again,
because it would be double spending itself!

[-- Attachment #2: Type: text/html, Size: 525 bytes --]

 permalink raw reply	[|nested]
2014-04-15 15:30       ` Mike Hearn

  2014-04-15 15:47           ` Mike Belshe
  
From: Matt Whitlock @ 2014-04-15 15:42 UTC (permalink / raw)
  To: Mike Hearn;  Bitcoin Dev

On Tuesday, 15 April 2014, at 5:30 pm, Mike Hearn wrote:
> >
> > That's so weird, though, because we haven't been able to get anything to
> > accept the transaction, seemingly, and yet it was accepted into the block
> > chain 15 blocks ago.
> 
> 
> If the tx is already in the block chain then it won't be accepted again,
> because it would be double spending itself!

Haha, yes, I know that. But we had been trying to get a 2-of-3 to be accepted by something for hours, and everything was rejecting it: Coinb.in, our local Bitcoind, the Eligius tx push form. Evidently something did accept it and we didn't notice. We're starting over again now and trying to reproduce the success (or failure).



 permalink raw reply	[|nested]
2014-04-15 15:42         ` Matt Whitlock

  2014-04-15 16:27             ` Matt Whitlock
  
From: Mike Belshe @ 2014-04-15 15:47 UTC (permalink / raw)
  To: Matt Whitlock;  Bitcoin Dev

[-- Attachment #1: Type: text/plain, Size: 1637 bytes --]

For what it is worth, I found btcd (the go implementation of bitcoind) has
much better error/diagnostics messages.  It would have given you more than
"-22 TX Rejected".  I used it to debug my own multi-sig transactions and it
was very helpful.

Mike



On Tue, Apr 15, 2014 at 8:42 AM, Matt Whitlock <bip@mattwhitlock•name>wrote:

> On Tuesday, 15 April 2014, at 5:30 pm, Mike Hearn wrote:
> > >
> > > That's so weird, though, because we haven't been able to get anything
> to
> > > accept the transaction, seemingly, and yet it was accepted into the
> block
> > > chain 15 blocks ago.
> >
> >
> > If the tx is already in the block chain then it won't be accepted again,
> > because it would be double spending itself!
>
> Haha, yes, I know that. But we had been trying to get a 2-of-3 to be
> accepted by something for hours, and everything was rejecting it: Coinb.in,
> our local Bitcoind, the Eligius tx push form. Evidently something did
> accept it and we didn't notice. We're starting over again now and trying to
> reproduce the success (or failure).
>
>
> ------------------------------------------------------------------------------
> Learn Graph Databases - Download FREE O'Reilly Book
> "Graph Databases" is the definitive new guide to graph databases and their
> applications. Written by three acclaimed leaders in the field,
> this first edition is now available. Download your free book today!
> http://p.sf.net/sfu/NeoTech
> _______________________________________________
> Bitcoin-development mailing list
> Bitcoin-development@lists•sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/bitcoin-development
>

[-- Attachment #2: Type: text/html, Size: 2438 bytes --]

 permalink raw reply	[|nested]
2014-04-15 15:47           ` Mike Belshe

  2014-04-15 16:39               ` Chris Beams
  
From: Matt Whitlock @ 2014-04-15 16:27 UTC (permalink / raw)
  To: Mike Belshe;  Bitcoin Dev

On Tuesday, 15 April 2014, at 8:47 am, Mike Belshe wrote:
> For what it is worth, I found btcd (the go implementation of bitcoind) has
> much better error/diagnostics messages.  It would have given you more than
> "-22 TX Rejected".  I used it to debug my own multi-sig transactions and it
> was very helpful.

I'll have to check that out.


A follow-up on my initial post... I did just successfully create, sign, and transmit another 2-of-3 transaction, so once again, I'm sorry I bothered this list. But since I did (and am now doing so again), I'll give a little more background on what we've been up to. It's not quite as simple as what I've shared thus far. 

We have built a tool from scratch in C++ that is kind of a Swiss Army knife of Bitcoin. It does all sorts of key and address conversions, hash functions, encoding and decoding, script disassembly, BIP38 encryption/decrytion, the Shamir Secret Sharing that I've posted about here on this list before, and transaction building and signing. It has its own wallet and it's own UTXO cache that contains only TXOs that are relevant to the objects in its wallet. It synchronizes its cache by scanning bitcoind's block data files. (It memory maps them and can do a full scan of the entire block chain in about a minute!) The wallet can contain keys, seeds, and multi-signature aggregates (which in turn can comprise keys and seeds). What we've been testing is deriving sequences of multi-sig P2SH addresses from a set of public seeds, sending bitcoins to those addresses, then using our tool to find those outputs in the block chain and to create transactions that redeem them, and then signing those transactions by supplying the private seeds to the tool.

Our tool is quite a bit easier to use than Bitcoind. (I was frankly appalled at the command-line syntax that was necessary to get Bitcoind to sign a P2SH multi-sig transaction.)

$ ./btctool privkey < /dev/random > privseed1
$ ./btctool privkey < /dev/random > privseed2
$ ./btctool privkey < /dev/random > privseed3
$ pubseed1=$(./btctool pubkey < privseed1)
$ pubseed2=$(./btctool pubkey < privseed2)
$ pubseed3=$(./btctool pubkey < privseed3)
$ ./chaintool init
$ ./chaintool add demo 2 ":${pubseed1}" ":${pubseed2}" ":${pubseed3}"
$ ./chaintool ls
demo    2 :036447c7edc861b9f41fa0f611d81784f19ce692f37e8772b55c37c743cd526b49 :03c831711ea65decc06b0f3ccb4b9f1ba1a99a6933e520f6e7e4c3dbb4f015b701 :0347f2a0a346f21538fc451b95a600bc64ce5d2d28b89bf547697f3a77195d8dd1
$ ./btctool addresses 1 2 "${pubseed1}" "${pubseed2}" "${pubseed3}"
3GQd1tosFCE7Vo4TAiDHEKTaBgoyZTeL6R
$ bitcoind sendtoaddress 3GQd1tosFCE7Vo4TAiDHEKTaBgoyZTeL6R 0.01
6a9538f496f4c2d7f50c342fa6f6f76904a3b19f55f3a54a0003fc00b327d81b
(I waited here for the tx to get into a block)
$ ./chaintool sync /var/lib/bitcoin/.bitcoin/blocks 2> /dev/null
$ ./chaintool listunspent
[
        {
                "txid": "6a9538f496f4c2d7f50c342fa6f6f76904a3b19f55f3a54a0003fc00b327d81b",
                "vout": 1,
                "address": "3GQd1tosFCE7Vo4TAiDHEKTaBgoyZTeL6R",
                "scriptPubKey": "a914a1701be36532f05a74511fca89afce180c58189587",
                "amount": 1000000,
                "confirmations": 1
        }
]
$ cat > outputs << EOF
> 13QAKNuh9uFcEiNAsct6LSF1qWQR6HLarT 50000
> 1FV4Fm3VCXfWy7BAXzT8t5qqTvEKZSad9v
> EOF
$ tx=$(./chaintool createtx 10000 demo < outputs)
(I manually edited ${tx} at this point to add an OP_RETURN output. We're currently working toward using OP_RETURN in a provable solvency scheme.)
$ signedtx1=$(./chaintool signtx "${tx}" < privseed1)
input #0: need 1 of [:03c831711ea65decc06b0f3ccb4b9f1ba1a99a6933e520f6e7e4c3dbb4f015b701, :0347f2a0a346f21538fc451b95a600bc64ce5d2d28b89bf547697f3a77195d8dd1]
$ signedtx2=$(./chaintool signtx "${signedtx1}" < privseed2)
$ bitcoind sendrawtransaction "${signedtx2}"
b485b185c77d803f75e1ccfee1b5072846c9e0728f4c955ca40dce82263f8f16
$ exit

:-)



 permalink raw reply	[|nested]
2014-04-15 16:27             ` Matt Whitlock

  2014-04-15 16:45                 ` Matt Whitlock
  
From: Chris Beams @ 2014-04-15 16:39 UTC (permalink / raw)
  To: Matt Whitlock;  Bitcoin Dev

[-- Attachment #1: Type: text/plain, Size: 4654 bytes --]

Hi Matt,

Looks interesting. Is the source available?


On Apr 15, 2014, at 6:27 PM, Matt Whitlock <bip@mattwhitlock•name> wrote:

On Tuesday, 15 April 2014, at 8:47 am, Mike Belshe wrote:
For what it is worth, I found btcd (the go implementation of bitcoind) has
much better error/diagnostics messages.  It would have given you more than
"-22 TX Rejected".  I used it to debug my own multi-sig transactions and it
was very helpful.

I'll have to check that out.


A follow-up on my initial post... I did just successfully create, sign, and transmit another 2-of-3 transaction, so once again, I'm sorry I bothered this list. But since I did (and am now doing so again), I'll give a little more background on what we've been up to. It's not quite as simple as what I've shared thus far.

We have built a tool from scratch in C++ that is kind of a Swiss Army knife of Bitcoin. It does all sorts of key and address conversions, hash functions, encoding and decoding, script disassembly, BIP38 encryption/decrytion, the Shamir Secret Sharing that I've posted about here on this list before, and transaction building and signing. It has its own wallet and it's own UTXO cache that contains only TXOs that are relevant to the objects in its wallet. It synchronizes its cache by scanning bitcoind's block data files. (It memory maps them and can do a full scan of the entire block chain in about a minute!) The wallet can contain keys, seeds, and multi-signature aggregates (which in turn can comprise keys and seeds). What we've been testing is deriving sequences of multi-sig P2SH addresses from a set of public seeds, sending bitcoins to those addresses, then using our tool to find those outputs in the block chain and to create transactions that redeem them, and then signing those trans
actions by supplying the private seeds to the tool.

Our tool is quite a bit easier to use than Bitcoind. (I was frankly appalled at the command-line syntax that was necessary to get Bitcoind to sign a P2SH multi-sig transaction.)

$ ./btctool privkey < /dev/random > privseed1
$ ./btctool privkey < /dev/random > privseed2
$ ./btctool privkey < /dev/random > privseed3
$ pubseed1=$(./btctool pubkey < privseed1)
$ pubseed2=$(./btctool pubkey < privseed2)
$ pubseed3=$(./btctool pubkey < privseed3)
$ ./chaintool init
$ ./chaintool add demo 2 ":${pubseed1}" ":${pubseed2}" ":${pubseed3}"
$ ./chaintool ls
demo    2 :036447c7edc861b9f41fa0f611d81784f19ce692f37e8772b55c37c743cd526b49 :03c831711ea65decc06b0f3ccb4b9f1ba1a99a6933e520f6e7e4c3dbb4f015b701 :0347f2a0a346f21538fc451b95a600bc64ce5d2d28b89bf547697f3a77195d8dd1
$ ./btctool addresses 1 2 "${pubseed1}" "${pubseed2}" "${pubseed3}"
3GQd1tosFCE7Vo4TAiDHEKTaBgoyZTeL6R
$ bitcoind sendtoaddress 3GQd1tosFCE7Vo4TAiDHEKTaBgoyZTeL6R 0.01
6a9538f496f4c2d7f50c342fa6f6f76904a3b19f55f3a54a0003fc00b327d81b
(I waited here for the tx to get into a block)
$ ./chaintool sync /var/lib/bitcoin/.bitcoin/blocks 2> /dev/null
$ ./chaintool listunspent
[
       {
               "txid": "6a9538f496f4c2d7f50c342fa6f6f76904a3b19f55f3a54a0003fc00b327d81b",
               "vout": 1,
               "address": "3GQd1tosFCE7Vo4TAiDHEKTaBgoyZTeL6R",
               "scriptPubKey": "a914a1701be36532f05a74511fca89afce180c58189587",
               "amount": 1000000,
               "confirmations": 1
       }
]
$ cat > outputs << EOF
13QAKNuh9uFcEiNAsct6LSF1qWQR6HLarT 50000
1FV4Fm3VCXfWy7BAXzT8t5qqTvEKZSad9v
EOF
$ tx=$(./chaintool createtx 10000 demo < outputs)
(I manually edited ${tx} at this point to add an OP_RETURN output. We're currently working toward using OP_RETURN in a provable solvency scheme.)
$ signedtx1=$(./chaintool signtx "${tx}" < privseed1)
input #0: need 1 of [:03c831711ea65decc06b0f3ccb4b9f1ba1a99a6933e520f6e7e4c3dbb4f015b701, :0347f2a0a346f21538fc451b95a600bc64ce5d2d28b89bf547697f3a77195d8dd1]
$ signedtx2=$(./chaintool signtx "${signedtx1}" < privseed2)
$ bitcoind sendrawtransaction "${signedtx2}"
b485b185c77d803f75e1ccfee1b5072846c9e0728f4c955ca40dce82263f8f16
$ exit

:-)

------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their
applications. Written by three acclaimed leaders in the field,
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/NeoTech
_______________________________________________
Bitcoin-development mailing list
Bitcoin-development@lists•sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bitcoin-development


[-- Attachment #2: Message signed with OpenPGP using GPGMail --]
[-- Type: application/pgp-signature, Size: 841 bytes --]

 permalink raw reply	[|nested]
2014-04-15 16:39               ` Chris Beams

  
From: Matt Whitlock @ 2014-04-15 16:45 UTC (permalink / raw)
  To: Chris Beams;  Bitcoin Dev

On Tuesday, 15 April 2014, at 6:39 pm, Chris Beams wrote:
> Looks interesting. Is the source available?

The intent is to open-source it. We will do so when I'm confident that we have all the kinks worked out.

Here's what it can do presently:

$ ./btctool
usage: ./btctool <function> [<args>]
  encode16
    Encode stdin to hex.
  decode16 [<hex>]
    Decode hex from stdin or string.
  encode64 [<hex>]
    Encode stdin or octets to Base64.
  decode64 [<base64>]
    Decode Base64 from stdin or string.
  encode58 <version> [<hex>]
    Encode stdin or octets to Base58Check.
  decode58 [<base58>]
    Decode Base58Check from stdin or string.
  disassemble [<script>]
    Disassemble hex script.
  sha256 [<hex>]
    Hash stdin or octets using SHA-256.
  rmd160 [<hex>]
    Hash stdin or octets using RIPEMD-160.
  privkey [<hex>]
    Derive private key from stdin or octets.
  pubkey [<privkey>]
    Derive public key from private key.
  address [<pubkey>]
    Derive address from public key.
  address <m> [<pubkey>...]
    Derive m-of-n P2SH address from public keys.
  encrypt [<privkey>]
    Encrypt private key per BIP38.
  decrypt [<privkey>]
    Decrypt private key per BIP38.
  shares <m> <n> [<privkey>]
    Distribute private key into m-of-n shares.
  join [<share>...]
    Join shares to reconstitute private key.
  privkeys <k> [<privseed>]
    Derive k private keys from private seed.
  pubkeys <k> [<pubseed>]
    Derive k public keys from public seed.
  addresses <k> [<pubseed>]
    Derive k addresses from public seed.
  addresses <k> <m> [<pubseed>...]
    Derive k m-of-n P2SH addresses from public seeds.

$ ./chaintool
usage: ./chaintool <function> [<args>]
  init
    Initialize a new cache file.
  add <label> <pubkey>
    Add a public key.
  add <label> :<pubseed>
    Add a public seed.
  add <label> <m> {<pubkey>|:<pubseed>}...
    Add public keys/seeds for m-of-n P2SH.
  rm <label>
    Remove a public key or seed.
  ls
    List public keys and seeds.
  sync <blocksdir>
    Synchronize with block chain.
  tip
    Print hash of block at tip of main chain.
  getbalance [<label>...]
    Get available balance.
  listunspent [<label>...]
    List unspent outputs in JSON.
  createtx [<fee>] [<label>...]
    Create transaction from address+amount pairs on stdin.
  signtx <tx> [{<privkey>|<privseed>}...]
    Sign transaction with private key(s)/seed(s).




 permalink raw reply	[|nested]