{"content":{"title":"比特币钱包地址的演变(二)-P2SH","body":"# \r\n# **P2SH的由来**\r\n#\r\n上文提到的P2PKH，只能支付到一个公钥地址，且解锁脚本也是固定的步骤，是一笔简单的C2C支付。日常生活中，还有很多较复杂的支付场景，如支票，组织中多人管理一笔资金，银行承兑等等。比特币预留了交易类型拓展的窗口，其实现方式是比特币脚本。我们先看一封中本聪给加文的邮件：\r\n\r\n*标题：“回复：交易和脚本：DUP HASH160...EQUALVERIFY CHECKSIG”*\r\n\r\n*内容节选：*\r\n\r\n    比特币的性质是0.1版一旦发布，其核心设计在剩余的生命周期中就不再改变。因此，我想将其设计成能支撑各种可能交易类型的系统。问题在于不管是否用到这些类型，都需要特殊的支持代码和数据字段，并且每次只能覆盖一种情况，这会产生海量的特例。解决方案是用脚本来概括问题，因此交易方可以将交易描述为对网络节点评估的断言。节点对交易的了解只需到可以评估支付方是否满足条件就可以了。\r\n\r\n    脚本实际上是一种断言。它只是用来评估真假的方程式。断言是一个生僻的词，所以我称之为脚本。收款方在脚本上匹配模板。目前，收款方只接受两种模板：直接支付和比特币地址。未来的版本可以为更多的交易类型提供更多的模板，运行那个版本或更高版本的节点就能接收这些交易类型。网络中所有版本的节点都可以验证并且处理任何新交易，然后移至区块里，即使它们可能不知道如何读取这些新交易类型。\r\n\r\n    这个设计支持我多年前设计的各种可能的交易类型，包括托管交易、担保交易、第三方仲裁、多方签名等。如果比特币的发展规模够大，这些就是未来我们想要探索的，但它们都必须在一开始就设计才能确保未来成为可能。\r\n\r\n2012年，加文沿着这一思路提出了P2SH。\r\n\r\nP2PKH是支付到一个“公钥”，P2SH就是支付到一个“脚本”。脚本内可以设定灵活的条件，控制一笔比特币的支出，这个条件脚本可以是多人签名、到期时间等等各种各样的设定。\r\n\r\n在UTXO中的，pkscript定义了花费的条件，它是一个固定长度的hash值，在未花费之前，具体条件详情是不公开的未知的，直到这表UTXO被花费。\r\n\r\n所以，P2SH的诞生，是为了支持各种各样的交易类型，扩展了比特币交易的使用范围。\r\n\r\n# \r\n# **P2SH-多人签名**\r\n# \r\n\r\n我们从比特币主网上挑出一个P2SH交易做分析，了解P2SH地址及相关的交易验证信息。\r\n\r\n可以使用比特币浏览器：\r\n\r\nhttps://www.blockchain.com/\r\n\r\n定位到交易ID：\r\n\r\nf080d24044863e4dced8aeaf4c4ab0120d6742a3ed58ec61297539d9fd1e0981\r\n\r\n该交易有一笔输出，地址为3开头，是一个P2SH地址：\r\n\r\n\r\n```\r\n{\r\n    \"address\": \"32uYXZ9v65EYrpGBYHSHYdbopCeKxhYCLR\",    \r\n    \"pkscript\": \"a9140d56a9f96955bb0300138fef075d4046a9961c9987\",    \r\n    \"value\": 33240000,    \r\n    \"spent\": true,    \r\n    \"spender\": {      \r\n        \"txid\": \"7122c33a37603a27ea155b0dab742f4e2bdfb6a520b33b5c7cd5abb81419810d\",      \r\n        \"input\": 0    \r\n    }\r\n}\r\n```\r\n\r\n分析下pkscript字段，解析如下：\r\n\r\n[169, '0d56a9f96955bb0300138fef075d4046a9961c99', 135]\r\n\r\n其中**169**是OP_HASH160，**135**是OP_EQUAL，所以pkscript是固定的模板格式：\r\n\r\n**<OP_HASH160>** 0d56a9f96955bb0300138fef075d4046a9961c99 **<OP_EQUAL>**\r\n\r\n中间的20字节，是赎回脚本的哈希。此时还无法知道赎回条件是什么。花费这笔UTXO的时候，需要提供赎回脚本。赎回脚本进行哈希计算，与这里的20字节对比，相同则赎回脚本验证通过。\r\n\r\n现在我们分析花费此UTXO的下笔交易：\r\n\r\n7122c33a37603a27ea155b0dab742f4e2bdfb6a520b33b5c7cd5abb81419810d\r\n\r\n其中一笔输入：\r\n\r\n```\r\n{     \r\n    \"coinbase\": false,     \r\n    \"txid\": \"f080d24044863e4dced8aeaf4c4ab0120d6742a3ed58ec61297539d9fd1e0981\",     \r\n    \"output\": 1,      \"sigscript\": \"00483045022100d83f4331bb184a442409c990fa1b05a373e0ae926f3fca7d0a4e0a0ac7af9a49022007cc484da7b9921ac75baef8ae1255e030f70ea2c634ae48fbbedf8f59a45c9801483045022100bf5d7c7c31235ee18792e51dabc816f30b7edc4220139d5f70a685f4f874303702207325400915c4d8c9bdf6634efe49fe48eaaa7dc3e5edd90f4282f94a309d50ae014c695221027936091e40fd128a0df56eb8195adfc820d7e5ed6b2b129357b6669b47c48ab12103df4d641f1907c7f9c317cbd2d648a1cab3908f58c2eb7f904b4cba6839303d4b210325604dfd90bf472307725a1eabb973de8849e8cdbae6b59fc7cea0b7d1fe6b1153ae\",     \r\n    \"sequence\": 4294967295,     \r\n    \"pkscript\": \"a9140d56a9f96955bb0300138fef075d4046a9961c9987\",     \r\n    \"value\": 33240000,     \r\n    \"address\": \"32uYXZ9v65EYrpGBYHSHYdbopCeKxhYCLR\",     \r\n    \"witness\": []\r\n}\r\n```\r\n\r\n其中sigscript字段，我们解析出来就是P2SH中的赎回脚本含义：\r\n\r\n\r\n```\r\n00483045022100d83f4331bb184a442409c990fa1b05a373e0ae926f3fca7d0a4e0a0ac7af9a49022007cc484da7b9921ac75baef8ae1255e030f70ea2c634ae48fbbedf8f59a45c9801483045022100bf5d7c7c31235ee18792e51dabc816f30b7edc4220139d5f70a685f4f874303702207325400915c4d8c9bdf6634efe49fe48eaaa7dc3e5edd90f4282f94a309d50ae014c695221027936091e40fd128a0df56eb8195adfc820d7e5ed6b2b129357b6669b47c48ab12103df4d641f1907c7f9c317cbd2d648a1cab3908f58c2eb7f904b4cba6839303d4b210325604dfd90bf472307725a1eabb973de8849e8cdbae6b59fc7cea0b7d1fe6b1153ae\r\n```\r\n\r\n解析后：\r\n\r\n[**0**, '3045022100d83f4331bb184a442409c990fa1b05a373e0ae926f3fca7d0a4e0a0ac7af9a49022007cc484da7b9921ac75baef8ae1255e030f70ea2c634ae48fbbedf8f59a45c9801', '3045022100bf5d7c7c31235ee18792e51dabc816f30b7edc4220139d5f70a685f4f874303702207325400915c4d8c9bdf6634efe49fe48eaaa7dc3e5edd90f4282f94a309d50ae01', **76, 105, 82**, '027936091e40fd128a0df56eb8195adfc820d7e5ed6b2b129357b6669b47c48ab1', '03df4d641f1907c7f9c317cbd2d648a1cab3908f58c2eb7f904b4cba6839303d4b', '0325604dfd90bf472307725a1eabb973de8849e8cdbae6b59fc7cea0b7d1fe6b11', **83, 174**]\r\n\r\n把数字替换为对应的操作码：\r\n\r\n[**OP_0**, '3045022100d83f4331bb184a442409c990fa1b05a373e0ae926f3fca7d0a4e0a0ac7af9a49022007cc484da7b9921ac75baef8ae1255e030f70ea2c634ae48fbbedf8f59a45c9801', '3045022100bf5d7c7c31235ee18792e51dabc816f30b7edc4220139d5f70a685f4f874303702207325400915c4d8c9bdf6634efe49fe48eaaa7dc3e5edd90f4282f94a309d50ae01', **OP_PUSHDATA1, OP_VERIFY, OP_2**, '027936091e40fd128a0df56eb8195adfc820d7e5ed6b2b129357b6669b47c48ab1', '03df4d641f1907c7f9c317cbd2d648a1cab3908f58c2eb7f904b4cba6839303d4b', '0325604dfd90bf472307725a1eabb973de8849e8cdbae6b59fc7cea0b7d1fe6b11', **OP_3, OP_CHECKMULTISIG**]\r\n\r\n所以这应该是一笔2-of-3多签交易。例子中用到的操作码及编号如下表，请参考：\r\n\r\n|                  |         |                      |\r\n| ---------------- | ------- | -------------------- |\r\n| **操作码**          | **编号 ** | **描述**               |\r\n| OP_HASH160       | 169     | 两次哈希SHA256和RIPEMD160 |\r\n| OP_EQUAL         | 135     | 相等判断，相等为1，否则为0       |\r\n| OP_0             | 0       | 空压入堆栈，为了兼容性          |\r\n| OP_PUSHDATA1     | 76      | 下一个压入堆栈的字节数          |\r\n| OP_VERIFY        | 105     | 判断栈顶是否为真             |\r\n| OP_2             | 82      | 2压入堆栈                |\r\n| OP_3             | 83      | 3压入堆栈                |\r\n| OP_CHECKMULTISIG | 174     | 多签验证                 |\r\n\r\n通过上面的例子可以清晰看到，P2SH比P2PKH增强了交易功能，可以让交易满足更多的应用场景。\r\n\r\n# \r\n# **尾声**\r\n# \r\n\r\n当下，P2PKH和P2SH的应用越来越少了，取而代之的是下篇文章要讲的隔离见证。我们看个P2SH的一个截图：\r\n</br>\r\n![image.png](https://img.learnblockchain.cn/attachments/2025/01/IXhbjxKS678b609abb5c4.png)\r\n</br>\r\nsigscript字段特别长。如果某个交易有多个P2SH交易类型的输入，那交易数据的字节数将更大，交易费也更昂贵。比特币区块链每个区块的容量很有限，为了解决这一问题，隔离见证方案在2017年落地实施。这就是比特币支付地址的下一代演变-Bench32。"},"author":{"user":"https://learnblockchain.cn/people/25283","address":null},"history":"bafkreiawx76vt7xroe2tnip5i6bvnmy7jai22yrf6cuhastxv22nh7rdai","timestamp":1737187608,"version":1}