btc-raw-tx-desc




BTC transaction rawtx 解析


很多情况下,我们都需要对交易中的某一些rawtx进行解析,以便更加清楚的理解,其在交易过程中的一些详细信息,现在,详细罗列一下rawtx中每一个字节码究竟代表什么,建议一定要耐心阅读,可能有点恶心。
先来一段交易过程中的原始rawtx:

0100000001697f98c004bbb7d184119a31b2b8c96683fa8c7ca0d7755c6196888fb6ba046e010000006a473044022077de54191ae91b502d03a83bd1d580a8b4467fc3d205c7bce169f13e6abc1c91022064f759845c960b04ddf9dd5a635da5f8b990fc934fced06747d52f2658603735012103c426034f05b3b66700f151991e6e45f2d63545a73b36c0a8e8c4200c53f7fd2cfeffffff02a0f53813000000001976a914e85324d4402d9758122c5498de80d1cfcc6330cb88aca09f6636000000001976a914093f4c533deb449f6bd0a427bddb0f02c297101388ac5dad0700

这个是截取的块高度为503134,交易为27f5f35b447e219d0b3a3ac55f9dc6aacf2d4145fbd930207ef5b7710c47d883的rawtx。

在了解如何解析之前,首先我们需要了解 tx 中都包含哪些字段,究竟有哪些格式:

tx

field sizedescriptiondata typecomments
4versionint32_tTransaction data format version (note, this is signed)
0 or 2flagoptional uint8_t[2]If present, always 0001, and indicates the presence of witness data
1+tx_in countvar_intNumber of Transaction inputs (never zero)
41+tx_intx_in[]A list of 1 or more transaction inputs or sources for coins
9+tx_out countvar_intNumber of Transaction outputs
41+tx_outtx_out[]A list of 1 or more transaction outputs or destinations for coins
0+tx_witnessestx_witness[]A list of witnesses, one for each input; omitted if flag is omitted above
4lock_timeuint32_t一般为 00000000

TxIn consists of the following fields:

field sizedescriptiondata typecomments
36previous_outputoutpointThe previous output transaction reference, as an OutPoint structure
1+script lengthvar_intThe length of the signature script
?signature scriptuchar[]Computational Script for confirming transaction authorization
4sequenceuint32_t一般为 FFFFFFFF

The OutPoint structure consists of the following fields:

field sizedescriptiondata typecomments
32hashchar[32]The hash of the referenced transaction.
4indexuint32_tThe index of the specific output in the transaction. The first output is 0, etc.

The TxOut structure consists of the following fields:

field sizedescriptiondata typecomments
8valueint64_tTtransaction value.
1+pk_script lengthvar_intLength of the pk_script
?pk_scriptuchar[]Usually contains the public key as a Bitcoin script setting up conditions to claim this output.

Standard Transaction to Bitcoin address (pay-to-pubkey-hash)

  1. scriptPubKey: OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
  2. scriptSig: <sig> <pubKey>

To demonstrate how scripts look on the wire, here is a raw scriptPubKey:

  1. 76 A9 14
  2. OP_DUP OP_HASH160 Bytes to push
  3. 89 AB CD EF AB BA AB BA AB BA AB BA AB BA AB BA AB BA AB BA 88 AC
  4. Data to push OP_EQUALVERIFY OP_CHECKSIG

比特币交易(P2PKH:对公钥哈希的付款)的解锁和锁定脚本的示例,显示了在脚本验证之前从解锁和锁定脚本的并置产生的组合脚本

签名+pubKey

PUB_KEY 格式:

  1. pubkey分为压缩和未压缩两种方式
  2. 公钥是在椭圆曲线上的一个点,由一对坐标(x,y)组成。
  1. 04 //代表未压缩公钥(02、03 代表压缩公钥)
  2. 025a1cffe502a80dfa1f543ae14c082aff24d5ecadab160ca904d288eed8e3d8 //x
  3. cacef0985f690868df4f416c3890909b4c0c843da153d41382ac20c80170240a //y

ok,对上述格式有一个简单的了解之后,我们来解析上述rawtx,看看它究竟为何方神圣。

======================================================
===================飙车 分割线==========================
======================================================

tx describes a bitcoin transaction, in reply to getdata

  1. 01000000 //[4字节] 的版本号(16进制,两位一个字节)
  2. //[0或2字节] no flag( If present, always 0001, and indicates the presence of witness data)
  3. 01 //[1字节] tx_in count(01代表一个输入,可能有多个)
  4. // tx_in array:
  5. 2ac424bf26875f2fa550b6df61a49564d510c6e8b535fd6f8870a0dc4b3711a301000000 //[36字节]的previous_output
  6. 8a //[1字节]的script length(16进制,8a=138 )
  7. 47304402205a2041854aba3d33ec92fae4894eb38c99aab1e6cfca619c08545f5eb757925902205f5593e104860a300df6c0d463744fed610a6bc914ee9959be467dae9b306623014104025a1cffe502a80dfa1f543ae14c082aff24d5ecadab160ca904d288eed8e3d8cacef0985f690868df4f416c3890909b4c0c843da153d41382ac20c80170240a
  8. // [138字节]的signature script
  9. ffffffff //[4字节]的sequence
  10. 02 //[1字节]的tx_out count,02代表有两个输出。
  11. //tx_out array:
  12. //第一个输出:
  13. 40420f0000000000 //[8字节]的Transaction Value(这里是小端,从后往前看(0f4240的十六进制转化为十进制,之后除以1亿,就是交易比特币的值。))
  14. 19 //[1字节]的pk_script length(代表pk_script长度是16进制的19(25字节))
  15. 76a914ae3b0aaf5e2ab94e0c8297fe055df443c69b4bdc88ac //pk_script(25字节)
  16. //第二个输出:
  17. fe130e9400000000 //[8字节]的 Transaction Value(2位在一起看(94 0e 13 fe))
  18. 19 //[1字节]的pk_script length
  19. 76a914bae025140c454518b8cba0c25d45a6dc87f4b9ce88ac //pk_script(25字节)
  20. 00000000 //[4字节]的lock_time

继续拆分signature script(一个签名,一个pubKey)

  1. // [138字节]的signature script
  2. 47 //数据的长度。//47代表*******所包含的范围,是一个签名
  3. ******************
  4. 30 //表示DER序列的开始
  5. 44 //序列的长度(16进制,68字节)//44代表的是>>>>>所包含的范围
  6. >>>>>>>>>>>>
  7. 02 //一个整数值
  8. 20 //整数的长度(32字节)
  9. 5a2041854aba3d33ec92fae4894eb38c99aab1e6cfca619c08545f5eb7579259 //R
  10. 02 //一个整数值
  11. 20 //整数的长度(32字节)
  12. 5f5593e104860a300df6c0d463744fed610a6bc914ee9959be467dae9b306623 //S
  13. >>>>>>>>>>>>>
  14. 01 //签名hash类型(sighash)
  15. *******************
  16. 41 //(16进制的65,有65个字节) 这个是pubKey的长度
  17. 04025a1cffe502a80dfa1f543ae14c082aff24d5ecadab160ca904d288eed8e3d8cacef0985f690868df4f416c3890909b4c0c843da153d41382ac20c80170240a
  18. //65字节 未压缩公钥(pubKey)

继续拆分pk_script

  1. //pk_script(25字节)
  2. 76 //OP_DUP
  3. a9 //OP_HASH160
  4. 14 //(20字节的push数据)
  5. ae3b0aaf5e2ab94e0c8297fe055df443c69b4bdc //20字节 data to push
  6. 88 //OP_EQUALVERIFY
  7. ac //OP_CHECKSIG

P2SH MULTISIG (2 of 3)拆分

  1. 00 //00是当时候设计的一个bug,目前已经成为一种共识,只有当多重签名的时候,才会使用 00
  2. //两个签名脚本
  3. 47 //OP_DATA_71
  4. 304402206a46d2803f9bc7bb59fd66a7e2eb19625bc7c897e0ab84d841179fdfdfb2ebbb02202949e64609827687fd9b2c7cbb3b706a34e67cdd3f6536c630dcac78a8eb6cf001
  5. 47
  6. 304402207946b95930ce13d96592a35b278df16ff6544083ab18dd3a7fb35a2cc118a88102203bcb33f08b3230cc0c42ac77050bcbdc4e3a5643b4c29986d844c6314e71614c01
  7. 4c //操作码--> OP_PUSHDATA1
  8. 69 //105字节 代表>>>所包含的内容
  9. >>>>>
  10. 52
  11. 21028bb6ee1127a620219c4f6fb22067536649d439929e177ebfe76386dff52a7084
  12. 2102f9cd8728b12b6c8a17a15cb4a19de000641f78a449c1b619dc271b84643ce0e9
  13. 2103d33aef1ae9ecfcfa0935a8e34bb4a285cfaad1be800fc38f9fc869043c1cbee2
  14. 53 //代表有3个公钥
  15. ae //代表脚本OP_XXX(OP_CHECKMULTISIG 校验多重签名是否正确)
  16. >>>>>>


have a try: 
tx='0100000003be99aef3d48f60ebb0b7a5253b119784c80646babcd9fed02a527ba628c22b4a5f0000006a47304402206e4337c360d437e541d0614edd76b2a2c455349fef5a6e5e42d27a582c565176022051f916ec38ded2f5a5ad54148a0912b286dd4278403872ec9a14b31858a691360121020155ad90a496a89f3744eae693d4098128e0e5f00b886a6d95b9f7c9440a386affffffff72b4a9ded6dfb98caf008964cda5628c675e183f6513d8e61e27097b03ad60c8380000006a47304402203f137a70d457c5b7845508bcb9cfe7d441b571d56f3e23feef48af92fe95345c022027ab89e387f38ae0d8d23e3203de7aa11ef0b906f9f4ecbfe4416f027273e7d80121037ba1425eb3cf7ce27abaf449f547bdaa651c308845769fc96488ac355c5349dcffffffffee55cdd5a8a19f7fe0fb96335609fb851fd5b0f8830b68ebb6864d4d0dabea6b000000006b48304502202165438ac01215bf4e3e368019ffe6accc36a22680db6da2b9dcefcc6a489fca0221009ad2708d5e43ddebfba651bdd1c9c9707ecd940aad76c2fe43643f54b29165ce012102f781905c5e8192faabef879832e7a8ed24e1b16b4928d5116ea2de5ba43cb67effffffff015b6f1e00000000001976a914b9fac5599055253a9bcfac69b0d8a15bb09749be88ac00000000'


按照tx的格式开始拆分,(注意:signature还没有进行拆分)
01000000             ---->版本
03                         ---->表示有3个输入
be99aef3d48f60ebb0b7a5253b119784c80646babcd9fed02a527ba628c22b4a --->来自哪个output,这个是big endian表示方法,真正的txid需要转换一下,参考这个,设tid='be99aef3d48f60ebb0b7a5253b119784c80646babcd9fed02a527ba628c22b4a', 则真实的id为:  codecs.encode(codecs.decode(tid,'hex')[::-1],'hex_codec').decode(),求得txid=''4a2bc228a67b522ad0fed9bcba4606c88497113b25a5b7b0eb608fd4f3ae99be''这个代表tx hash
5f000000                ----->来自output中的第几个(即输出中的第几个地址)  这个也是big endian表示法,转换之后是0000005f,即第16×5+15=95个输出
6a                           ----->签名脚本(signature script)的长度 ,此时为16×6+10=106个字节
47304402206e4337c360d437e541d0614edd76b2a2c455349fef5a6e5e42d27a582c565176022051f916ec38ded2f5a5ad54148a0912b286dd4278403872ec9a14b31858a691360121020155ad90a496a89f3744eae693d4098128e0e5f00b886a6d95b9f7c9440a386a  ------>签名脚本,16进制表示,2位表示一个字节,共212位,对应上面的106个字节
ffffffff                     ----->sequence,序列号,暂时不知道其他用途
72b4a9ded6dfb98caf008964cda5628c675e183f6513d8e61e27097b03ad60c8  ----->同上,表示来自哪个output,big endian表示,真实的txid=c860ad037b09271ee6d813653f185e678c62a5cd648900af8cb9dfd6dea9b472
38000000               ------>同上,output中第几个地址,big endian表示,真实标识为00000038,即第16×3+8=56个输出
6a                         ----->签名脚本(signature script)的长度 ,此时为16×6+10=106个字节
47304402203f137a70d457c5b7845508bcb9cfe7d441b571d56f3e23feef48af92fe95345c022027ab89e387f38ae0d8d23e3203de7aa11ef0b906f9f4ecbfe4416f027273e7d80121037ba1425eb3cf7ce27abaf449f547bdaa651c308845769fc96488ac355c5349dc  ------>签名脚本,16进制表示,2位表示一个字节,共212位,对应上面的106个字节
ffffffff                   ----->sequence,序列号,暂时不知道其他用途
ee55cdd5a8a19f7fe0fb96335609fb851fd5b0f8830b68ebb6864d4d0dabea6b   ----->同上,表示来自哪个output,big endian表示,真实的txid=6beaab0d4d4d86b6eb680b83f8b0d51f85fb09563396fbe07f9fa1a8d5cd55ee
00000000             ------>同上,output中第几个地址,big endian表示,这里标识第0个输出
6b                        ----->签名脚本(signature script)的长度 ,此时为16×6+11=107个字节
48304502202165438ac01215bf4e3e368019ffe6accc36a22680db6da2b9dcefcc6a489fca0221009ad2708d5e43ddebfba651bdd1c9c9707ecd940aad76c2fe43643f54b29165ce012102f781905c5e8192faabef879832e7a8ed24e1b16b4928d5116ea2de5ba43cb67e  ------>签名脚本数据,16进制表示,2位表示一个字节,共214位,对应上面的107个字节
ffffffff                  ----->sequence,序列号,暂时不知道其他用途
01                       ------->输出个数,此时表示只有1个输出
5b6f1e0000000000   ----->本次交易(tx)输出的值,即币的个数,最小单位是1聪,也是big endian表示,按照这个计算, codecs.encode(codecs.decode('5b6f1e0000000000','hex')[::-1],'hex_codec').decode(),真实值是:00000000001e6f5b,转换为10进制是:1994587
19                        ------>pk脚本的长度,16进制,这里表示16×1+9=25个字节 
76a914b9fac5599055253a9bcfac69b0d8a15bb09749be88ac     ----->pk脚本数据,16进制表示,共50位,25个字节,与上面25字节保持一致
00000000            ----->锁定时间



以下面signature script为例
signatue script: 
48304502202165438ac01215bf4e3e368019ffe6accc36a22680db6da2b9dcefcc6a489fca0221009ad2708d5e43ddebfba651bdd1c9c9707ecd940aad76c2fe43643f54b29165ce012102f781905c5e8192faabef879832e7a8ed24e1b16b4928d5116ea2de5ba43cb67e

  1. // [138字节]的signature script
  2. 47 //数据的长度。//47代表*******所包含的范围,是一个签名
  3. ******************
  4. 30 //表示DER序列的开始
  5. 44 //序列的长度(16进制,68字节)//44代表的是>>>>>所包含的范围
  6. >>>>>>>>>>>>
  7. 02 //一个整数值
  8. 20 //整数的长度(32字节)
  9. 5a2041854aba3d33ec92fae4894eb38c99aab1e6cfca619c08545f5eb7579259 //R
  10. 02 //一个整数值
  11. 20 //整数的长度(32字节)
  12. 5f5593e104860a300df6c0d463744fed610a6bc914ee9959be467dae9b306623 //S
  13. >>>>>>>>>>>>>
  14. 01 //签名hash类型(sighash)
  15. *******************
  16. 41 //(16进制的65,有65个字节) 这个是pubKey的长度
  17. 04025a1cffe502a80dfa1f543ae14c082aff24d5ecadab160ca904d288eed8e3d8cacef0985f690868df4f416c3890909b4c0c843da153d41382ac20c80170240a
  18. //65字节 未压缩公钥(pubKey)

107字节的signature script数据:

48                -------> 数据长度,共16×4+8=72字节,代表*******所包含的范围,是一个签名
***********************************
30                -------> 表示DER序列开始
45                -------> 表示序列长度 ,代表的是>>>>>所包含的范围
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
02                -------> 表示一个整数值
20                -------> 表示整数的长度,16进制表示,所以这个长度是16×2=32字节
2165438ac01215bf4e3e368019ffe6accc36a22680db6da2b9dcefcc6a489fca  ----->R
02                -------> 表示一个整数值
21                -------> 表示整数的长度,16进制表示,所以这个长度是16×2+1=33字节
009ad2708d5e43ddebfba651bdd1c9c9707ecd940aad76c2fe43643f54b291 ------>S
65ce
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
01                -------> 签名hash类型(sighash)
***********************************
21                -------> pubKey(公钥)的长度,16进制,此时公钥长度是16×2+1=33字节
02f781905c5e8192faabef879832e7a8ed24e1b16b4928d5116ea2de5ba43cb67e ------>公钥,此时是压缩公钥



以下面pk script为例:
pk script: 
76a914b9fac5599055253a9bcfac69b0d8a15bb09749be88ac

  1. 76 //OP_DUP
  2. a9 //OP_HASH160
  3. 14 //(20字节的push数据)
  4. ae3b0aaf5e2ab94e0c8297fe055df443c69b4bdc //20字节 data to push
  5. 88 //OP_EQUALVERIFY
  6. ac //OP_CHECKSIG
76                -------> OP_DUP
a9                -------> OP_HASH160
14                -------> 20字节的push数据    ,16×1+4 = 20
b9fac5599055253a9bcfac69b0d8a15bb09749be                 -------> 20字节 data to push
88                -------> OP_EQUALVERIFY          
ac                -------> OP_CHECKSIG





原始raw tx如下:
0100000003be99aef3d48f60ebb0b7a5253b119784c80646babcd9fed02a527ba628c22b4a5f0000006a47304402206e4337c360d437e541d0614edd76b2a2c455349fef5a6e5e42d27a582c565176022051f916ec38ded2f5a5ad54148a0912b286dd4278403872ec9a14b31858a691360121020155ad90a496a89f3744eae693d4098128e0e5f00b886a6d95b9f7c9440a386affffffff72b4a9ded6dfb98caf008964cda5628c675e183f6513d8e61e27097b03ad60c8380000006a47304402203f137a70d457c5b7845508bcb9cfe7d441b571d56f3e23feef48af92fe95345c022027ab89e387f38ae0d8d23e3203de7aa11ef0b906f9f4ecbfe4416f027273e7d80121037ba1425eb3cf7ce27abaf449f547bdaa651c308845769fc96488ac355c5349dcffffffffee55cdd5a8a19f7fe0fb96335609fb851fd5b0f8830b68ebb6864d4d0dabea6b000000006b48304502202165438ac01215bf4e3e368019ffe6accc36a22680db6da2b9dcefcc6a489fca0221009ad2708d5e43ddebfba651bdd1c9c9707ecd940aad76c2fe43643f54b29165ce012102f781905c5e8192faabef879832e7a8ed24e1b16b4928d5116ea2de5ba43cb67effffffff015b6f1e00000000001976a914b9fac5599055253a9bcfac69b0d8a15bb09749be88ac00000000



总体拆分情况如下:
01000000       ---->版本
03             ---->3个输入
<!-----Input 1 ------->
be99aef3d48f60ebb0b7a5253b119784c80646babcd9fed02a527ba628c22b4a    ----->来自哪个Output
5f000000   ----->来自哪个Output的第几个
6a         --->签名脚本的长度,共106字节
47         --->//数据的长度。//47代表××××所包含的范围,是一个签名
           ---> ××××开始
30         --->30代表DER序列开始
44         --->代表DER序列长度,16进制,所以长度为:16×4+4=68字节 
           --->》》》开始
02         --->//一个整数值
20         --->//整数的长度(32字节)
6e4337c360d437e541d0614edd76b2a2c455349fef5a6e5e42d27a582c565176 ---->  R
02         --->//一个整数值
20         --->//整数的长度(32字节)
51f916ec38ded2f5a5ad54148a0912b286dd4278403872ec9a14b31858a69136 ---->  S     
           ---->》》》结束
01         --->签名hash类型(sighash) 
           ---> ×××××结束
21         --->这个是pubKey的长度,表示:16×2+1=33字节
020155ad90a496a89f3744eae693d4098128e0e5f00b886a6d95b9f7c9440a386a ----> pubKey,公钥
ffffffff

<!-----Input 2 ------->
72b4a9ded6dfb98caf008964cda5628c675e183f6513d8e61e27097b03ad60c8
38000000
6a
47         --->//数据的长度。//47代表××××所包含的范围,是一个签名
           ---> ××××开始
30         --->30代表DER序列开始
44         --->代表DER序列长度,16进制,所以长度为:16×4+4=68字节 
           --->》》》开始
02         --->//一个整数值
20         --->//整数的长度(32字节)
3f137a70d457c5b7845508bcb9cfe7d441b571d56f3e23feef48af92fe95345c ---->  R
02         --->//一个整数值
20         --->//整数的长度(32字节)
27ab89e387f38ae0d8d23e3203de7aa11ef0b906f9f4ecbfe4416f027273e7d8 ---->  S   
           ---->》》》结束
01         --->签名hash类型(sighash) 
           ---> ×××××结束
21         --->这个是pubKey的长度,表示:16×2+1=33字节
037ba1425eb3cf7ce27abaf449f547bdaa651c308845769fc96488ac355c5349dc ----> pubKey,公钥
ffffffff

<!-----Input 3 ------->
ee55cdd5a8a19f7fe0fb96335609fb851fd5b0f8830b68ebb6864d4d0dabea6b
00000000
6b
48         --->//数据的长度。//48代表××××所包含的范围,是一个签名
           ---> ××××开始
30         --->30代表DER序列开始
45         --->代表DER序列长度,16进制,所以长度为:16×4+5=69字节 
           --->》》》开始
02         --->//一个整数值
20         --->//整数的长度(32字节)
2165438ac01215bf4e3e368019ffe6accc36a22680db6da2b9dcefcc6a489fca ---->  R
02         --->//一个整数值
21         --->//整数的长度(33字节)
009ad2708d5e43ddebfba651bdd1c9c9707ecd940aad76c2fe43643f54b29165ce ---> S
           ---->》》》结束
01         --->签名hash类型(sighash) 
           ---> ×××××结束
21         --->这个是pubKey的长度,表示:16×2+1=33字节
02f781905c5e8192faabef879832e7a8ed24e1b16b4928d5116ea2de5ba43cb67e ----> pubKey,公钥
ffffffff

<!-----Output 1 ------->
01
5b6f1e0000000000
19     ---->pk script长度,16×1+9=25字节//OP_DUP
76     ---->OP_DUP
a9     ---->OP_HASH160
14     ---->  //(20字节的push数据)
b9fac5599055253a9bcfac69b0d8a15bb09749be ---->//20字节 data to push
88     ---->//OP_EQUALVERIFY
ac     ---->//OP_CHECKSIG
00000000  ---->锁定时间