媒体争相报道的比特币所具有的去中心化、不可篡改、不可伪造的特性是指什么?它们背后所需要的技术栈是什么?另外,上一篇文章中介绍了比特币的运转,支撑这些运转流程的背后技术又是那些呢?在本文中,我们展开叙述。
01 去中心化
中心化是指,我们需要一个像银行一样中心机构来验证交易。去中心化,本质上是让所有的交易节点都具有验证交易真伪的能力。在比特币交易中,我们用到非对称交易俩验证交易的真伪。非对称加密是一种加密和解密的时候使用不同秘钥的加密算法。对于,非对称加密,简单地说就是:公钥和私钥在非对称加密机制里是成对存在,公钥和私钥可以相互去验证对方。在比特币的世界里,地址可以理解为公钥,签名、输入密码的过程理解为私钥的签名。每一笔交易,旷工都可以通过验证公钥和私钥是否匹配,来验证这笔交易是否合法。
地址与私钥
私钥经过一序列运算(两次hash)之后,可以得到地址,但是地址无法反推得到私钥。
地址: 2A39CBa2390FDe
私钥: sdgHsdniNIhdsgaKIhkgnakgaihNKHIskdgal
Hash(Hash(fun(sdgHsdniNIhdsgaKIhkgnakgaihNKHIskdgal))) -> 2A39CBa2390FDe
所以,正如上文所描述的,在比特币的网络中,每一个人只要保护好自己的私钥;这样,在知道自己的比特币地址和对方的比特币地址的情况下,就可以在没有一个中心机构的情况下进行安全的转账和交易操作。例如之前交易的例子:
{
"付款地址":"2A39CBa2390FDe",
"收款地址":"AAC9CBa239aFcc",
"金额":"0.2btc"
}
在只有拥有地址2A39CBa2390FDe的私钥的情况下,才能进行支付。
非对称加密技术使用
在非对称加密技术中,我们怎么证明你拥有这个付款地址的私钥,可以完成这次交易呢?
交易信息签名
实际在签名之前,会先对交易信息进行Hash运算的到摘要信息,然后对摘要信息进行签名。过程大概是这样:
1.对交易进行hash, 得到一个摘要信息(Hash值)
hash('{"付款地址":"2A39CBa2390FDe",
"收款地址":"AAC9CBa239aFcc",
"金额":"0.2btc"}') -> 8aDB23CDEA6
2.用私钥对交易摘要进行签名(付款方在安全的环境下进行,以避免私钥泄密), 用代码表示大概是这样。
#参数1为交易摘要
#参数2为私钥
#返回签名信息
sign("8aDB23CDEA6", "J78sknJhidhLIqdngalket") -> "3cdferdadgadg"
广播
在签名运算之后,付款节点就开始在全网进行广播:我支付了0.2btc到AAC9CBa239aFcc,签名信息是3cdferdadgadg,你们来确认一下吧。
广播过程实际上是发信息到相连的其它节点,其它节点在验证通过后再转发到与之相连的节点,这样的扩散过程。
广播的信息包含了交易原始信息和签名信息。
验证
其它节点在收到广播信息之后,会验证签名信息是不是付款方用私钥对交易原始信息签名产生的,如果验证通过说明确实是付款方本人发出的交易,说明交易有效,才会记录到账本中去。
验证过程实际是签名过程的逆运算,用代码表示大概过程是这样的:
#参数1为签名信息
#参数2为付款方地址
#返回交易摘要
verify("3cdferdadgadg", "2A39CBa2390FDe") -> "8aDB23CDEA6"
如果验证输出的信息和原始交易信息的hash一致,则验证通过,记录账本,用代码表示大概是这样:
if(verify("3cdferdadgadg", "2A39CBa2390FDe")
== hash('{"付款地址":"2A39CBa2390FDe",
"收款地址":"AAC9CBa239aFcc",
"金额":"0.2btc"}')) :
# 写入账本
# 广播
else:
# donothing
大家可以理解为付款地址为公钥,签名过程即为用私钥对交易摘要的加密过程,验证过程为用公钥解密的过程(为方便大家理解,严格来讲是不准确的)。
比特币系统使用了椭圆曲线签名算法,算法的私钥由32个字节随机数组成,通过私钥可以计算出公钥,公钥经过一序列哈希算法和编码算法得到比特币地址,地址也可以理解为公钥的摘要。
这里,对于去中心化,我们只是介绍了下非对称加密技术所体现的作用。其实在去中心化特性中,分布式存储也发挥了非常重要的作用。
这里,技术先不深究,我们理清楚这个关系之后,后面再做深入的探索和研究。
02 不可篡改
篡改是指在网络中为了某种利益,对比特币网络中的账本进行恶意修改。比特币中不可篡改特性,由工作量证明机制和最长链机制来保障。
工作量证明机制(PoW)从笼统上讲,就是一种在差不多时间内发生的食物的先后顺序达成某种共识的一种算法。工作量证明,简单理解就是这一份证明,用来确认你做过一定量的工作。它是一种通过工作的结果进行验证的一种工作量验证方式。这种方式非常高效。在现实的世界里,就好比我们经过了四年的努力学习、艰难地通过考试,最后也是通过一纸文凭(学位证书)来证明我们的知识水平和学习能力。
在比特币网络中,PoW是通过计算猜测一个数值(nonce),使得拼凑上交易数据后内容的hash值满足规定的上限。由于hash难题在目前的计算模式下需要大量的计算,这就保证在一段时间内系统中只能出现少数合法的提案。反过来,能够提出合法提案,也证明提案者确实付出了一定的工作量。
这些少数的提案者会在网络中记性广播,收到的用户进行验证之后,会在用户认为的最长链的基础上继续难题的计算。因此,系统中可能出现分叉(fork),但是最终会有一条链成为最长链。
前面讲到的hash难题,因为具有不可逆的特点。目前,除了暴力计算外,还没有有效的算法进行解决。所以,用户如果获得了符合要求的nonce,说明在概率上付出了对应的算力。这里,谁的算力多,谁最先解决问题的概率就越大。当掌握了超过全网一半的算力的时候,从概率上就能控制网络中链的走向。这也是所谓的51%攻击的由来。
参与PoW计算比赛的人,将付出的成本包括:硬件、电力、维护等。当首个算出nonce值得“幸运儿”诞生之后,这些成本就将会被沉没掉。所以,恶意尝试破坏或者篡改,需要付出巨大的经济成本。
举一个直观的例子。像上图中所示,如果一个买票窗口只有一个的情况下,需要在窗口的前面排一支队伍。因为有些人不守规矩,可能就会出现有人插队的情况。票务管理员会检查队伍,认为最长的的一条队伍是最长的,并让不合法的分叉队伍重新排队。那么,新来的人,看到场面后,在足够理智的情况下,会选择最长的队伍进行排队。 这种情况下,从博弈的角度看,是在看到有多条链的参与者往往认为目前越长的链具备越大的胜出可能性,从而更加倾向于选择长的链。
03 不可伪造
不可伪造的定义就是不能造假币、不能重复使用比特币。和我们实际中使用货币的场景来看,就对应为:我们购买了1元钱东西之后,支付的1元的钱币是真币;另外,我们不能用同一张1元纸币,在购买了价值1元的鸡蛋之后,再用来购买价值1元的方便面,也就是不可以重复支付。
比特币是通过未经使用的交易的输出(Unspent Transaction Outputs, UTXO)结构来保证的。它是比特币交易生成及验证的一个核心概念。我们先从实际货币的使用过程来熟悉和理解这个概念:举个例子,打个比方我支付购买苹果的20元钱,其中2张5元的来自是饮料店老板给的找零,1张10元是超市给的找零。拿到找零的这3张纸币之后,需要我还没有用出去,才可以支付给买苹果的老板。这样,这种情况才叫做未花费的交易输出。而我们手上的这些钞票也可能来自其他人,如果之前的脑纪委老板有足够好的记忆能力的话,那么我们就可以顺藤摸瓜一直追溯到对应货币的发行的时刻。由此,可以验证这张钞票的真实性。
在比特币网络中,区块链网络提供的账本并非用于记录每个账户的余额,而是用来记录发生过的交易的历史信息。也就是说,每一次交易,用户需要将新的交易信息写到比特币区块链网络中,等网络确认后即可认为交易完成。每个交易包括了输入和输出。UTXO即可作为下一个新的交易的输入。相应的,被使用过的交易的输出(Spent Transaction Outputs, STO)则是无法被引用作为合法输入。所以,在比特币网络中,一笔合法的交易,即引用某些已存在的交易的UTXO作为交易的输入,并生成新的输出的过程。
为了更加形象地理解UTXO,我们通过一个实际的场景再来讲述一下:
如上图中所示:场景是Alle挖到10枚比特币;之后,用两枚购买了baby手上的一只羊;过了几天,Alle和baby合资两个比特币,购买了carry的一块地。如果从账面上看,他们三个人账户上的信息的变换如上图中所示。
我们通过上面的图,只能看到三个账户余额信息的变化,中间交易的信息我们不得而知。在比特币网络中,我们并不是这样简单的记录这几个账户信息的,而是通过如下图所示的UTXO结构。
综合以上,做个小结:
比特币的区块链账本里记录的是一笔又一笔的交易,并不是简单的账户的余额。
每笔交易都有若干交易输入,也就是资金来源,也都有若干笔交易输出,也就是资金去向。一般来说,每一笔交易都要花费(spend)一笔输入,产生一笔输出,而其所产生的输出,就是“未花费过的交易输出”,也就是 UTXO。
比特币交易遵守几个规则:
第一,除了 coinbase 交易之外,所有的资金来源都必须来自前面某一个或者几个交易的 UTXO,就像接水管一样,一个接一个,此出彼入,此入彼出,生生不息,钱就在交易之间流动起来了。
第二,任何一笔交易的交易输入总量必须等于交易输出总量,等式两边必须配平。