术语表 /地址与密钥
P2SH 地址
又称 Pay-to-Script-Hash、P2SH 输出、脚本哈希支付地址。
- P2SH 地址是什么?
- P2SH 地址以3开头,并承诺一个赎回脚本的哈希值,因此在有人公开该脚本之前,花费条件一直保持保密。
规定于 BIP-16。
Pay to script hash 随 BIP-16出现,自2012年4月1日的区块173,805起强制执行,它改变了由谁来承担复杂性成本。在此之前,发送方必须把整个合约写进输出。在此之后,发送方只需写入23字节,接收方在日后公开脚本时再支付相应成本,因此一个3开头的地址既可以隐藏五密钥保险库,也可以只是普通的单密钥钱包。
运作方式
所有 P2SH 地址的输出脚本都简短且完全相同:OP_HASH160 后接一个20字节的哈希值和 OP_EQUAL,共23字节。该哈希值承诺的是只有接收方知道的赎回脚本。
花费分两步进行。scriptSig 提供赎回脚本所需的参数,随后以序列化的赎回脚本本身作为最后一项。节点对最后一项计算哈希,与所承诺的值比对,若两者一致,就反序列化该脚本,并用栈中剩余的全部内容运行它。两个阶段都必须成功。
有两项限制决定了能放进什么内容。赎回脚本是单个栈元素,因此不能超过 Bitcoin Core 定义为 MAX_SCRIPT_ELEMENT_SIZE 的520字节入栈上限。中继策略还增加了第二道上限:每个 P2SH 输入最多15次签名操作。两者合在一起,使可用的配置远低于脚本语言一般情况下所允许的范围,后者的上限是10,000字节的脚本。
地址本身采用 Base58Check 编码,版本字节为0x05,由此产生开头的3和长度为34个字符的字符串。该格式由 BIP-13定义,与 BIP-16中的共识规则相互独立。
在哪里会遇到它
交易所的提币表单若把某个选项描述为"SegWit"而没有写明"native",通常指的是3开头的地址。2018年之前构建的多重签名保险库使用这类地址。需要脚本、又希望使用普通钱包也能付款的地址的原子交换和哈希时间锁合约,同样使用它们。
这种设计的后果是模糊性,而且是完全的模糊性。未花费的3输出只显示一个哈希值,因此区块浏览器无法告诉您它装的是一个被封装的单密钥,还是一个企业的签名阈值方案,发送方同样无从得知。这些信息只会在花费交易中出现。
这种模糊性带来了真实的丢失风险。从 P2SH 输出中找回比特币,需要的是赎回脚本,而不仅仅是私钥。仅凭助记词无法重建任意脚本,因此任何比标准钱包派生更复杂的 P2SH 配置,都必须以描述符或脚本字节本身的形式备份。曾有人在持有全部密钥却没有脚本的情况下丢失了比特币。
P2SH 地址 vs P2SH 多重签名
P2SH 多重签名只是可以放进 P2SH 地址的一种内容,并不是该格式的同义词。地址是一个容器,藏在其中的赎回脚本可能是 m-of-n 多重签名、嵌套的 SegWit 密钥哈希、带时间锁的恢复条款,或是从未有人写过的脚本。把3开头的地址当作"a multisig address"只是一种猜测,而且经常出错,因为在2017年之后的几年里,封装 SegWit 使3成为默认的单密钥格式,使数百万个普通钱包停留在这一前缀之后。