历史遗留地址P2PKH

为要支付的人输入IP地址有很多优点,但也有很多缺点。一个特别的缺点是接收者需要他们的钱包在线并在其IP地址上可访问。对于很多人来说,这不是一个选择。他们晚上关闭计算机,他们的笔记本电脑进入睡眠模式,他们处于防火墙后面,或者他们正在使用网络地址转换(NAT)。

这让我们回到了接收者(如Bob)不得不向发送者(如Alice)提供一个较长的公钥的问题。早期比特币开发者所知的最短版本的比特币公钥是65字节,用十六进制表示时相当于130个字符。然而,比特币已经包含了几个比65字节大得多的数据结构,需要在比特币的其他部分中以最少的数据安全地引用。

比特币通过哈希函数实现了这一点,哈希函数是一种将潜在大量数据混淆(哈希)并输出固定量数据的函数。当给定相同的输入时,加密哈希函数总是产生相同的输出,并且安全函数还会使得别人很难选择不同的输入以产生先前看到的输出。这使得输出成为对输入的承诺。实际上,这是一种承诺,只有输入x会产生输出X。

例如,假设我想问你一个问题,并且以一种你无法立即阅读的形式给出我的答案。假设问题是,“中本聪什么时候开始研发比特币?”我会以SHA256哈希函数的输出形式给你我的答案的承诺,这是比特币中最常用的函数:

94d7a772612c8f2f2ec609d41f5bd3d04a5aa1dfe3582f04af517d396a302e4e

稍后,当你告诉我你对问题答案的猜测后,我可以揭示我的答案,并向你证明我的答案作为哈希函数的输入产生了与我之前给你的完全相同的输出:

$ echo "2007. He said about a year and a half before Oct 2008" | sha256sum 94d7a772612c8f2f2ec609d41f5bd3d04a5aa1dfe3582f04af517d396a302e4e

现在想象一下,我们向 Bob 提出问题:“你的公钥是什么?” Bob 可以使用哈希函数为他的公钥提供一个具有密码学安全性的承诺。如果他后来透露了他的密钥,而我们验证它产生了与他先前给我们的完全相同的承诺,那么我们可以确定它是用于创建早期承诺的确切相同的密钥。

SHA256 哈希函数被认为非常安全,并产生 256 位(32 字节)的输出,不到原始比特币公钥大小的一半。然而,还有其他略微不太安全的哈希函数可以产生较小的输出,比如 RIPEMD-160 哈希函数,其输出为 160 位(20 字节)。由于 Satoshi Nakamoto 从未说明原因,比特币的原始版本通过首先使用 SHA256 对密钥进行哈希,然后使用 RIPEMD-160 对该输出进行哈希,从而对公钥进行承诺;这产生了对公钥的 20 字节承诺。

我们可以从算法的角度来看。从公钥 K 开始,我们计算 SHA256 哈希,然后计算结果的 RIPEMD-160 哈希,得到一个 160 位(20 字节)的数字:

A = RIPEMD160(SHA256(K))

现在我们知道如何对公钥做出承诺了,接下来我们需要弄清楚如何在交易中使用它。考虑以下输出脚本:

OP_DUP OP_HASH160 <Bob's commitment> OP_EQUAL OP_CHECKSIG

以及以下输入脚本:

<Bob's signature> <Bob's public key>

它们组合在一起形成以下脚本:

OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG

正如我们在“IP地址:比特币的原始地址(P2PK)”上一页所做的那样,我们开始将项目放在堆栈上。 首先放入Bob的签名,然后放入他的公钥。 OP_DUP操作复制顶部项目,因此堆栈顶部和次顶部现在都是Bob的公钥。 OP_HASH160操作消耗(删除)顶部公钥,并用RIPEMD160(SHA256(K))对其进行哈希处理,因此现在堆栈顶部是Bob的公钥的哈希。 接下来,将Bob的公钥的承诺添加到堆栈的顶部。 OP_EQUALVERIFY操作消耗了顶部两个项目,并验证它们是否相等; 如果Bob在输入脚本中提供的公钥与Alice支付中用于创建承诺的公钥相同,那么情况应该是如此。 如果OP_EQUALVERIFY失败,则整个脚本失败。 最后,我们得到的是一个仅包含Bob的签名和他的公钥的堆栈; OP_CHECKSIG操作码验证它们是否相互对应,并且签名是否承诺了交易。

虽然这种支付给公钥哈希(P2PKH)的过程可能看起来有些复杂,但它允许Alice的付款只包含对他的公钥的20字节承诺,而不是公钥本身,在比特币的原始版本中会是65字节。 这使得Bob不必与Alice交流太多的数据。

但是,我们还没有讨论Bob如何从他的比特币钱包将这20个字节传递给Alice的钱包。 字节值有常用的编码,例如十六进制,但如果在复制承诺时出现任何错误,将导致比特币被发送到不可支配的输出,从而永远丢失。 在下一节中,我们将介绍紧凑编码和可靠的校验和。

Last updated