区块链(Blockchain)是一系列现有成熟技术的有机组合,它对账本进行分布式的有效记录,并且提供完善的脚本以支持不同的业务逻辑。在典型的区块链系统中,**数据以区块(block)为单位产生和存储,并按照时间顺序连成链式(chain)数据结构。**所有节点共同参与区块链系统的数据验证、存储和维护。新区块的创建通常需得到全网多数(数量取决于不同的共识机制)节点的确认,并向各节点广播实现全网同步,之后不能更改或删除。
从外部来看,区块链系统应具备如下特征:
- 多方写入,共同维护
- 公开账本
- 去中心化
- 不可篡改
区块链技术是对现有技术的一种补充,其在现有的加密技术上,利用分布式账本和共识机制形成在数据流转过程中防篡改的一种机制保障。
–以上摘自《华为区块链白皮书》
区块链分为公有链、私有链、联盟链三种,比特币和以太坊都属于公有链范畴。
- 主流金融机构难以接纳公有链。
- 私有链与公有链架构差异大。
- 私有链和联盟链还很不成熟。
–以上摘自《区块链技术指南》
公有链:账本全公开 任何参与者可见 参与者匿名
联盟链:账本联盟组织内公开 实名参与 满足监管要求
私有链:账本不公开 组织内可见
区块链起源于比特币
–图片来自华为云区块链相关文档
每个区块分成块头 Block header和块身 Block body两部分。
保存区块的宏观信息(80bytes)
–version 版本号(4bytes)
–hash of previous block header 前一区块的哈希(32bytes)
–Merkle root hash merkle tree的根哈希值(32bytes)
–timestamp 时间戳(4bytes)
–target 难度目标阈值的编码nBits(4bytes)
–nonce 随机数(4bytes)
保存交易列表
–transaction list 交易列表(包括coinbase tx)
图例:
比特币中的哈希函数使用的是SHA-256(Secure Hash Algorithm),符合三个性质.
collision-resistance
鸽笼原理
作用:求摘要digest
hiding
成立条件:1)输入空间足够大的 2)输入分布均匀
作用:数字信封digital commitment / digital equivalent of a sealed envelope.
puzzle-friendly
作用:工作量证明POW
比特币是去中心化的,开户不依靠外界批准,在本地创建一个公私钥对(public key,private key),就是一个账户。
比特币使用的非对称加密是ECC(Elliptic Curves Cryptography,椭圆曲线加密),基于“椭圆曲线离散对数”的数学难题,使用特定的曲线方程和基点生成公钥和私钥,选择的是secp256k1曲线。
过程:随机数 --> 私钥 --> 公钥 --> 地址(公钥哈希)
公私钥对在比特币中,主要是用作数字签名。发布交易时,通过自己的私钥对交易的摘要进行签名,其他人通过自己的公钥去验签。
例:
注:私钥泄露,丢失情况
比特币系统中每个交易都包含输入和输出两部分,输入部分要说明币的来源(1.防止币是凭空捏造的 2.防止double spending.)以及付款人的公钥(验签),输出部分要给出收款人的公钥的哈希(收款地址)。
每个交易可以有多个输入,也可以有多个输出。所有输入的金额要等于所有输出的金额,即 total inputs = total outputs。有些交易会出现input > output,那么这个差额就是作为交易费 transaction fee给获得记账权的节点。
注:激励机制,稀缺性
指的是一方(证明者)向另一方(验证者)证明一个陈述是正确的,而无需透露除该陈述是正确以外的任何信息。
注:匿名性保证
零知识证明的数学基础是同态隐藏。同态隐藏的3个性质:
1.如果x,y不同,那么它们的加密函数值E(x)和E(y)也不相同。
即加密函数值不会出现碰撞,不同于哈希函数的collision resistance。反之加密函数值相等,那么原来的输入也是相等的。
2.给定E(x)的值,很难反推出x的值。
即加密函数不可逆,类似哈希函数的hiding性质。
3.同态运算:给定E(x)和E(y)的值,我们可以很容易算出某些关于x,y的加密函数值。
–同态加法:通过E(x)和E(y)计算出E(x+y)的值
–同态乘法:通过E(x)和E(y)计算出E(xy)的值
–扩展到多项式
注:同态隐藏函数的实现
例:A(证明者)想要向B(验证者)证明他知道一组数使得x+y=7(陈述),同时不让B知道x和y的具体数值(隐藏)。
A把E(x)和E(y)的数值发给B;(利用性质2,E(x)和E(y)不可逆,所以无法推算出x和y的值。)
B通过E(x)和E(y)计算出E(x+y)的值(利用性质3同态加法);
B同时计算出E(7)的值,如果E(x+y) = E(7),则验证通过,否则失败。(利用性质1,E(x+y) = E(7),说明x+y=7,因为没有碰撞,如果两个密码值E(x+y) 和E(7)是相等的,那么两个输入一定是相等的。)
最基本的数据结构,就是一个个区块组成的链表。和普通链表区别就是用哈希指针Hash pointers代替普通指针。
普通指针存的是某个结构体在内存中的地址,**哈希指针不仅保存地址,还保存hash值 H( )。**所以不仅能找到结构体的位置,还能检测出内容是否被篡改。
如果修改某个区块的内容,则后面区块的H( )对不上,包括系统保留的H( )都需要修改。只需要记住最后一个H( ),就会检测出对区块链的任何部分修改。哈希指针的性质保证了整个区块链的内容是不可篡改的。
注:指针保存的是本地内存的地址,只在本地计算机才有意义,传到其他计算机上没有意义。发布区块时,哈希指针如何通过网络进行传输?
哈希指针只是一种形象的说法,**实际使用只有哈希,没有指针,或者认为hash本身就是指针。**全节点一般是把区块存储在一个key-value数据库中,key就是区块哈希,value就是区块内容。常用key-value数据库level DB,所谓的区块链这种链表结构,实际上是在levelDB里面用hash值串起来的。只要掌握最后一个区块的hash,就可以通过level DB查找hash值这个key所对应的value,查找到最后一个区块内容,该区块header中又有前一个区块的hash,可以找到前一个区块内容。以此类推,最终能把整个区块链找出来。
只要记住root hash,能检测出对树中任何位置的修改。
merkle tree作用:提供merkle proof。
proof of membership O(log(n))
proof of non-membership O(n)
Trie树
–图片来源于网络
Patricia tree(trie)
–图片来源于网络
MPT
拜占庭容错算法(Byzantine Fault Tolerance,BFT)
来源:拜占庭将军问题(The Byzantine Generals Problem)
实用拜占庭容错(Practical Byzantine Fault Tolerance,PBFT)
应用:hyperledger facric
工作量证明(Proof of Work,POW)
应用:BitCoin Ethereum前3阶段
权益证明(Proof of Stake,POS)
应用:Ethereum第4阶段
委任权益证明(Delegated Proof of Stake,DPOS)
应用:BitShare
非拜占庭容错算法(Crash Fault Tolerance,CFT)
例:Paxos,Raft,ZAB
比特币系统中要取得的分布式共识是去中心化账本中的内容
比特币中每个节点都可以在本地组装一个候选区块,把认为合法交易放在区块中,然后开始不停地尝试大量nonce值(4 bytes),使整个block header中的哈希值小于等于给定的目标阈值 target,即H(block header) <= target,即挖矿。
只有找到符合要求的nonce,获得记账权,即往比特币去中心化的账本里写入下一个区块的权利,才有权发布下一区块。puzzle friendly性质说明获得记账权没有捷径,只能一个个输入去试,保证了“工作量证明”(proof of work,POW)机制。
其他全节点收到区块,验证合法性,比如验证header中的内容是否正确,验证body中每个交易是否都是合法,有合法的签名,以前也没有被消费过。
注:分叉,最长合法链,抄袭别人nonce值发布,耗电
target越小,挖矿难度越大。调整挖矿难度,就是调整目标空间在整个输出空间中所占的比例。
**系统总算力越来越强,如果难度不变,出块时间将会越来越短。**一个区块传播给大多数节点所需要的时间大约是几十秒,如果出块时间缩短,如几秒钟一个,那么会很容易出现分叉。分叉过多,系统不易达成共识,威胁系统安全性。
每2016个区块调一下阈值 target,也就是14天。
target = target *(actual time / expected time)
difficulty = difficulty *(expected time / actual time)
计算target的方法是写在比特币系统的代码中,每挖到2016个区块,会自动进行调整,代码开源。实际代码中,上调或下调都有4倍的限制。
每一次尝试nonce可以看作是一次Bernoulli trial(a random experiment with binary outcome)。如果做了很多的Bernoulli trial,每个实验都是随机的,那么这些Bernoulli trial就够成了一个Bernoulli process(a sequence of independent Bernoulli trials)。Bernoulli process一个性质是无记忆性 memoryless,即做大量的实验,前面的结果对后面没有影响。
对于挖矿来说,每次尝试nonce,成功的可能性很小,需要尝试大量的nonce才能符合要求,这种情况下,Bernoulli process可以用Poisson process来近似。实验的次数很多,每次成功的概率很小。
出块时间服从指数分布 exponential distribution。整个系统平均出块时间为10min,是比特币协议设计的定期调整挖矿难度,使得平均出块时间维持在10min左右。具体到每一个矿工,他能够挖到下一个区块的时间,取决于矿工的算力占系统总算力的百分比。指数分布也是无记忆的,也叫作progess free,是挖矿公平性的保证。
注:挖矿过程中,如果监听到别人发布一个合法区块的情况。
智能合约概念可追溯到 20 世纪 90 年代,由计算机科学家、法学家及密码学家尼克·萨博(Nick Szabo)首次提出。他对智能合约的定义如下:“一个智能合约是一套以数字形式定义的承诺,包括合约参与方可以在上面执行这些承诺的协议。”
用技术手段保证合同参与方从开始就不可能违约,代码一旦发布到区块链上,通过不可篡改性,保证大家只能按照代码中的规则执行。
本质是运行在区块链上的一段代码,代码的逻辑定义了合约的内容。
Solidity是智能合约的最常用的语言,语言上与js接近。如下: