为了便于理解,我们可以把比特币区块链上的资产交易比喻成 将资产锁进保险箱,只有持有保险箱钥匙的人(即收款人)才能拿出保险箱中的资产进行交易。举个例子,如果 Alice 要向 Bob 支付一笔资产,Alice 将这笔资产锁进一个保险箱中,只有 Bob 才有这个保险箱的钥匙,即只有Bob才能取出这笔资产。如果 Bob 要取出资产,那么要求 Bob 必须同时花掉这笔资产(即锁入另一个保险箱)。在 Bob 没有取出资产前,资产并不真正属于 Bob。设想如果 Bob 丢了钥匙,那么将无法再取出资产。 换句话说,这笔资产还在保险箱中保存的时候,既不属于Alice,也不完全属于Bob。当然,Alice 也可以把资产放入任何人都可以打开的保险箱中,这也被称之为 Anyone-Can-Spend 交易。
zer0to0ne 接着向我们详细解释了两个重要概念 P2PKH(Pay to Public Key Hash) 与 P2SH (Pay to Script Hash)的来龙去脉。这两个名词分别代表了两种不同的比特币交易类型。
下面是 zer0to0ne 的精彩技术细节分析
P2PKH——中本聪的伟大发明
Pay to Public Key Hash 顾名思义,是将比特币放入一个保险箱,钥匙孔为公钥 Hash(Public Key Hash)。我们最常见到的 1-地址 本质上就是 Public Key Hash 的一种编码。1-地址 的生成过程也很简单,将公钥经过Hash160运算得到 Public Key Hash,在 Public Key Hash 头部补上前缀 0x00,Hash 尾部补上校验和,经过Base58便得到了1开头的比特币地址。
再解释一遍:当 Bob 要花费 Alice 给他的比特币时,Bob 只有用正确的钥匙才能打开 Alice 留给他的保险箱,把钱放入 Bob 新构造的一个保险箱里。
这时候一些聪明的读者会注意到一个细节:如果 Bob 取出钥匙,在还未打开保险箱的时刻,区块链上的任何矿工都能看得见这把钥匙的形状,理论上他们是可以立即复制一把钥匙,把 Alice 留给 Bob 的保险箱打开并花掉(俗称 Front-running 攻击)。真的可以这样做吗?显然中本聪考虑了这个问题,这把钥匙中的交易签名是 Bob 发起的交易的完整签名。假设 Bob 要将 Alice 构造的保险箱中的比特币 装入一个新的保险箱(留给Charlie),这时候 Bob 出示的钥匙包含了 Charlie 的公钥Hash,矿工虽然可以复制 Bob 的钥匙,但是这把钥匙已经隐藏了下一个新保险箱的关键信息,因此矿工无法使用这个复制钥匙来完成别的动作(无法挪用数字签名)。
我们继续通过保险箱的例子来解释,并给这类保险箱起名为 3-类保险箱。现在 Alice 给 Bob 的比特币锁定在一个由上述 Hash160保护的保险箱里,我们姑且称之为哈希锁吧。
这把锁依然需要正确的形状才能开启,但是安全性却弱很多,缺少数字签名机制导致钥匙隐藏的关键信息不会随着Bob 新建的保险箱而变化。任何矿工都能在 Bob 亮出钥匙的一瞬间复制出一摸一样的钥匙,抢着去开Alice留给Bob的保险箱(Front-running),将币转给另一个人 Eve,于是原本属于 Bob 的比特币会被洗劫一空。
这个问题可以解释为:Alice 按照 Bob 的要求制作了一个 3-类保险箱,但是这个保险箱是被 pywallet 错误修改的,实际上 Bob 的本意是需要一个 1-类保险箱 ,因为 Bob 手里只有一个1-类保险箱 的钥匙。
当 Bob 请求 Alice 把比特币锁定到 3-类保险箱 时,这个保险箱就需要同时校验钥匙形状和钥匙芯片内容了,但是 Bob 的1-类保险箱 的钥匙形状是 Public Key 决定的,在保险箱误变为 3-类保险箱 后,钥匙形状校验却没有改变,也没有相应的钥匙芯片内容。
Bob 尝试在钥匙芯片中写入Public Key,使得钥匙形状和锁匹配,但是芯片中的Public Key 却无法被保险箱正确执行,所以 Bob 可能再也无法将他的比特币从保险箱中解锁了。
SegWit——全新时代来临
比特币开核心发者 Eric Lombrozo, Johnson Lau, Pieter Wuille 提出来了一种全新的概念,隔离见证(Segregated Witness,简称SegWit)。这是一种有效缓解比特币区块拥堵的技术,并且彻底解决了交易延展性问题(Transaction Malleability)。