2.2 比特币脚本(原理解释和P2PK)
比特币脚本
在比特币世界的话语体系,当我们提到“Alice支付一笔钱给Bob”,首先根据前面学习的UTXO的知识,我们不再想象所谓Alice的账户转账给Bob的账户;而是到Alice控制的一个地址,把对应的UTXO支付到Bob控制的地址;更具体的说,是支付到Bob地址对应的锁定脚本里。Bob需要再使用这笔钱,则需要满足一定的条件才能解锁。
UTXO与比特币脚本的关系
比特币的每笔交易(transaction)不仅仅包含金额,还包含一个关键组件:锁定脚本(ScriptPubKey)。请记住这个单词,他也叫PubKeyScript,锁定脚本。锁定脚本,顾名思义,我们支付一笔钱到一个地址,本质是支付到这个地址对应的锁定脚本,满足一定的条件才能支取。
锁定脚本(ScriptPubKey):
每个UTXO都有一个锁定脚本,规定了花费这个UTXO的条件
最常见的是要求提供匹配特定公钥哈希的签名
例如:"这个UTXO只能被拥有与此公钥哈希匹配的私钥的人花费"
解锁脚本(ScriptSig):
当有人想花费一个UTXO时,必须提供一个解锁脚本
解锁脚本通常包含签名和公钥
它必须满足锁定脚本设定的条件
脚本验证:
解锁脚本和锁定脚本组合执行
如果执行结果为真,UTXO可以被花费
如果为假,交易无效
简单例子
用我们之前的例子扩展一下:
Alice的原始UTXO:
金额: 10比特币
锁定脚本: "只有能证明拥有与Alice公钥哈希匹配的私钥的人才能花费"
Alice创建交易给Bob:
她提供解锁脚本: "Alice的签名 + Alice的公钥"
系统验证: 公钥哈希匹配 + 签名有效 = 允许花费
她创建两个新UTXO:
Bob的7比特币,锁定脚本指向Bob的公钥哈希
Alice的3比特币找零,锁定脚本指向Alice的公钥哈希
这就是为什么比特币被描述为"程序化货币" - 因为每个UTXO不仅仅是一个价值存储,还是一个带有执行条件的小程序。
接下来,我们拿真实的一个交易ID: f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16
,介绍下前面说的UTXO和脚本系统。
就是中本聪(Satoshi Nakamoto,比特币的创造者)向Hal Finney(第一个接收比特币交易的人)发送的10个比特币的交易。
你可以在任何比特币区块浏览器上查看此交易:
交易结构分析
输入(Input)
这笔交易消费了一个来自区块9的挖矿奖励UTXO。中本聪作为比特币的早期矿工,通过挖矿获得了50 BTC的奖励。
输入详情:
前一个交易ID:
0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9
输出索引: 0
脚本类型: 支付到公钥(P2PK)
这里的特别之处在于,这是一个挖矿奖励的UTXO,被称为"coinbase"交易。这类UTXO比较特殊,它们不是之前交易的输出,而是区块奖励直接创建的。
输出(Outputs)
这笔交易创建了两个新的UTXO:
输出 #0:
金额: 10 BTC
收款地址: 关联到Hal Finney
锁定脚本: 标准P2PK (Pay to Public Key)格式
输出 #1:
金额: 40 BTC
收款地址: 返回给中本聪本人(找零)
锁定脚本: 标准P2PK格式
早期比特币的脚本特点
需要注意的是,这笔交易使用的是P2PK(Pay to Public Key)脚本格式,而不是现在更常见的P2PKH(Pay to Public Key Hash)。这体现了比特币早期的特点:
P2PK锁定脚本格式:
<Public Key> OP_CHECKSIG
这种脚本直接在输出中包含了完整的公钥,而不是公钥的哈希值。
相比之下,现代比特币交易通常使用P2PKH格式:
OP_DUP OP_HASH160 <Public Key Hash> OP_EQUALVERIFY OP_CHECKSIG
为什么后来改用P2PKH?
P2PK到P2PKH的转变主要出于两个原因:
安全考虑: P2PKH只暴露公钥哈希而非完整公钥,提供了额外的安全层
节省空间: 公钥哈希(20字节)比完整公钥(33或65字节)小,更节省区块链空间
UTXO模型解析
让我们通过这笔历史交易来理解UTXO模型:
初始状态:
中本聪拥有一个值为50 BTC的UTXO(来自挖矿)
交易后:
原始的50 BTC UTXO被完全消费(销毁)
创建了两个新的UTXO:
10 BTC归Hal Finney所有
40 BTC作为找零返回给中本聪
这个过程展示了UTXO的基本特性:
UTXO必须被完整消费
交易创建新的UTXO
找零是通过创建发回给自己的UTXO实现的
交易验证流程
当Hal Finney后来想花费他的10 BTC时,验证过程是:
他需要提供自己的私钥生成的签名
比特币网络验证这个签名是否与UTXO中公开的公钥匹配
如果验证成功,这个UTXO可以被花费
现在,让我们继续分析Hal Finney如何花费这些比特币,这将帮助我们更深入地理解比特币的解锁过程和脚本执行机制。
交易概览
交易ID: ea44e97271691990157559d0bdd9959e02790c34db6c006d779e82fa5aee708e
时间戳: 2010年11月17日 04:39:27
确认数: 超过79万(截至2025年)
手续费: 0 BTC(早期比特币交易常见)
您可以在区块浏览器上查看此交易: mempool.space查看此交易
Hal Finney在这笔交易中消费了之前从中本聪处接收的10 BTC。让我们看看解锁过程:
输入UTXO:
来源:中本聪发送的10 BTC
脚本类型:P2PK(Pay to Public Key)
原始锁定脚本(ScriptPubKey):
OP_PUSHBYTES_65 04ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84c OP_CHECKSIG
翻译:这个脚本将65字节的公钥推入堆栈,然后检查交易签名是否与此公钥匹配
解锁脚本(ScriptSig):
OP_PUSHBYTES_71 30440220576497b7e6f9b553c0aba0d8929432550e092db9c130aae37b84b545e7f4a36c022066cb982ed80608372c139d7bb9af335423d5280350fe3e06bd510e695480914f01
翻译:这个脚本将71字节的签名推入堆栈
P2PK解锁过程详解
当比特币网络验证这笔交易时,会执行以下步骤:
执行解锁脚本:
将Hal Finney的签名推入堆栈
执行锁定脚本:
将公钥推入堆栈
执行OP_CHECKSIG操作符,该操作符会:
弹出堆栈顶部的公钥
弹出堆栈顶部的签名
验证签名是否正确对应这个交易和公钥
如果验证成功,推入TRUE到堆栈;否则推入FALSE
结果评估:
如果堆栈顶部为TRUE,交易有效
如果为FALSE,交易被拒绝
在这个例子中,签名验证成功,因此Hal Finney成功解锁并花费了这10个比特币。
输出分析(锁定过程)
有趣的是,Hal Finney将这10 BTC发送到了使用更现代P2PKH脚本格式的地址:
输出UTXO:
金额:10 BTC
收款地址:15kDhRAcpgsugmh6mQsTcCHdvbsuYncEEV
脚本类型:P2PKH(Pay to Public Key Hash)
锁定脚本(ScriptPubKey):
OP_DUP OP_HASH160 OP_PUSHBYTES_20 340cfcffe029e6935f4e4e5839a2ff5f29c7a571 OP_EQUALVERIFY OP_CHECKSIG
这个新的P2PKH锁定脚本工作方式如下:
复制提供的公钥(OP_DUP)
对公钥执行哈希操作(OP_HASH160)
将20字节的公钥哈希值推入堆栈
验证计算得到的哈希与脚本中的哈希匹配(OP_EQUALVERIFY)
验证签名(OP_CHECKSIG)
以模拟动画的形式,来介绍堆栈的执行过程。
https://x.com/zzmjxy/status/1895736302932541873
相信看到这里大家对比特币的UTXO和脚本系统有了深刻理解。
这样你会惊奇的发现,你把区块链浏览器的各种字节都看懂了。当你出现这个感觉,你就走向比特币开发的高手之旅了。
Last updated