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

欢迎转载,但请注明出处!!

    最近项目需要接触到了数字货币,然后需要弄明白比特币整个交易流程,在自行构建tx(transaction)数据的过程中,遇到一些问题,现在简明扼要地进行阐述和讲解。

注:以下的例子中假设都使用的P2PKH交易标准(pay-to-public-key-hash)

一、一个输入一个输出的交易构建与签名实现

比特币交易数据的结构如下:

standard BTC Tx struct defined below:

    4byte  version

    1byte  tx_in_count

    ??      tx_in

    1byte  tx_out_count

    ??      tx_out

    4byte  lock_time

具体每个成员的含义,请自行通过阅读bitcoin 协议说明的官方文档了解。

如果一个交易中只包含一个输入和一个输出,则构建一个交易的原始数据如下(已使用https://btc.com/tools/tx/decode完成解码显示):

{

    "txid": "400b47d407b0e216c6e0d74df2387f52823e50b3d7a463ac6881806580134d0f",

    "hash": "400b47d407b0e216c6e0d74df2387f52823e50b3d7a463ac6881806580134d0f",

    "size": 110,

    "vsize": 110,

    "version": 1,

    "locktime": 0,

    "vin": [

        {

            "txid": "a37938cb6e7b91dbc36f9e07bdd292b9bfc8a7034cb254e7e3c92075e0d3cfc9",

            "vout": 0,

            "scriptSig": {

                "asm": "OP_DUP OP_HASH160 b2fd829c977a49044cd21e8762a99ce670800dbe OP_EQUALVERIFY OP_CHECKSIG",

                "hex": "76a914b2fd829c977a49044cd21e8762a99ce670800dbe88ac"

            },

            "sequence": 4294967295

        }

    ],

    "vout": [

        {

            "value": 98000,

            "n": 0,

            "scriptPubKey": {

                "asm": "OP_DUP OP_HASH160 762d0c29ad755dd850af43e6b99ef48f1ff680ab OP_EQUALVERIFY OP_CHECKSIG",

                "hex": "76a914762d0c29ad755dd850af43e6b99ef48f1ff680ab88ac",

                "reqSigs": 1,

                "type": "pubkeyhash",

                "addresses": [

                    "1BmrhbLE6vdy1mSMTAnq1YDL3XCPLVu64t"

                ]

            }

        }

    ]

}

其对应的16进制串为:

0100000001c9cfd3e07520c9e3e754b24c03a7c8bfb992d2bd079e6fc3db917b6ecb3879a3000000001976a914b2fd829c977a49044cd21e8762a99ce670800dbe88acffffffff01d07e0100000000001976a914762d0c29ad755dd850af43e6b99ef48f1ff680ab88ac0000000001000000

这里插一句:一笔交易在广播到BTC网络之前,需要先进行签名处理,简而言之就是需要证明两个事情:

1、这笔交易中的输入,确实有钱存在,且大于等于输出的数额;

2、这笔交易中的输入,确实是你的(即你掌握了这笔交易输入所描述的那笔钱的私钥)

为了达成以上的证明,需要将自己的签名数据和公钥信息加入到交易的输入脚本中,一并广播出去,这样才能通过其它节点对这个交易合法性的检查,最终被写入区块。

签名的大致流程如下:

1、准备好一个原始的交易数据;

2、对这个原始的交易数据进行两次SHA256 hash运算,得到固定长度的hash散列;

3、使用椭圆曲线算法,结合你自己的私钥,对上述的hash散列值进行加密计算,得到签名数据;

重点是:如何准备好一个原始的交易数据???

解答:根据交易的数据结构,可以很轻易地填充好注入version、tx_in_num、tx_out_num、lock_time等数据,但是tx_in结构中本身就包含了script_len和signature_script这两个成员,在填充原始交易的时候,这两个成员也需要进行赋值填充:

以P2PKH交易类型为例,从上图,可看出signature_script中置入的数据:

OP_DUP OP_HASH160 b2fd829c977a49044cd21e8762a99ce670800dbe OP_EQUALVERIFY OP_CHECKSIG

这部分数据其实是你将要花费的这笔UTXO所在交易的输出脚本。说白了就是你发起的这笔交易中,你的输入必定能够在区块链中找到一条记录,那条记录里面描述了其他人给你支付了一笔钱。我们置入的这部分数据,就是从那条记录中取出的输出脚本。由于P2PKH交易的输出脚本格式固定,所以script_len也能轻易计算出长度,script_len = 25。

输入中的script_len和signature_script填充完成以后,就可以对这个原始的tx交易数据进行签名了,签名步骤如上所述,最后得到的签名数据如下:

4730440220195ee72370253823b08b155c78daba812549104e5b1b4a6c1fecf4364e2c1cca0220169b3c0c558eb9e61ca3a6ac816c0c251427573b3e147be62701a3208c2775090141043d23e5f0758a53e2a18c8156051ca136d4639db5ceace580583983151113c1e5dcd7523f777fcd5b7ba16fef8dcbf4c2dbcaf91dd0c5d72080703517b96c4994

将这部分数据重新置入到signature_script域中,根据这部分脚本的数据长度,重新对script_len 赋值,得到真正可以广播的交易数据如下(已使用https://btc.com/tools/tx/decode完成解码显示):

{

    "txid": "31be8c8d939081f411e6e557c7bdc25e99ab9f777e680cd651b77660a828d607",

    "hash": "31be8c8d939081f411e6e557c7bdc25e99ab9f777e680cd651b77660a828d607",

    "size": 223,

    "vsize": 223,

    "version": 1,

    "locktime": 0,

    "vin": [

        {

            "txid": "a37938cb6e7b91dbc36f9e07bdd292b9bfc8a7034cb254e7e3c92075e0d3cfc9",

            "vout": 0,

            "scriptSig": {

                "asm": "30440220195ee72370253823b08b155c78daba812549104e5b1b4a6c1fecf4364e2c1cca0220169b3c0c558eb9e61ca3a6ac816c0c251427573b3e147be62701a3208c277509[ALL] 043d23e5f0758a53e2a18c8156051ca136d4639db5ceace580583983151113c1e5dcd7523f777fcd5b7ba16fef8dcbf4c2dbcaf91dd0c5d72080703517b96c4994",

                "hex": "4730440220195ee72370253823b08b155c78daba812549104e5b1b4a6c1fecf4364e2c1cca0220169b3c0c558eb9e61ca3a6ac816c0c251427573b3e147be62701a3208c2775090141043d23e5f0758a53e2a18c8156051ca136d4639db5ceace580583983151113c1e5dcd7523f777fcd5b7ba16fef8dcbf4c2dbcaf91dd0c5d72080703517b96c4994"

            },

            "sequence": 4294967295

        }

    ],

    "vout": [

        {

            "value": 98000,

            "n": 0,

            "scriptPubKey": {

                "asm": "OP_DUP OP_HASH160 762d0c29ad755dd850af43e6b99ef48f1ff680ab OP_EQUALVERIFY OP_CHECKSIG",

                "hex": "76a914762d0c29ad755dd850af43e6b99ef48f1ff680ab88ac",

                "reqSigs": 1,

                "type": "pubkeyhash",

                "addresses": [

                    "1BmrhbLE6vdy1mSMTAnq1YDL3XCPLVu64t"

                ]

            }

        }

    ]

}

真正的16进制数据串如下:

0100000001c9cfd3e07520c9e3e754b24c03a7c8bfb992d2bd079e6fc3db917b6ecb3879a3000000008a4730440220195ee72370253823b08b155c78daba812549104e5b1b4a6c1fecf4364e2c1cca0220169b3c0c558eb9e61ca3a6ac816c0c251427573b3e147be62701a3208c2775090141043d23e5f0758a53e2a18c8156051ca136d4639db5ceace580583983151113c1e5dcd7523f777fcd5b7ba16fef8dcbf4c2dbcaf91dd0c5d72080703517b96c4994ffffffff01d07e0100000000001976a914762d0c29ad755dd850af43e6b99ef48f1ff680ab88ac00000000

直接通过P2P方式或者使用网站API就能把这笔交易广播出去了。

多个输入的交易,比这个稍微复杂一下,待续。

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

1HKQyLvLL4zCsbewjxdbV9WsCmqyaZYUUT

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容