Realtime Price(实时价格):

比特币多个输入交易数据的签名实现(二)

作者:david_hmy

发布时间:2018年8月9日

网络来源:简书

上文讲解了一笔交易中存在一个输入和一个输出的情况,一个输入和多个输出的情形与之处理方式一样,不再赘述。本文着重讲解多个输入的交易,如何完成签名。

以一个包含两个输入和两个输出的交易为例,其它更多输入和输出的交易实现,原理一致。

下面是根据交易数据结构,通过查询各自输入对应上一笔输出,找到各自的输出脚本后,完成全部填充后的一笔交易信息:

{

“txid”: “6f92259760fb24fc81f06cfe984c33d883724d655243824b755d763a2180609c”,

“hash”: “6f92259760fb24fc81f06cfe984c33d883724d655243824b755d763a2180609c”,

“size”: 185,

“vsize”: 185,

“version”: 1,

“locktime”: 0,

“vin”: [

{

“txid”: “350216356afc5ddb2143786318f9ccbee97abbcc5c9f4cfadbbb4d5c8dc3ccd9”,

“vout”: 0,

“scriptSig”: {

“asm”: “OP_DUP OP_HASH160 b2fd829c977a49044cd21e8762a99ce670800dbe OP_EQUALVERIFY OP_CHECKSIG”,

“hex”: “76a914b2fd829c977a49044cd21e8762a99ce670800dbe88ac”

},

“sequence”: 4294967295

},

{

“txid”: “dffdc8363aa6ddcaa7df62a8eeef635cc248b778da245e1d99c303148e1f5d24”,

“vout”: 0,

“scriptSig”: {

“asm”: “OP_DUP OP_HASH160 c8e9a628b5d1e49020efc51153fab992213d96fa OP_EQUALVERIFY OP_CHECKSIG”,

“hex”: “76a914c8e9a628b5d1e49020efc51153fab992213d96fa88ac”

},

“sequence”: 4294967295

}

],

“vout”: [

{

“value”: 188638,

“n”: 0,

“scriptPubKey”: {

“asm”: “OP_DUP OP_HASH160 ad46f3b798adeb378f732a864ccf4516b8d02c6a OP_EQUALVERIFY OP_CHECKSIG”,

“hex”: “76a914ad46f3b798adeb378f732a864ccf4516b8d02c6a88ac”,

“reqSigs”: 1,

“type”: “pubkeyhash”,

“addresses”: [

“1GoCu28SQu17FGEc4cv3of9ugwAcoPxGqE”

]

}

},

{

“value”: 200000,

“n”: 1,

“scriptPubKey”: {

“asm”: “OP_DUP OP_HASH160 ed5f9b6dce1fdcdb0c904b2b6928d5e25594ad23 OP_EQUALVERIFY OP_CHECKSIG”,

“hex”: “76a914ed5f9b6dce1fdcdb0c904b2b6928d5e25594ad2388ac”,

“reqSigs”: 1,

“type”: “pubkeyhash”,

“addresses”: [

“1Ne7gN9gUUpDp3JWK32bZyRH8ixCyPJQJa”

]

}

}

]

}

如结构所示,总共两个输入,每个输入对应的上一个输出脚本也都填充好了,那么,签名的时候,都用这一份原始交易数据内容么?

1、理解的偏差

因为我最先实现的一对一交易,所以在构建多对多的交易数据时,我想当然认为,在对原始数据填充输入脚本这部分的操作应该这么做:

a、找到输入1的上一笔输出交易信息,从该信息中提取出属于自己的输出脚本,填充到本次交易输入1的脚本域中;

b、找到输入2的上一笔输出交易信息,从该信息中提取出属于自己的输出脚本,填充到本次交易输入2的脚本域中;

c、完成本次交易整个数据的赋值和填充后,形成一个原始交易数据;

d、将步骤c的原始交易数据用输入1对应的私钥进行签名,得到sign1,将其重新回填到输入1 的脚本域;

e、将步骤c的原始交易数据用输入2对应的私钥进行签名,得到sign2,将其重新回填到输入2的脚本域;

f、完成上述步骤后,得到真正可以广播出去的交易数据。

我按照以上思路做完签名后,发现数据广播出去失败,返回错误,提示该交易数据签名数据错误。

2、真正的原始交易数据

出现问题后上网搜索一遍,发现没有这方面的任何解答,好在公司能上外网,终于找到一个国外同行们的解答:

https://bitcoin.stackexchange.com/questions/41209/how-to-sign-a-transaction-with-multiple-inputs

通过阅读理解,再结合keepkey的firmware源码中该部分的实现,整理出来处理思路如下:

1、对于多个输入的交易签名,在构建原始交易数据时,本着用谁的私钥签名,就先填充谁的脚本域的原则,比如,现在要用输入1对应的私钥对这笔交易进行签名,那么在构建原始交易数据时,其它的输入中的脚本域不做填充,并且赋值script_len =0。

2、构建一个原始交易1,用私钥1来完成签名,得到sign1,原始交易1的数据结构如下:

0100000002d9ccc38d5c4dbbdbfa4c9f5cccbb7ae9beccf91863784321db5dfc6a35160235000000001976a914b2fd829c977a49044cd21e8762a99ce670800dbe88acffffffff245d1f8e1403c3991d5e24da78b748c25c63efeea862dfa7cadda63a36c8fddf0000000000ffffffff02dee00200000000001976a914ad46f3b798adeb378f732a864ccf4516b8d02c6a88ac400d0300000000001976a914ed5f9b6dce1fdcdb0c904b2b6928d5e25594ad2388ac0000000001000000

{

“txid”: “6f92259760fb24fc81f06cfe984c33d883724d655243824b755d763a2180609c”,

“hash”: “6f92259760fb24fc81f06cfe984c33d883724d655243824b755d763a2180609c”,

“size”: 185,

“vsize”: 185,

“version”: 1,

“locktime”: 0,

“vin”: [

{

“txid”: “350216356afc5ddb2143786318f9ccbee97abbcc5c9f4cfadbbb4d5c8dc3ccd9”,

“vout”: 0,

“scriptSig”: {

“asm”: “OP_DUP OP_HASH160 b2fd829c977a49044cd21e8762a99ce670800dbe OP_EQUALVERIFY OP_CHECKSIG”,

“hex”: “76a914b2fd829c977a49044cd21e8762a99ce670800dbe88ac”

},

“sequence”: 4294967295

},

{

“txid”: “dffdc8363aa6ddcaa7df62a8eeef635cc248b778da245e1d99c303148e1f5d24”,

“vout”: 0,

“scriptSig”: {

“asm”: “”,

“hex”: “”

},

“sequence”: 4294967295

}

],

“vout”: [

{

“value”: 188638,

“n”: 0,

“scriptPubKey”: {

“asm”: “OP_DUP OP_HASH160 ad46f3b798adeb378f732a864ccf4516b8d02c6a OP_EQUALVERIFY OP_CHECKSIG”,

“hex”: “76a914ad46f3b798adeb378f732a864ccf4516b8d02c6a88ac”,

“reqSigs”: 1,

“type”: “pubkeyhash”,

“addresses”: [

“1GoCu28SQu17FGEc4cv3of9ugwAcoPxGqE”

]

}

},

{

“value”: 200000,

“n”: 1,

“scriptPubKey”: {

“asm”: “OP_DUP OP_HASH160 ed5f9b6dce1fdcdb0c904b2b6928d5e25594ad23 OP_EQUALVERIFY OP_CHECKSIG”,

“hex”: “76a914ed5f9b6dce1fdcdb0c904b2b6928d5e25594ad2388ac”,

“reqSigs”: 1,

“type”: “pubkeyhash”,

“addresses”: [

“1Ne7gN9gUUpDp3JWK32bZyRH8ixCyPJQJa”

]

}

}

]

}

得到的sign1如下:

473044022073d0210a320b3d6ce3088da58e9f31dd87fda550762b248b794172b3ccaac13902205da717b785a4219518cd3f5903d130886c2b8905c543abb389fbbafa41e90c300141043d23e5f0758a53e2a18c8156051ca136d4639db5ceace580583983151113c1e5dcd7523f777fcd5b7ba16fef8dcbf4c2dbcaf91dd0c5d72080703517b96c4994

3、在构建第二个原始交易2,用私钥2完成签名,得到sign2。原始交易1的数据结构如下:

0100000002d9ccc38d5c4dbbdbfa4c9f5cccbb7ae9beccf91863784321db5dfc6a351602350000000000ffffffff245d1f8e1403c3991d5e24da78b748c25c63efeea862dfa7cadda63a36c8fddf000000001976a914c8e9a628b5d1e49020efc51153fab992213d96fa88acffffffff02dee00200000000001976a914ad46f3b798adeb378f732a864ccf4516b8d02c6a88ac400d0300000000001976a914ed5f9b6dce1fdcdb0c904b2b6928d5e25594ad2388ac0000000001000000

{

“txid”: “55b61a575943ed9718989dabb4d8b5cdd90d3097d375f0354274894894f06ce5”,

“hash”: “55b61a575943ed9718989dabb4d8b5cdd90d3097d375f0354274894894f06ce5”,

“size”: 185,

“vsize”: 185,

“version”: 1,

“locktime”: 0,

“vin”: [

{

“txid”: “350216356afc5ddb2143786318f9ccbee97abbcc5c9f4cfadbbb4d5c8dc3ccd9”,

“vout”: 0,

“scriptSig”: {

“asm”: “”,

“hex”: “”

},

“sequence”: 4294967295

},

{

“txid”: “dffdc8363aa6ddcaa7df62a8eeef635cc248b778da245e1d99c303148e1f5d24”,

“vout”: 0,

“scriptSig”: {

“asm”: “OP_DUP OP_HASH160 c8e9a628b5d1e49020efc51153fab992213d96fa OP_EQUALVERIFY OP_CHECKSIG”,

“hex”: “76a914c8e9a628b5d1e49020efc51153fab992213d96fa88ac”

},

“sequence”: 4294967295

}

],

“vout”: [

{

“value”: 188638,

“n”: 0,

“scriptPubKey”: {

“asm”: “OP_DUP OP_HASH160 ad46f3b798adeb378f732a864ccf4516b8d02c6a OP_EQUALVERIFY OP_CHECKSIG”,

“hex”: “76a914ad46f3b798adeb378f732a864ccf4516b8d02c6a88ac”,

“reqSigs”: 1,

“type”: “pubkeyhash”,

“addresses”: [

“1GoCu28SQu17FGEc4cv3of9ugwAcoPxGqE”

]

}

},

{

“value”: 200000,

“n”: 1,

“scriptPubKey”: {

“asm”: “OP_DUP OP_HASH160 ed5f9b6dce1fdcdb0c904b2b6928d5e25594ad23 OP_EQUALVERIFY OP_CHECKSIG”,

“hex”: “76a914ed5f9b6dce1fdcdb0c904b2b6928d5e25594ad2388ac”,

“reqSigs”: 1,

“type”: “pubkeyhash”,

“addresses”: [

“1Ne7gN9gUUpDp3JWK32bZyRH8ixCyPJQJa”

]

}

}

]

}

得到的sign2如下:

47304402207f179bbf1ba47beaa80f9916c587700e1ed5141f2476bd803c6ec3bc953c0d1a0220662fee1ed87879f8ef5cc6877068dea9906809f86e22f713a4e674986f0647b8014104e152cd7210e4c2a0791514ca2d7d75e0bf25c7763488ffe73694c7d10b21471fe6ccdada299c6ab5d61ea7c13f3c480516cc980cab0820d7f67dbcc1da2831d1

………

n、完成所有的签名后,分别将sign1、sign2……分别重新回填到各自的输入脚本域中,更新各自的script_len值,最终形成真正能够广播的交易数据:

0100000002d9ccc38d5c4dbbdbfa4c9f5cccbb7ae9beccf91863784321db5dfc6a35160235000000008a473044022073d0210a320b3d6ce3088da58e9f31dd87fda550762b248b794172b3ccaac13902205da717b785a4219518cd3f5903d130886c2b8905c543abb389fbbafa41e90c300141043d23e5f0758a53e2a18c8156051ca136d4639db5ceace580583983151113c1e5dcd7523f777fcd5b7ba16fef8dcbf4c2dbcaf91dd0c5d72080703517b96c4994ffffffff245d1f8e1403c3991d5e24da78b748c25c63efeea862dfa7cadda63a36c8fddf000000008a47304402207f179bbf1ba47beaa80f9916c587700e1ed5141f2476bd803c6ec3bc953c0d1a0220662fee1ed87879f8ef5cc6877068dea9906809f86e22f713a4e674986f0647b8014104e152cd7210e4c2a0791514ca2d7d75e0bf25c7763488ffe73694c7d10b21471fe6ccdada299c6ab5d61ea7c13f3c480516cc980cab0820d7f67dbcc1da2831d1ffffffff02dee00200000000001976a914ad46f3b798adeb378f732a864ccf4516b8d02c6a88ac400d0300000000001976a914ed5f9b6dce1fdcdb0c904b2b6928d5e25594ad2388ac00000000

{

“txid”: “4ec1953b1e468b4f965b7eac307023ea801a5a75f0adef7387c500c06d2ae5ce”,

“hash”: “4ec1953b1e468b4f965b7eac307023ea801a5a75f0adef7387c500c06d2ae5ce”,

“size”: 436,

“vsize”: 436,

“version”: 1,

“locktime”: 0,

“vin”: [

{

“txid”: “350216356afc5ddb2143786318f9ccbee97abbcc5c9f4cfadbbb4d5c8dc3ccd9”,

“vout”: 0,

“scriptSig”: {

“asm”: “3044022073d0210a320b3d6ce3088da58e9f31dd87fda550762b248b794172b3ccaac13902205da717b785a4219518cd3f5903d130886c2b8905c543abb389fbbafa41e90c30[ALL] 043d23e5f0758a53e2a18c8156051ca136d4639db5ceace580583983151113c1e5dcd7523f777fcd5b7ba16fef8dcbf4c2dbcaf91dd0c5d72080703517b96c4994”,

“hex”: “473044022073d0210a320b3d6ce3088da58e9f31dd87fda550762b248b794172b3ccaac13902205da717b785a4219518cd3f5903d130886c2b8905c543abb389fbbafa41e90c300141043d23e5f0758a53e2a18c8156051ca136d4639db5ceace580583983151113c1e5dcd7523f777fcd5b7ba16fef8dcbf4c2dbcaf91dd0c5d72080703517b96c4994”

},

“sequence”: 4294967295

},

{

“txid”: “dffdc8363aa6ddcaa7df62a8eeef635cc248b778da245e1d99c303148e1f5d24”,

“vout”: 0,

“scriptSig”: {

“asm”: “304402207f179bbf1ba47beaa80f9916c587700e1ed5141f2476bd803c6ec3bc953c0d1a0220662fee1ed87879f8ef5cc6877068dea9906809f86e22f713a4e674986f0647b8[ALL] 04e152cd7210e4c2a0791514ca2d7d75e0bf25c7763488ffe73694c7d10b21471fe6ccdada299c6ab5d61ea7c13f3c480516cc980cab0820d7f67dbcc1da2831d1”,

“hex”: “47304402207f179bbf1ba47beaa80f9916c587700e1ed5141f2476bd803c6ec3bc953c0d1a0220662fee1ed87879f8ef5cc6877068dea9906809f86e22f713a4e674986f0647b8014104e152cd7210e4c2a0791514ca2d7d75e0bf25c7763488ffe73694c7d10b21471fe6ccdada299c6ab5d61ea7c13f3c480516cc980cab0820d7f67dbcc1da2831d1”

},

“sequence”: 4294967295

}

],

“vout”: [

{

“value”: 188638,

“n”: 0,

“scriptPubKey”: {

“asm”: “OP_DUP OP_HASH160 ad46f3b798adeb378f732a864ccf4516b8d02c6a OP_EQUALVERIFY OP_CHECKSIG”,

“hex”: “76a914ad46f3b798adeb378f732a864ccf4516b8d02c6a88ac”,

“reqSigs”: 1,

“type”: “pubkeyhash”,

“addresses”: [

“1GoCu28SQu17FGEc4cv3of9ugwAcoPxGqE”

]

}

},

{

“value”: 200000,

“n”: 1,

“scriptPubKey”: {

“asm”: “OP_DUP OP_HASH160 ed5f9b6dce1fdcdb0c904b2b6928d5e25594ad23 OP_EQUALVERIFY OP_CHECKSIG”,

“hex”: “76a914ed5f9b6dce1fdcdb0c904b2b6928d5e25594ad2388ac”,

“reqSigs”: 1,

“type”: “pubkeyhash”,

“addresses”: [

“1Ne7gN9gUUpDp3JWK32bZyRH8ixCyPJQJa”

]

}

}

]

}

以上数据都是真正在BTC网络上实现交易的,请各位查阅。

如果你觉得这篇文档对你有帮助,别忘了打赏:

1HKQyLvLL4zCsbewjxdbV9WsCmqyaZYUUT

作者:david_hmy
链接:https://www.jianshu.com/p/cb18869bd5ba
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

相关文章:

比特币布道者

比特币的坚定信仰者!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注