← 返回总目录 · 区块链技术与应用笔记(BTC)
比特币交易通过一种名为 Bitcoin Script 的简易脚本语言来定义和验证交易条件。每笔比特币交易包含两部分主要内容:输入(Inputs):用于引用和花费之前的交易输出。输出(Outputs):定义新的比特币接收者及其支付条件。输入脚本和输出脚本是这两部分的核心组成部分,分别用于解锁和锁定比特币。
输出脚本(Output Script,也称为 scriptPubKey)
1. 定义
输出脚本是比特币交易中的一段脚本代码,定义了比特币输出的锁定条件。它指定了谁可以花费该输出中的比特币以及如何花费。
2. 作用
- 锁定比特币:设置条件,使得只有满足这些条件的用户才能花费该输出的比特币。
- 定义接收者:指定接收比特币的地址或其他条件。
3. 典型结构
输出脚本通常采用以下格式:
最常见的输出脚本类型包括:
a. P2PKH(Pay to Public Key Hash)
这是最常见的输出脚本类型,使用用户的公钥哈希(即比特币地址)作为锁定条件。
脚本结构:
解释:
OP_DUP:复制栈顶部的元素。
OP_HASH160:对公钥进行哈希(SHA-256 后取前160位)。
<PubKeyHash>:接收者的公钥哈希。
OP_EQUALVERIFY:验证两个栈顶元素是否相等,若不等则交易失败。
OP_CHECKSIG:验证签名是否有效。
流程:
- 把接收者的公钥哈希嵌入脚本中。
- 只有持有对应私钥的用户,能够提供有效的签名和公钥,从而解锁并花费该输出。
b. P2SH(Pay to Script Hash)
允许将更复杂的脚本条件隐藏在哈希值中,使得输出更加灵活。
脚本结构:
解释:
OP_HASH160:对赎回脚本进行哈希。
<ScriptHash>:赎回脚本的哈希值。
OP_EQUAL:验证两个栈顶元素是否相等。
流程:
- 创建一个赎回脚本,定义复杂的支付条件(例如多重签名)。
- 对赎回脚本进行哈希,生成
ScriptHash。
- 输出脚本中嵌入
ScriptHash。
- 花费时,提供赎回脚本和满足其条件的数据。
c. OP_RETURN
用于在区块链上嵌入不可花费的数据。
脚本结构:
解释:
OP_RETURN:标识该输出为数据存储类型。
<数据>:要存储的任意数据,通常限制在80字节以内。
特点:
- 不可花费:包含
OP_RETURN的输出无法被花费,等同于“销毁”比特币。
- 数据存储:用于记录元数据、消息、代币发行等。
4. 应用场景
- 普通支付:使用 P2PKH 脚本,将比特币发送到特定地址。
- 复杂支付条件:使用 P2SH 脚本,实现多重签名、时间锁定等复杂条件。
- 数据存储与智能合约:使用
OP_RETURN脚本,在区块链上嵌入数据,实现简单的智能合约功能。
输入脚本(Input Script,也称为 scriptSig)
1. 定义
输入脚本是比特币交易中的一段脚本代码,用于解锁和花费之前交易的输出。它提供了满足之前输出脚本中锁定条件的必要数据。
2. 作用
- 解锁比特币:提供必要的数据(如签名、公钥)来满足之前输出脚本设定的条件。
- 授权花费:证明交易发起者有权花费这些比特币。
3. 典型结构
输入脚本通常采用以下格式:
最常见的输入脚本类型包括:
a. P2PKH 输入脚本
针对 P2PKH 输出脚本,输入脚本需要提供有效的签名和对应的公钥。
脚本结构:
解释:
<Signature>:对交易数据的签名,证明拥有对应私钥。
<PublicKey>:用于验证签名的公钥,需与输出脚本中的公钥哈希相匹配。
流程:
- 提供签名和公钥。
- 验证公钥哈希是否匹配输出脚本中的
<PubKeyHash>。
- 验证签名是否有效。
b. P2SH 输入脚本
针对 P2SH 输出脚本,输入脚本需要提供满足赎回脚本条件的数据和赎回脚本本身。
脚本结构:
解释:
<满足赎回条件的数据>:根据赎回脚本的要求提供的数据,例如多签名中的签名。
<Redeem Script>:原始定义支付条件的脚本,用于与输出脚本中的哈希值进行匹配和验证。
流程:
- 提供满足赎回脚本条件的数据(如签名)。
- 提供赎回脚本。
- 验证赎回脚本的哈希值是否与输出脚本中的
<ScriptHash>相匹配。
- 执行赎回脚本,验证提供的数据是否满足条件。
c. OP_RETURN 输入脚本
一般情况下,
OP_RETURN 输出脚本不需要输入脚本,因为这些输出是不可花费的。4. 应用场景
- 普通支付:使用 P2PKH 输入脚本,提供签名和公钥来解锁比特币。
- 复杂支付:使用 P2SH 输入脚本,提供满足赎回脚本条件的数据和赎回脚本本身。
- 多重签名:在输入脚本中提供多个签名来满足多签名赎回脚本的要求。
输入脚本与输出脚本的交互过程
1. 交易创建与输出
当用户 A 想向用户 B 发送比特币时,A 创建一个交易,包含一个或多个输出。每个输出定义了接收的比特币数量和锁定条件(即输出脚本)。
示例:
User A 向 User B 发送 1 BTC:
- 输出脚本:
2. 交易确认与存储
该交易被比特币网络验证并打包进区块链,成为一个未花费的交易输出(UTXO)。这时,输出脚本锁定了 1 BTC,只有满足脚本条件的用户才能花费。
3. 未来的交易与输入脚本
当 User B 想要花费这 1 BTC 时,他需要创建一个新的交易,引用之前的输出作为输入,并提供满足输出脚本条件的输入脚本。
步骤:
- 引用之前的输出:新交易的输入引用 User A 发送给 User B 的那笔输出(通过交易 ID 和输出索引)。
- 提供输入脚本:User B 在输入脚本中提供签名和公钥,满足之前输出脚本的条件。
- 定义新的输出:新交易中定义比特币的接收者及其锁定条件。
示例:
User B 向 User C 发送 0.5 BTC:
- 输入脚本:
- 输出脚本:
4. 验证与执行
比特币网络验证新交易时,会执行以下步骤:
- 执行输入脚本:解锁条件,提供签名和公钥。
- 执行输出脚本:锁定条件,验证公钥哈希是否匹配,验证签名是否有效。
如果所有条件满足,交易被确认,1 BTC 的所有权从 User B 转移到 User C。
具体示例分析
1. 创建交易输出(User A 向 User B 发送比特币)
输出脚本:
7c076ff316cb4a4dac2edc8a3f06e6b05c3f12ea是 User B 的公钥哈希。
解释:
- 只有拥有私钥对应于该公钥哈希的用户,才能花费这笔比特币。
2. 花费交易输出(User B 向 User C 发送比特币)
输入脚本:
3045022100dff1...022100f8ce...是 User B 对交易数据的签名。
<User B 的公钥>是 User B 的公钥,用于验证签名。
输出脚本:
3a3b2c1d4e5f6g7h8i9j0a1b2c3d4e5f6g7h8i9j是 User C 的公钥哈希。
验证过程:
- 执行输入脚本:
- 提供签名和公钥。
- 将公钥进行哈希,与输出脚本中的公钥哈希进行比对。
- 验证签名是否有效。
- 执行输出脚本:
- 确认提供的公钥哈希与输出脚本中的哈希一致。
- 验证签名有效后,允许花费。
结果:
- 比特币从 User B 转移到 User C。
op_return可以销毁比特币
OP_RETURN 是比特币脚本中的一个特殊操作码,允许用户在交易中嵌入不可花费的数据。通过使用 OP_RETURN,可以实现 “销毁” 比特币;当创建包含 OP_RETURN 的交易时,指定的比特币数量会被发送到该输出,但由于设置了 OP_RETURN,这些比特币会变得不可用。根据前面讲的,输入脚本是用于解锁之前的输出的,面对
OP_RETURN时- 没有可解锁的条件:
OP_RETURN的输出脚本不是设计用来被解锁的。任何后续输入脚本都没有与之匹配的条件,因为OP_RETURN本身并不定义一个允许花费的条件。- 输入脚本的内容(例如签名、公钥)在解锁
OP_RETURN输出时是完全无效的,因为输出脚本没有要求验证的公钥哈希,也没有签名等条件。
- 比特币脚本执行:
- 在比特币脚本执行过程中,包含
OP_RETURN的输出被立即视为“销毁”的比特币。网络中的节点在验证交易时只会检查其存在性,而不会尝试解锁它。
可以把
OP_RETURN 的机制想象成在比特币网络中加入一种特殊的输出类型,具有如下特性:- 禁止消费:一旦某个输出设置成
OP_RETURN,这表示这些比特币的一切消费权利已经被放弃,即使通过提供签名、公钥等传统方式也无法再次获取这些比特币。
- 目的:这种设计让用户可以在区块链中存储自定义喜欢的信息(不再与比特币相关联),同时还能减轻全网的存储负担。因为可以选择不存储这些不可用输出的具体信息。
- 作者:JIAHE
- 链接:https://blog.jiaheliu.top/Study-Notes/BTC-Script-1-Input-and-Output-Scripts
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。


