好好学习,天天向上

  • 后端开发
    • Rust
  • 区块链
    • BTC
    • Layer2
  • 经济投资
  • 文学创作
    • 哲学思考
    • 随笔
HhxxTtxs
人生到处知何似,应似飞鸿踏雪泥。
  1. 首页
  2. 区块链
  3. BTC
  4. 正文

比特币脚本

6 8 月, 2024 392点热度 0人点赞 0条评论
内容 隐藏
1 什么是比特币脚本
2 比特币交易的分类
2.1 1. P2PKH(Pay-to-PubKey-Hash)
2.2 2. P2PK(Pay-to-PubKey)
2.3 3. P2SH(Pay-to-Script-Hash)
2.4 4. P2MS(Pay-to-Multi-Sig)
2.5 5. OP_RETURN
2.6 6. P2WPKH(Pay-to-Witness-Script-Hash)
2.7 7. P2WSH(Pay-to-Witness-Script-Hash)
2.8 8. P2TR(Pay-to-Taproot)
2.9 总结

什么是比特币脚本

我们知道比特币是基于UTXO来进行交易的。例如你有10BTC的UTXO,准备给作者转 2BTC,那么就有输入一个10BTC的UTXO,输出 2BTC的UTXO给作者,8BTC的UTXO给自己(忽略手续费)。原来的10BTCUTXO就被废弃掉了。每一个UTXO都有一个锁定脚本 scriptPubKey,当我们要花费一个UTXO的时候,需要提供一个对应的解锁脚本 scriptSig 以证明有花费该UTXO的权利。

如下图所示交易:

{
  "txid": "17d568fc91ffc51cd554e08f59db77b204c4a8a49e0b404af9eb5fdeebd3d303",
  "size": 223,
  "version": 1,
  "locktime": 0,
  "fee": 2230,
  "inputs": [
    {
      "coinbase": false,
      "txid": "1791529d02204891dd3f42412e08055f310ae8d1a0eb11eff4c84ee1a4ed3a50",
      "output": 1,
      "sigscript": "483045022100cc1c03cf0ce22994a706b0274bf3d4a7d9ceb203a828b70a45531e698680c71102200aad893eb2928f9cd4ea48eae2437700a5516fabd1b13dd1419b584e09d22430012103b4a98edeb16a5e868fa215dddf7a2ad864ff3c61cd2c0ac0b0f46b6898f8fdd1",
      "sequence": 4294967295,
      "pkscript": "76a914a0a82a7bac78569ce1ea49b697eea51c41ebdf2a88ac",
      "value": 98871,
      "address": "1FeUa4wNZfDdt474PRwtBPPprinEHDmADd",
      "witness": []
    }
  ],
  "outputs": [
    {
      "address": "bc1qgl3y3nrznamdmmlvtr9gd9us82p34uz883a55t",
      "pkscript": "001447e248cc629f76ddefec58ca8697903a831af047",
      "value": 23000,
      "spent": false,
      "spender": null
    },
    {
      "address": "1CDWiDh3566yFqQ5RaPqfZmy4JJSJmFX42",
      "pkscript": "76a9147b072d274528006299b6ef8cb26a20704e3ae2c188ac",
      "value": 73641,
      "spent": false,
      "spender": null
    }
  ],
  "block": {
    "height": 855143,
    "position": 7
  },
  "deleted": false,
  "time": 1722646677,
  "rbf": false,
  "weight": 892
}

交易来源

如图所示inputs当中有一个UTXO,outputs当中有两个UTXO,其中inputs当中的pkscript对应锁定脚本,sigscript对应解锁脚本。

这里的pkscript和 都是16进制表示的比特币脚本操作码,翻译下如下:

pkscript:
76a914a0a82a7bac78569ce1ea49b697eea51c41ebdf2a88ac
OP_DUP OP_HASH160 0x14(随后跟的数据长度是0x14长度) a0a82a7bac78569ce1ea49b697eea51c41ebdf2a OP_EQUALVERIFY OP_CHECKSIG

sigscript:
483045022100cc1c03cf0ce22994a706b0274bf3d4a7d9ceb203a828b70a45531e698680c71102200aad893eb2928f9cd4ea48eae2437700a5516fabd1b13dd1419b584e09d22430012103b4a98edeb16a5e868fa215dddf7a2ad864ff3c61cd2c0ac0b0f46b6898f8fdd1
0x48(随后跟的数据长度是0x14长度) sign_data 0x21 pub_key  

具体脚本内容说明见文章:比特币脚本pkScript与signScript解读

那比特币是如何确定解密脚本是合法的呢?其实就是将pkscript与signscript对应的比特币op_code以及其中添加的相关数据排列在一起,例如上面所示数据排列在一起:

//上面数据中的0x48 0x21 0x14指随后跟的数据长度,脚本呢执行的时候省略掉
//排列的顺序 signscript pkscript
sign_data pub_key OP_DUP OP_HASH160 a0a82a7bac78569ce1ea49b697eea51c41ebdf2a OP_EQUALVERIFY OP_CHECKSIG

然后用栈式虚拟机进行执行,最后OP_CHECKSIG的结果如果是true(整个脚本执行完成后,堆栈顶端留下的结果必须是 True,表示交易验证通过。),那就说明该解密脚本是合法的。

图片来源

以上就是比特币脚本的简单说明。比特币脚本采用操作码的形式,来定义一个UTXO的锁定与使用权限,增加了灵活性与可编程性,同时为之后可能的扩展也留下了扩展空间。

比特币交易的分类

比特币交易有以下多种形式:

1. P2PKH(Pay-to-PubKey-Hash)

支付给公钥哈希。是最常见的一种交易类型,将比特币交易到指定的公钥hash,只有持有对应公钥哈希私钥的用户才可以花费该比特币(UTXO)。

对应的脚本示例如下:

//pkscript
OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG

//signscript
<signature>(签名数据) <PubKey>(公钥)

//组合起来
<signature>(签名数据) <PubKey>(公钥) OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG

2. P2PK(Pay-to-PubKey)

支付到指定公钥。未经OP_HASH160。将比特币交易到指定的公钥,只有持有对应私钥的用户才可以花费该比特币(UTXO)。

对应的脚本示例如下:

//pkscript
<Signature>(签名数据)

//signscript
<PubKey>(公钥) OP_CHECKSIG

//组合起来
<PubKey>(公钥) OP_CHECKSIG <Signature>(签名数据)

3. P2SH(Pay-to-Script-Hash)

支付到脚本哈希。P2PKH是支付到对应的公钥哈希,而P2SH是支付到一个脚本的哈希,该脚本也是通过比特币指令书写的。在进行执行时,首先会校验脚本哈希是否正确的,如果脚本哈希是正确的。接着就执行脚本哈希对应的脚本最后执行的结果是否是正确的。

对应的脚本示例如下:

//pkscript
OP_HASH160 <ScriptHash> OP_EQUAL

//signscript
<Signature1> <RedeemScript>

//RedeemScript 示例
<RedeemScript> = OP_1 <PubKey1> <PubKey2> OP_2 OP_CHECKMULTISIG

//组合起来
<Signature1> <RedeemScript> OP_HASH160 <ScriptHash> OP_EQUAL

4. P2MS(Pay-to-Multi-Sig)

支付到多重签名。有时会出现这种情况,希望自己的BTC可以由多人保管,只需要凑齐多人中的一部分人对应的私钥即可花费该BTC,那么就可以使用P2MS交易类型。P2MS交易将资金锁定在多个公钥哈希中,使用其中的全部或者一部分签名即可解锁对应BTC进行花费。

对应的脚本示例如下:

//pkScript
OP_2 <PubKey1> <PubKey2> <PubKey3> OP_3 OP_CHECKMULTISIG

//scriptSig(这里假设有公钥哈希对应的两个签名)
OP_0 <Signature1> <Signature2>

//组合起来
OP_0 <Signature1> <Signature2> OP_2 <PubKey1> <PubKey2> <PubKey3> OP_3 OP_CHECKMULTISIG

5. OP_RETURN

比特币存储。OP_RETURN是一种特殊的交易类型,也可以称为一种特殊的UTXO类型。对应输出的UTXO加密脚本如果包含OP_RETURN操作符,那么其中就允许用户在对应的脚本中添加至多80字节的数据(注意:输出的的UTXO如果是OP_RETURN交易类型,将不可再被交易,而是被固定在了比特币链上),这个也是比特币符文的底层实现基础。

对应的脚本示例如下:

//输出的UTXO scriptSig
OP_RETURN 48656c6c6f2c20426974636f696e21 

//其中48656c6c6f2c20426974636f696e21是我们要存储的数据的16进制表示

6. P2WPKH(Pay-to-Witness-Script-Hash)

P2WPKH是Segregated Witness(隔离见证,简称SegWit)的一部分,旨在提高交易效率和降低交易费用,同时解决交易延展性(Transaction Malleability)问题。具体升级信息见:BTC隔离见证SegWit。P2WPKH与P2PKH交易类似,不同的地方有以下几点:

  1. 地址格式:P2PKH地址以1开头,P2WPKH地址以bc1开头。
  2. 锁定脚本:P2PKH使用更复杂的锁定脚本,而P2WPKH的锁定脚本更简单。
  3. 解锁脚本:P2PKH的解锁脚本包含在输入中,而P2WPKH将解锁数据放入见证(witness)结构中。
  4. 交易大小和费用:P2WPKH交易通常更小,交易费用更低。
  5. 交易验证过程:P2WPKH交易的验证过程利用了见证数据,提升了效率。

对应的脚本示例如下:

//pkScript
OP_0 <PubKeyHash>

//见证数据(Witness)中的scriptSig
<Signature> <PublicKey>

//组合起来
<Signature> <PublicKey> OP_0 <PubKeyHash>

7. P2WSH(Pay-to-Witness-Script-Hash)

P2WSH也是segwit升级的一部分,具体升级信息见:BTC隔离见证SegWit。P2WSH与P2SH交易类似,不同的地方有以下几点:

  1. 地址格式:P2SH地址以3开头,P2WSH地址以bc1开头,通常使用Bech32编码。
  2. 锁定脚本:P2SH使用RIPEMD-160哈希,P2WSH使用SHA-256哈希。
  3. 解锁脚本:P2SH的解锁脚本包含在ScriptSig中,P2WSH的解锁数据放入见证结构中。
  4. 交易大小和费用:P2WSH交易通常更小,交易费用更低。
  5. 交易验证过程:P2WSH利用见证数据,验证和执行的效率更高。

对应的脚本示例如下:

//pkScript
OP_0 <ScriptHash>

//见证数据(Witness)中的scriptSig
<Signature1> <Signature2> <WitnessScript>

//组合起来
<Signature1> <Signature2> <WitnessScript> OP_0 <ScriptHash>

8. P2TR(Pay-to-Taproot)

P2TR是比特币Taproot升级之后新的交易类型,Taproot的主要目的是提高比特币的隐私性、效率和灵活性。Taproot结合了Schnorr签名和MAST(Merkelized Abstract Syntax Tree)技术,旨在优化比特币的智能合约功能。它使得复杂的交易在链上看起来与普通的单一签名交易几乎没有区别,从而提升了隐私性。P2TR地址使用Bech32m编码,以bc1p开头。该交易目前也是铭文、符文等交易的基础。

P2TR交易将比特币锁定在一个脚本上,允许用户向 Schnorr 公钥或各种其他脚本的 Merkle 根支付,类似于结合P2PKH与P2SH。不过区别有如下:

  1. 采用的签名是 Schnorr 签名算法,可见文章:比特币签名算法的实现,Schnorr 签名算法更加高效和简单。这个也是提升效率的原因。
  2. 支付到脚本哈希时,对应的脚本哈希是一个基于MAST技术的merkle root。可以简单理解为拥有多个可花费UTXO的条件,满足其中一个条件即可花费对应的UTXO。在输出解锁脚本时,不用输出所有的“条件”(每一个条件可以理解为一个脚本),可以只揭示其中的一个满足条件的脚本,同时结合一些输出merkle root对应的哈希,最后组成解锁脚本。这个也是提高交易灵活性的原因。

如图所示,我们需要通过条件A脚本来解锁UTXO,那么只需要提供条件A脚本、条件B脚本哈希、hashB(条件C脚本hash与条件D脚本hash之后再哈希获得)。因为只有解锁的时候才会知道是什么交易类型以及使用了什么交易条件,所以提升了隐私性。

对应的脚本示例如下:

//pkScript 
//Xonly-PubKey 去掉前缀字节的32字节公钥哈希(这里的公钥是特殊的被称为Tweaking的公钥)
OP_1 <Xonly-PubKey>

//见证数据(Witness)中的scriptSig
//Control Block包含了路径证明信息,用于证明该交易满足MAST中的条件
<Signature> <Control Block> <Script>

//组合起来
<Signature> <Control Block> <Script> OP_1 <Xonly-PubKey>

总结

比特币节点通过将解锁脚本(scriptSig)和锁定脚本(pkScript)组合在一起执行,利用堆栈进行一系列操作码和数据处理,最终验证交易的合法性。对于P2SH交易,节点还需要额外执行嵌入的赎回脚本(RedeemScript)以完成完整的验证流程。这种基于堆栈的脚本执行机制确保了比特币交易的灵活性和安全性。之后的文章会通过比特币testnet网络对这些交易进行编码测试。

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: 区块链 比特币
最后更新:6 8 月, 2024

hhxxttxs

五年服务端开发,现专职区块链,偏零知识Layer2工程方向

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

Archives

  • 2026 年 2 月
  • 2025 年 9 月
  • 2025 年 8 月
  • 2025 年 7 月
  • 2025 年 1 月
  • 2024 年 9 月
  • 2024 年 8 月
  • 2024 年 7 月
  • 2024 年 6 月
  • 2024 年 5 月
  • 2024 年 4 月
  • 2024 年 3 月

Categories

  • BTC
  • cuda
  • L2
  • rust
  • 其他
  • 区块链
  • 后端开发
  • 哲学思考
  • 文学创作
  • 算法
  • 经济投资
  • 链开发
  • 零知识

COPYRIGHT © 2024 好好学习,天天向上. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang