BTC基于脚本公钥交易的签名过程

签名过程主要是对交易进行签名,故首先需要了解BTC的交易结构组成。

一、普通交易结构

字节字段描述
4版本明确这笔交易参照的规则
1-9输入计数器包含的交易输入数量
不定输入【见普通交易输入】一个或多个交易输入
1-9输出计数器包含的交易输出数量
不定输出【见普通交易输出】一个或多个交易输出
4锁定时间一个区块号或UNIX时间戳

普通交易输入

字节字段描述
32交易哈希值指向被花费的UTXO所在的交易的哈希指针
4输出索引被花费的UTXO的索引号,第一个是0
1-9解锁脚本大小用字节表示的后面的解锁脚本长度
不定解锁脚本满足UTXO解锁脚本条件的脚本
4序列号目前未被使用的交易替换功能,设为0xFFFFFFFF

普通交易输出

字节字段描述
8总量用聪表示的比特币值
1-9锁定脚本大小用字节表示的后面的锁定脚本长度
不定锁定脚本一个定义了支付输出所需条件的脚本

二、构建原始交易RawTransaction

现在假设有一个地址S_ADD_001,该地址收到了两笔转账,一笔交易ID为TX001,金额0.4BTC,另一笔交易ID为TX002,金额1.1BTC,这两笔收入都是在其交易Output的第0条,也就是Index=0。现在我们想要做一笔1.2BTC的转账[收款人的地址R_ADD_001],然后给一定的手续费后,找零到原地址,所以我们会构建一笔交易,该交易有2Input和2Output。构造如下:

既有的UTXO输出结构
UTXO

TxHash:TX001,

OutIndex:0,

Amount:0.4BTC,

PkScript:【锁定脚本 L1】

OP_DUP OP_HASH160 PUSHDATA(20)S_ADD_001 OP_EQUALVERIFY OP_CHECKSIG

TxHash:TX002,

OutIndex:0,

Amount:1.1BTC,

PkScript:【锁定脚本】

OP_DUP OP_HASH160 PUSHDATA(20)S_ADD_001 OP_EQUALVERIFY OP_CHECKSIG

锁定脚本的S_ADD_001位置,往往是公钥或者公钥的HASH值【BTC地址】 

构造原始交易[命名为T]:
inputoutput
PreviousOutPoint={

TxHash:TX001,

OutIndex:0}

SignatureScript =NULL,Sequence =0xFFFFFFFF

Value=29910240

PkScript=

OP_DUP OP_HASH160 PUSHDATA(20)S_ADD_001OP_EQUALVERIFY OP_CHECKSIG

PreviousOutPoint={

TxHash:TX002,

OutIndex:0}

 SignatureScript =NULL,Sequence =0xFFFFFFFF

Value=120000000

PkScript=

OP_DUP OP_HASH160 PUSHDATA(20)R_ADD_002 OP_EQUALVERIFY OP_CHECKSIG

三、签名过程

在比特币中,对交易T的签名流程是这样的:

1.查找交易T对应的UTXO

2.获得该UTXO对应的锁定脚本

3.复制该交易T对象,并在复制副本中将该Input的解锁脚本字段的值设置为对应的锁定脚本

4.清除其他Input的解锁脚本字段

5.对这个改造后的交易对象计算SHA-256值,

6.使用私钥对SHA-256值进行签名。

四、示例

现在需要用私钥,对该交易进行签名,因为有2个Input,所以需要进行签名2次,每个签名的原理是一样的,以第一个Input例来说明。

1、交易T复制一个副本,并改为如下形式,该副本命名为T_C
inputoutput
PreviousOutPoint={

TxHash:TX001,

OutIndex:0}

SignatureScript =OP_DUP OP_HASH160 PUSHDATA(20) S_ADD_001 OP_EQUALVERIFY OP_CHECKSIG,Sequence =0xFFFFFFFF

Value=29910240

PkScript=

OP_DUP OP_HASH160 PUSHDATA(20)S_ADD_001OP_EQUALVERIFY OP_CHECKSIG

PreviousOutPoint={

TxHash:TX002,

OutIndex:0}

 SignatureScript =NULL,Sequence =0xFFFFFFFF

Value=120000000

PkScript=

OP_DUP OP_HASH160 PUSHDATA(20)R_ADD_002 OP_EQUALVERIFY OP_CHECKSIG

绿色背景内容来自交易TX001的UTXO上的锁定脚本值,数据直接拷贝过来

2、对T_C序列化后做SHA_256得M值【256位】
3、用私钥对M进行签名,得签名S1
4、对输入1签名之后结果如下
inputoutput
PreviousOutPoint={

TxHash:TX001,

OutIndex:0}

SignatureScript =

PUSHDATA(72)[签名S1] PUSHDATA(33)[公钥值]

,Sequence =0xFFFFFFFF

Value=29910240

PkScript=

OP_DUP OP_HASH160 PUSHDATA(20)S_ADD_001OP_EQUALVERIFY OP_CHECKSIG

PreviousOutPoint={

TxHash:TX002,

OutIndex:0}

 SignatureScript =NULL,Sequence =0xFFFFFFFF

Value=120000000

PkScript=

OP_DUP OP_HASH160 PUSHDATA(20)R_ADD_002 OP_EQUALVERIFY OP_CHECKSIG

5、对输入2进行签名 

同样的道理,制造一个交易的副本,然后把第一个Input的SignatureScript清空,然后给第二个Input的SignatureScript赋值:

inputoutput
PreviousOutPoint={

TxHash:TX001,

OutIndex:0}

SignatureScript =NULL,Sequence =0xFFFFFFFF

Value=29910240

PkScript=

OP_DUP OP_HASH160 PUSHDATA(20)S_ADD_001OP_EQUALVERIFY OP_CHECKSIG

PreviousOutPoint={

TxHash:TX002,

OutIndex:0}

 SignatureScript =OP_DUP OP_HASH160 PUSHDATA(20) S_ADD_001 OP_EQUALVERIFY OP_CHECKSIG,Sequence =0xFFFFFFFF

Value=120000000

PkScript=

OP_DUP OP_HASH160 PUSHDATA(20)R_ADD_002 OP_EQUALVERIFY OP_CHECKSIG

 显然这个副本与第一个签名时的数据【数据位置不同,同时可能锁定脚本可能不同】是不一样的,所以签名结果也不一样。设输入2的签名为S2

6、组装完整交易:

将S2签名和公钥再放回原始交易中,就变成需要的完整签名的交易:

PreviousOutPoint={

TxHash:TX001,

OutIndex:0}

SignatureScript =

PUSHDATA(72)[签名S1] PUSHDATA(33)[公钥值]

,Sequence =0xFFFFFFFF

Value=29910240

PkScript=

OP_DUP OP_HASH160 PUSHDATA(20)S_ADD_001OP_EQUALVERIFY OP_CHECKSIG

PreviousOutPoint={

TxHash:TX002,

OutIndex:0}

 SignatureScript =PUSHDATA(72)[签名S2] PUSHDATA(33)[公钥值],Sequence =0xFFFFFFFF

Value=120000000

PkScript=

OP_DUP OP_HASH160 PUSHDATA(20)R_ADD_002 OP_EQUALVERIFY OP_CHECKSIG

接下来就可以通过P2P网络发送该交易,并最终被矿工打包确认。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值