2 区块链技术发展史
2.1 区块链之前的技术发展
1976年以前,所有的加密方法都是同一种模式[2]:
(1)发送者选择某一种加密规则,对信息进行加密;
(2)接收者使用同一种规则,和相同的秘钥,对信息进行解密。
由于加密和解密使用同样规则,相同的秘钥,这种方法被称为对称加密算法。
1976年,两位美国计算机学家 Whitfield Diffie和Martin Hellman提出了一种崭新构思,可以在不直接传递秘钥的情况下,完成解密。这被称为"Diffie-Hellman 秘钥交换算法"。这个算法启发了其他科学家。人们认识到,加密和解密可以使用不同的规则,只要这两种规则之间存在某种对应关系即可,这样就避免了直接传递秘钥。
这种新的加密模式被称为"非对称加密算法"。
(1)接收方生成两把秘钥(公钥和私钥)。公钥是公开的,任何人都可以获得,私钥则是保密的。
(2)发送方获取接收方的公钥,然后用它对原文进行。
(3)接收方得到密文后,用私钥解密。
如果公钥加密的信息只有私钥解得开,那么只要私钥不泄漏,通信就是安全的。
1977年,三位数学Rivest、Shamir 和 Adleman 设计了 RSA 算法,发表论文"On Digital Signatures and Public-Key Cryptosystems" [3]。RSA 算法可以实现非对称加密。
1979年,拉尔夫·默克尔(Ralph Merkle)提出了哈希/默克尔树的概念[4]。默克尔树或哈希树是一棵树,其中每个叶节点都用一个数据块标记,每个非叶节点都用其子节点的标签的加密哈希标记。哈希树允许对大型数据结构的内容进行有效且安全的验证。
1982年,Lamport 提出拜占廷将军问题"Byzantine generals and transaction commit protocols"[5],研究了共识问题。
1983年,David Chaum发表了eCash电子货币的构想[6]。用户本地计算机上的eCash软件以数字格式存储货币,并由银行加密签名。用户可以在任何接受eCash的商店上花费电子货币,而无需先在供应商处开设帐户或传输信用卡号。公钥数字签名方案确保了安全性。RSA盲签名实现了提款和支出交易之间的不可链接性。
1985年,Koblitz 和 Miller 各自独立提出了著名的椭圆曲线加密(ECC)算法。由于此前发明的 RSA 的算法计算量过大很难实用, ECC 的提出才真正使得非对称加密体系产生了实用的可能。现代密码学的理论和技术基础已经完全确立了。
1990年,David Chaum与Moni Naor一起提出了第一个离线电子现金系统,该系统也基于盲目签名[6]。
1997年,Adam Back[7]发明了Hashcash。Hashcash是一种工作量证明算法,已在许多系统中用作抵抗拒绝服务的技术。Hashcash stamp构成工作量证明,该工作量证明需要发送者提供一定量的计算工作量。接收者(实际上是任何可以公开审核的人)可以有效地验证收到的Hashcash stamp。
1998年,Wei Dai在"anonymous, distributed electronic cash system"[8]中提出B-money。在论文中Dai提出了两种协议。在第一个协议中,建议使用工作量证明功能作为铸钱的手段。在B-Money中,资金是通过向所有参与者广播交易来转移的,所有参与者都保留所有其他账户。如果发生违约,可以在可能的赔偿下订立合同,并由第三方同意担任仲裁员。如果没有达成协议,则当事各方均以有利于其自己的方式广播论据或证据,并且每个参与者都将为其本人决定其赔偿/罚款。在第二种协议中,只有一部分参与者("服务器")保存账户,并进行发布。参与者通过询问服务器来验证交易。参与者还验证货币供应量没有通胀。成为服务器需要一定的保证金,如果服务器被发现不诚实,则会丢失这笔钱。
1998年,Szabo设计了一种去中心化数字货币的机制,称之为"bit gold"[9]。bit gold从未实现过,但被称为"比特币架构的直接前身" [10]。在Szabo的bit gold结构中,参与者将致力于使用计算机功能来解决密码难题。在一个bit gold网络中,已解决的难题将发送到拜占庭容错公共注册中心,并关联到解题者的公钥上。每个难题的解都将成为下一个难题的一部分。从而形成一个增长的财产链。该方法为网络提供了一种验证新铸币并为其打上时间戳的方法。除非大多数参与者同意接受新难题的解,否则将无法启动下一个难题。
1999年,19岁的Shawn Fanning设计了Napster,之后Napster 迅速在大学里窜红。Napster 是第一个被广泛应用的点对点(Peer-to-Peer,P2P)音乐共享服务,它极大地影响了人们,特别是大学生使用互联网的方式。它给点对点文件共享程序,如Kazaa,Limewire 和BearShare--的拓展铺好了路[11]。1999到2001的三年时间内,Napster、EDonkey 2000和BitTorrent 分别先后出现,奠定了P2P 网络计算的基础[12]。
2002年,SHA-256算法的初始版本发布[13]。
这些技术的发展,为区块链的诞生直接打下了基石。它们和比特币区块链的关系如图1所示。
图1 基础技术与比特币区块链的关系
2.2 比特币区块链的产生
2.2.1 标志事件
2008年Satoshi Nakamoto 发表了著名的论文Bitcoin: A Peer-to-Peer Electronic Cash System[14].
2009年1月Satoshi Nakamoto 用第一版比特币软件挖掘出了创始区块,包含着这句:"The Times 03/Jan/2009 Chancellor on brink of second bailout for banks" (2009年1月3日,财政大臣正处于实施第二轮银行紧急援助的边缘)[15]。
2.2.2 区块链结构
2.2.2.1 概述
BitCoin网络中的任意两个用户可在无可信第三方参与的情况下进行P2P交易,并将每笔交易计入总帐中。
区块链技术通过以下方式解决信任问题。
交易被打包成区块,区块"链接"在一起形成区块链;
选取最长链作为主链,全网共识,保证账本一致;
在多数人参与者是诚实的情况下,系统是安全的。
BitCoin采用了去中心化的区块链技术来完成交易记账,与传统的中心化记账方式不同,如图2所示。
图2 基础技术与比特币区块链的关系
2.2.2.2 区块的完整结构
区块链的账本由多个区块组成。每个区块中会包括一些交易信息,如图3所示。
图3 区块链账本的结构
区块是一种记录交易的数据结构。如表5所示,一个完整的区块结构主要由以下几部分构成。
表5 完整的区块结构
字段 名称 字节 说明
Magic NO 魔数 4 常数0xD9B4BEF9
Blocksize 区块大小 4 用字节表示的该字段之后的区块大小
Blockheader 区块头 80 组成区块头的几个字段
Transaction counter 交易计数器 1-9 该区块包含的交易数量,包含coinbase交易
Transactions 交易 不定 记录在区块里的交易信息,使用原生的交易信息格式,并且交易在数据流中的位置必须与Merkle树的叶子节点顺序一致
2.2.2.3 区块头的结构
区块头的结构如表6所示。表中的版本、父区块头哈希值和Merkle根采用的是小端格式编码,即低有效位放在前面;时间戳表示的是自1970年1月1日0时0分0秒以来的秒数[16]。
表6 区块头结构
字段 字节 说明
版本 4 区块版本号,表示本区块遵守的验证规则
父区块头哈希值 32 前一区块的哈希值,使用SHA256(SHA256(父区块头))计算。
Merkle根 32 该区块中交易的Merkle树根的哈希值,同样采用SHA256(SHA256())计算。
时间戳 4 该区块产生的近似时间,精确到秒的UNIX时间戳,必须严格大于前11个区块时间的中值,同时全节点也会拒绝那些超出自己2个小时时间戳的区块。
难度目标 4 该区块工作量证明算法的难度目标,已经使用特定算法编码。
Nonce 4 为了找到满足难度目标所设定的随机数,为了解决32位随机数在算力飞升的情况下不够用的问题,规定时间戳和coinbase交易信息均可更改,以此扩展nonce的位数。
例1:一个区块的区块头数据。
{
"hash":"000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506",
"ver":1,
"prev_block":"000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250",
"mrkl_root":"f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766",
"time":1293623863,
"bits":453281356,
"nonce":274148111
}
2.2.2.4 coinbase交易结构
一个区块第一个交易规定为coinbase交易,即由挖矿产生的比特币奖励。
除了挖矿奖励,"矿工"的激励还有新增账本记账的手续费,在未来比特币总量不增加之后,后者会成为矿工的主要收入。
每个区块的第一个交易叫做coinbase交易,它的结构如下[17]:
字节长度 字段 说明
4 交易版本号 明确这笔交易参照的规则
1-9 输入计数器 包含的交易输入数量
不定 交易输入 一个或多个交易输入
1-9 输出计数器 包含的交易输出数量
不定 交易输出 一个或多个交易输出
4 锁定时间 一个区块号或UNIX时间戳
coinbase的交易输入结构为:
字节长度 字段 说明
32 交易哈希值 固定为全0
4 输出索引 固定为全1
1-9 coinbase脚本长度 coinbase的脚本字节长度
不定 coinbase脚本 coinbase脚本,可以任意填充
4 序列号 固定值0xFFFFFFFF
coinbase的交易输出结构为:
字节长度 字段 说明
8 总量 用聪表示的比特币值
1-9 锁定脚本大小 用字节表示的后面的锁定脚本长度
不定 锁定脚本 一个定义了支付输出所需条件的脚本
例2:一个coinbase交易的数据。
{
"block_hash":"00000000d1145790a8694403d4063f323d499e655c83426834d4ce2f8dd4a2ee",
"block_height":170,
"block_index":0,
"hash":"b1fea52486ce0c62bb442b530a3f0132b826c74e473d1f2c220bfa78111c5082",
"addresses":[
"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc"
],
"total":5000000000,
"fees":0,
"size":134,
"preference":"low",
"confirmed":"2014-11-16T18:53:46.237Z",
"received":"2014-11-16T18:53:46.237Z",
"ver":1,
"double_spend": false,
"vin_sz":1,
"vout_sz":1,
"confirmations":541062,
"confidence":1,
"inputs":[
{
"output_index":-1,
"script":"04ffff001d0102",
"sequence":4294967295,
"script_type":"empty",
"age":170
}
],
"outputs":[
{
"value":5000000000,
"script":"4104d46c4968bde02899d2aa0963367c7a6ce34eec332b32e42e5f3407e052d64ac625da6f0718e7b302140434bd725706957c092db53805b821a85b23a7ac61725bac",
"addresses":[
"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc"
],
"script_type":"pay-to-pubkey"
}
]
}
coinbase交易的原始数据为:
01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0102ffffffff0100f2052a01000000434104d46c4968bde02899d2aa0963367c7a6ce34eec332b32e42e5f3407e052d64ac625da6f0718e7b302140434bd725706957c092db53805b821a85b23a7ac61725bac00000000
首先4个字节表示交易版本号:
json格式ver字段:1
hex格式4个字节数据:01000000
将小端格式数据0x01000000转化为大端格式数据为0x00000001,转化为十进制数值为1。表示coinbase交易的数据格式遵循的格式版本号为1。
其次1个字节表示交易输入的个数:
json格式vin_sz字段:1
hex格式1个字节数据:01
表示coinbase交易输入只有一个。
其次32个字节表示引用的UTXO交易哈希值:
json格式字段:无对应
hex格式32个字节数据:0000000000000000000000000000000000000000000000000000000000000000
32字节全0为固定值。
其次4个字节表示引用的UTXO所对应的输出索引:
json格式output_index字段:-1
hex格式4个字节数据:ffffffff
4个字节全1为固定值。
其次1个字节表示coinbase脚本数据的长度:
json格式字段:无对应
hex格式4个字节数据:07
0x07表示之后的coinbase脚本数据长度为7字节。
其次7个字节表示coinbase脚本:
json格式script字段:04ffff001d0102
hex格式4个字节数据:04ffff001d0102
coinbase脚本数据和普通交易的解锁脚本不同,因为coinbase是创币交易,则coinbase的脚本不需要对其它UTXO进行解锁,故可以填充任意数据。
其次4个字节序列号为固定值0xffffffff:
json格式sequence字段:4294967295
hex格式4个字节数据:ffffffff
十六进制0xffffffff转化为十进制值为4294967295。
其次1个字节表示交易输出的个数:
json格式vout_sz字段:1
hex格式1个字节数据:01
表明该交易有1个交易输出。
其次8个字节表示挖出新比特币的数量,单位为聪:
json格式value字段:5000000000
hex格式8个字节数据:00f2052a01000000
小端格式十六进制值0x00f2052a01000000转化为大端格式十六进制值0x000000012a05f200,之后转化为十进制值为5000000000,表示该交易输出转出比特币的值为50亿聪,表明该区块新挖出50个比特币。
其次1个字节表示锁定脚本的字节长度:
json格式字段:无对应
hex格式8个字节数据:43
表明接下来的锁定脚本字节长度为67个字节,转化为十六进制值为0x43。
其次67个字节表示锁定脚本:
json格式script字段:4104d46c4968bde02899d2aa0963367c7a6ce34eec332b32e42e5f3407e052d64ac625da6f0718e7b302140434bd725706957c092db53805b821a85b23a7ac61725bac
hex格式67个字节数据:4104d46c4968bde02899d2aa0963367c7a6ce34eec332b32e42e5f3407e052d64ac625da6f0718e7b302140434bd725706957c092db53805b821a85b23a7ac61725bac
锁定脚本开头的0x41表示将后面的65个字节压入堆栈。
其次4个字节表示锁定时间:
json格式字段:无对应
hex格式4个字节数据:00000000
锁定时间为0,表示立即执行。
2.2.2.5 普通交易信息结构
普通交易结构为:
字节长度 字段 说明
4 交易版本号 明确这笔交易参照的规则
1-9 输入计数器 包含的交易输入数量
不定 交易输入 一个或多个交易输入
1-9 输出计数器 包含的交易输出数量
不定 交易输出 一个或多个交易输出
4 锁定时间 一个区块号或UNIX时间戳
普通交易输入结构为:
字节长度 字段 说明
32 交易哈希值 指向被花费的UTXO所在的交易的哈希
4 输出索引 被花费的UTXO的索引号,第一个是0
1-9 解锁脚本大小 用字节表示的后面的解锁脚本长度
不定 解锁脚本 满足UTXO解锁脚本条件的脚本
4 序列号 固定值0xFFFFFFFF
普通交易输出结构为:
字节长度 字段 说明
8 总量 用聪表示的比特币值
1-9 锁定脚本大小 用字节表示的后面的锁定脚本长度
不定 锁定脚本 一个定义了支付输出所需条件的脚本
例3:一个普通交易的数据。
注:数据来自https://api.blockcypher.com/v1/btc/main/txs/b1fea52486ce0c62bb442b530a3f0132b826c74e473d1f2c220bfa78111c5082
{
"block_hash":"00000000d1145790a8694403d4063f323d499e655c83426834d4ce2f8dd4a2ee",
"block_height":170,
"block_index":1,
"hash":"f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16",
"addresses":[
"12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S",
"1Q2TWHE3GMdB6BZKafqwxXtWAWgFt5Jvm3"
],
"total":5000000000,
"fees":0,
"size":275,
"preference":"low",
"confirmed":"2009-01-12T03:30:25Z",
"received":"2009-01-12T03:30:25Z",
"ver":1,
"double_spend":false,
"vin_sz":1,
"vout_sz":2,
"confirmations":541034,
"confidence":1,
"inputs":[
{
"prev_hash":"0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9",
"output_index":0,
"script":"47304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901",
"output_value":5000000000,
"sequence":4294967295,
"addresses":[
"12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S"
],
"script_type":"pay-to-pubkey",
"age":9
}
],
"outputs":[
{
"value":1000000000,
"script":"4104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac",
"spent_by":"ea44e97271691990157559d0bdd9959e02790c34db6c006d779e82fa5aee708e",
"addresses":[
"1Q2TWHE3GMdB6BZKafqwxXtWAWgFt5Jvm3"
],
"script_type":"pay-to-pubkey"
},
{
"value":4000000000,
"script":"410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac",
"spent_by":"a16f3ce4dd5deb92d98ef5cf8afeaf0775ebca408f708b2146c4fb42b41e14be",
"addresses":[
"12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S"
],
"script_type":"pay-to-pubkey"
}
]
}
普通交易的原始数据为:
0100000001c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd3704000000004847304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901ffffffff0200ca9a3b00000000434104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac00286bee0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000
首先4个字节表示交易版本号:
json格式ver字段:1
hex格式4个字节数据:01000000
将小端格式数据0x01000000转化为大端格式数据为0x00000001,转化为十进制数值为1。
其次1个字节表示交易输入的数量:
json格式vin_sz字段:1
hex格式1个字节数据:01
其次32个字节表示引用的UTXO交易哈希值:
json格式prev_hash字段:0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9
hex格式32个字节数据:c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd3704
原生数据是小端格式,json格式数据是大端格式。
其次4个字节表示引用的UTXO所对应的输出索引:
json格式output_index字段:0
hex格式4个字节数据:00000000
这说明该交易输入引用的UTXO是交易 0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9 的第一个输出。
其次1个字节表示解锁脚本字节长度:
json格式字段:无对应
hex格式1个字节数据:48
表明接下来的解锁脚本字节长度为72个字节,转化为十六进制值为0x48。
其次72个字节表示解锁脚本:
json格式script字段:47304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901
hex格式72个字节数据:47304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901
解锁脚本开头的0x47表示将后面的71个字节压入堆栈。
其次4个字节序列号为固定值0xffffffff:
json格式sequence字段:4294967295
hex格式4个字节数据:ffffffff
十六进制0xffffffff转化为十进制值为4294967295。
其次1个字节表示交易输出的个数:
json格式vout_sz字段:2
hex格式1个字节数据:02
表明该交易有两个交易输出。
其次8个字节表示转出的btc的数量,单位为聪:
json格式value字段:1000000000
hex格式8个字节数据:00ca9a3b00000000
小端格式十六进制值0x00ca9a3b00000000转化为大端格式十六进制值0x000000003b9aca00,之后转化为十进制值为1000000000,表示该交易输出转出比特币的值为10亿聪,1亿聪=1BTC,因此该交易输出转出了10个比特币。
其次1个字节表示锁定脚本的字节长度:
json格式字段:无对应
hex格式8个字节数据:43
表明接下来的锁定脚本字节长度为67个字节,转化为十六进制值为0x43。
其次67个字节表示锁定脚本:
json格式script字段:4104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84c
hex格式67个字节数据:4104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac
锁定脚本开头的0x41表示将后面的65个字节压入堆栈。
其次8个字节表示转出的btc的数量,单位为聪:
json格式value字段:4000000000
hex格式8个字节数据:00286bee00000000
小端格式十六进制值0x00286bee00000000转化为大端格式十六进制值0x00000000ee6b2800,之后转化为十进制值为4000000000,表示该交易输出转出比特币的值为40亿聪,因此该交易输出转出了40个比特币。
其次1个字节表示锁定脚本的字节长度:
json格式字段:无对应
hex格式1个字节数据:43
表明接下来的锁定脚本字节长度为67个字节,转化为十六进制值为0x43。
其次67个字节表示锁定脚本:
json格式script字段:410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac
hex格式67个字节数据:410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac
其次4个字节表示锁定时间:
json格式字段:无对应
hex格式4个字节数据:00000000
锁定时间为0,表示立即执行。
2.3 比特币区块链之后的发展
2010年9月,首个矿池 slushpool出现,发明了多个节点合作挖矿的方式,成为比特币挖矿这个行业的开端[18]。
2011年4月,比特币官方有正式记载的(https://bitcoin.org/en/version-history)第一个版本:0.3.21发布。这个版本意义重大。首先,由于支持 uPNP(一种 P2P)。其次,在此之前比特币节点最小单位只支持0.01比特币,相当于"分",而这个版本真正支持了"聪"。
2013年,比特币发布了0.8的版本,这是比特币历史上最重要的版本。它完善了比特币节点本身的内部管理、网络通讯的优化。在这之后,比特币才真正支持全网的大规模交易,真正产生了全球影响力。在0.8版本中比特币引入了一个大的缺陷。这个版本发布以后比特币短时间就出现了硬分叉。
2013年,以太坊创始人Vitalik Buterin发布了以太坊(Ethereum)初版白皮书,启动了Ethereum项目[19]。
2016年1月在Github上超过了1万个相关的开源项目。区块链生态环境已经完全成熟了。