购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

4.4
支付到公钥哈希的传统地址

直接输入想要付款对象的IP地址虽然有一些优势,但也存在多个不足。一个特大的缺点是,接收者需要保持他们的钱包在线并且IP地址是可从外界访问的。实际上,这对于很多人来说并不可行。他们晚上会关闭计算机,笔记本计算机会休眠,他们的网络可能被防火墙保护,或者他们使用的是内部网络地址转换(Network Address Translation,NAT,没有独立的公网IP)。

这就引发了一个问题,像Bob这样的接收者需要给像Alice这样的支付者提供一个很长的公钥。早期的比特币开发者制定的比特币公钥最短版本是65字节,以十六进制写出来等于130个字符。然而,比特币中已经包含了很多远大于65字节的数据结构,因安全原因而这些数据需要在比特币的其他部分中被引用,因此需要引用的数据要尽可能小,同时又能保证安全性。

比特币使用哈希函数实现了这一点,哈希函数可以接收大量数据,对其进行加密(哈希处理),然后输出固定长度的数据。对于加密哈希函数,当给定相同的输入时,它总是会产生相同的输出,而安全函数则使得人们无法选择其他输入来得到之前见过的输出。这使得输出成为对输入的承诺。实际上,哈希函数是一个保证,只有输入 x 才会产生输出 X

例如,想象一下,我想问你一个问题,并给你我的答案,但不是以你能够立即阅读的形式。比如问题是:“中本聪是从哪一年开始研究比特币的?”我会用比特币中最常用的SHA256哈希函数输出形式,对我的答案进行承诺:

然后,当你告诉我你对这个问题的猜测之后,我可以公布我的答案,并且向你证明,我的答案作为哈希函数的输入,会产生一个与我早先给你的输出完全相同的结果:

现在假设我们询问Bob一个问题:“你的公钥是什么?”Bob可以使用一个哈希函数给我们一个对他公钥的加密安全承诺。如果他后来透露了他的密钥,并且我们验证它产生了与他之前给出的承诺相同的结果,那么我们可以确定它是用于创建先前承诺的完全相同的公钥。

SHA256哈希函数被认为非常安全,并能产生256位(32字节)的输出,这不到比特币原始公钥大小的一半。然而,也有其他安全性稍差的哈希函数可以产生更小的输出,例如RIPEMD-160哈希函数,其输出为160位(20字节)。由于中本聪从未说明的原因,比特币原始的版本首先通过使用SHA256对公钥进行哈希,然后再将该输出用RIPEMD-160进行哈希,这就产生了一个20字节的公钥承诺。

我们可以从算法角度来分析这个过程。首先,我们对公钥 K 进行SHA256哈希计算,然后对该结果进行RIPEMD-160哈希计算,产生一个160位(20字节)的数字:

A = RIPEMD 160 SHA 256 K

在这里, K 是公钥,而 A 是生成的承诺。

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

此外,我们还需要以下输入脚本:

它们一起构成了以下脚本:

正如我们在4.3节中所做的,我们开始往栈中放置条目。首先将Bob的签名放到栈顶,然后将他的公钥放置到签名上。OP_DUP操作复制栈顶的条目,因此栈中最顶端的两个条目现在都是Bob的公钥。OP_HASH160操作消耗(移除)栈顶的公钥,并将其用RIPEMD160(SHA256(K))哈希的结果替换,这样栈顶现在是Bob公钥的哈希值。接下来,将Bob公钥的承诺添加到栈顶。OP_EQUALVERIFY操作消耗掉栈顶的两个条目,并验证它们是否相等。如果Bob在输入脚本中提供的公钥与Alice支付给输出脚本中创建承诺的公钥相同,那么这两者应当是匹配的。如果OP_EQUALVERIFY失败,整个脚本就会失败。最后,我们的栈中只剩下Bob的签名和他的公钥。OP_CHECKSIG操作码验证它们是否相互对应,并且签名是对交易的承诺。

尽管将付款支付到公钥哈希(Pay to Public Key Hash,P2PKH)的这一过程看起来可能很复杂,但它允许Alice对Bob的支付只包含对他公钥的20字节承诺,而不是65字节长度的公钥本身,后者在比特币的原始版本中是必需的。这大大减少了Bob需要传递给Alice的数据量。

然而,我们还没有讨论Bob如何从他的比特币钱包向Alice的钱包发送这20字节的信息。我们通常使用十六进制等编码来表示字节值,但是在复制承诺时的任何错误都会导致比特币被发送到一个无法使用的输出,从而导致比特币永远丢失。接下来我们将探讨紧凑编码和可靠的校验码。 swdh+61mUf1vp8FYLrfVEvU/ncuttow22m4RYMSix84glFzSx26xTVN6r8dDvfg1

点击中间区域
呼出菜单
上一章
目录
下一章
×

打开