区块链(1.0)是一个基于密码学安全的分布式账本,是一个方便验证,不可篡改的账本。
通常认为与智能合约相结合的区块链为区块链2.0, 如以太坊是典型的区块链2.0
很多人只了解过比特币,不知道区块链,比特币实际是一个使用了区块链技术的应用。
而区块链是采用哈希函数进行运算的,所以我们要了解一下哈希函数
哈希函数:Hash(原始信息) = 摘要信息
原始信息可以是任意的信息, hash之后会得到一个简短的摘要信息
哈希函数有几个特点:
同样的原始信息用同一个哈希函数总能得到相同的摘要信息
原始信息任何微小的变化都会哈希出面目全非的摘要信息
从摘要信息无法逆向推算出原始信息
举例说明:
Hash(张三借给李四100万,利息1%,1年后还本息 …..) = AC4635D34DEF
账本上记录了AC4635D34DEF这样一条记录。
可以看出哈希函数有4个作用:
简化信息
很好理解,哈希后的信息变短了。
标识信息
可以使用AC4635D34DEF来标识原始信息,摘要信息也称为原始信息的id。
隐匿信息
账本是AC4635D34DEF这样一条记录,原始信息被隐匿。
验证信息
假如李四在还款时欺骗说,张三只借给李四10万,双方可以用AC4635D34DEF来验证原始信息
哈希函数的这4个作用在区块链技术里有广泛的运用。
假设有一个账页序号为0的账页交易记录如下:
账号 | 入账 | 出账 | 余额 | 备注说明 |
---|---|---|---|---|
王二 | 100 | 190 | 收到xxx货款 | |
张三 | 100 | 30 | xxxx | |
李四 | 120 | 90 | 170 | xxxx |
记账时间为:2017-10-22 10:22:02
区块链在记账是会把账页信息(包含序号、记账时间、交易记录)作为原始信息进行Hash, 得到一个Hash值,如:787635ACD, 用函数表示为:
1 | Hash(序号0、记账时间、交易记录) = 787635ACD |
账页信息和Hash值组合在一起就构成了第一个区块。
比特币系统里约10分钟记一次账,即每个区块生成时间大概间隔10分钟
在记第2个账页的时候,会把上一个块的Hash值和当前的账页信息一起作为原始信息进行Hash,即:
1 | Hash(上一个Hash值、序号1、记账时间、交易记录) = 456635BCD |
这样第2个区块不仅包含了本账页信息,还间接的包含了第一个区块的信息。依次按照此方法继续记账,则最新的区块总是间接包含了所有之前的账页信息。
所有这些区块组合起来就形成了区块链,这样的区块链就构成了一个便于验证(只要验证最后一个区块的Hash值就相当于验证了整个账本),不可更改(任何一个交易信息的更改,会让所有之后的区块的Hash值发生变化,这样在验证时就无法通过)的总账本。
由于记账是有奖励的,每次记账都可以给自己凭空增加一定数量的个比特币(当前是12.5比特币,博文写作时每个比特币是4万人民币以上,大家可以算算多少钱),因此就出现大家争相记账,大家一起记账就会引起问题:出现记账不一致的问题,比特币系统引入工作量证明来解决这个问题,规则如下:
一段时间内(10分钟左右,具体时间会与密码学难题难度相互影响)只有一人可以记账成功
通过解决密码学难题(即工作量证明)竞争获得唯一记账权
其他节点复制记账结果
不过在进行工作量证明之前,记账节点会做进行如下准备工作:
收集广播中还没有被记录账本的原始交易信息
检查每个交易信息中付款地址有没有足够的余额
验证交易是否有正确的签名
把验证通过的交易信息进行打包记录
添加一个奖励交易:给自己的地址增加12.5比特币
如果节点争夺记账权成功的话,就可以得到12.5比特币的奖励。
1 | # 没有难度时为:Hash(上一个Hash值,交易记录集) = 456635BCD |
我们知道改变Hash的原始信息的任何一部分,Hash值也会随之不断的变化,因此在运算Hash时,不断的改变随机数的值,总可以找的一个随机数使的Hash的结果以若干个0开头(下文把这个过程称为猜谜),率先找到随机数的节点就获得此次记账的唯一记账权。
Hash值是由数字和大小写字母构成的字符串,每一位有62种可能性(可能为26个大写字母、26个小写字母,10个数字中任一个),假设任何一个字符出现的概率是均等的,那么第一位为0的概率是1/62(其他位出现什么字符先不管),理论上需要尝试62次Hash运算才会出现一次第一位为0的情况,如果前两2位为0,就得尝试62的平方次Hash运算,以n个0开头就需要尝试62的n次方次运算。我们结合当前实际区块#493050信息来看看:
注:数据来源于https://blockchain.info
我们可以看到Hash值以18个0开头,理论上需要尝试62的18次方次,这个数是非常非常巨大的,我已经算不清楚了,应该是亿亿级别以上了。如此大的计算量需要投入大量的计算设备、电力等,
目前应该没有单矿工独立参与挖矿了,基本都是由矿工联合起来组成矿池进行挖矿(矿池里的矿工按算力百分比来分收益)。
从经济的角度讲,只有挖矿还有收益(比特币价格不断上涨也让收益变大),就会有新的矿工加入,从而加剧竞争,提高算力难度,挖矿就需要耗费更多的运算和电力,相互作用引起最终成本会接近收益。
题外话:国内由于电力成本较低,相对收益更高,中国的算力占整个网络的一半以上。
在节点成功找到满足的Hash值之后,会马上对全网进行广播打包区块,网络的节点收到广播打包区块,会立刻对其进行验证。
如果验证通过,则表明已经有节点成功解迷,自己就不再竞争当前区块打包,而是选择接受这个区块,记录到自己的账本中,然后进行下一个区块的竞争猜谜。
网络中只有最快解谜的区块,才会添加的账本中,其他的节点进行复制,这样就保证了整个账本的唯一性。
假如节点有任何的作弊行为,都会导致网络的节点验证不通过,直接丢弃其打包的区块,这个区块就无法记录到总账本中,作弊的节点耗费的成本就白费了,因此在巨大的挖矿成本下,也使得矿工自觉自愿的遵守比特币系统的共识协议,也就确保了整个系统的安全。
矿工的收益其实不仅仅包含新发行的12.5比特币奖励,同时还有交易费收益(本文忽略一些细节是为了让主干更清晰)。
有兴趣的同学可以看看图中区块都包含了那些信息,红箭头标示出的是本文涉及的信息。
比特币没有中心机构,几乎所有的完整节点都有一份公共总帐本,那么大家如何达成共识:确认哪一份才是公认权威的总账本呢?
这其实是一个经济问题,在经济活动中的每个人都是自私自利的,追求的是利益的最大化,一个节点工作量只有在其他的节点认同其是有效的(打包的新区块,其他的节点只有验证通过才会加入到区块链中,并在网络上传播),才能够过得收益,
而只有遵守规则才会得到其他的节点认同。
因此,基于逐利,节点就会自发的遵守协议。共识就是数以万计的独立节点遵守了简单的规则(通过异步交互)自发形成的。
共识:共同遵守的协议规范
我们了解通过工作量证明来竞争记账,权威的总帐本是怎么达到共识的,没有完全说清楚,今天补上,
实际上,比特币的共识由所有节点的4个独立过程相互作用而产生:
每个节点(挖矿节点)依据标准对每个交易进行独立验证
挖矿节点通过完成工作量证明,将交易记录独立打包进新区块
每个节点独立的对新区块进行校验并组装进区块链
每个节点对区块链进行独立选择,在工作量证明机制下选择累计工作量最大的区块链
共识最终目的是保证比特币不停的在工作量最大的区块链上运转,工作量最大的区块链就是权威的公共总帐本。
先来一个定义,把累计了最多难度的区块链。在一般情况下,也是包含最多区块的那个链称为主链
每一个(挖矿)节点总是选择并尝试延长主链。
当有两名矿工在几乎在相同的时间内,各自都算得了工作量证明解,便立即传播自己的“获胜”区块到网络中,先是传播给邻近的节点而后传播到整个网络。每个收到有效区块的节点都会将其并入并延长区块链。
当这个两个区块传播时,一些节点首先收到#3458A, 一些节点首先收到#3458B,这两个候选区块(通常这两个候选区块会包含几乎相同的交易)都是主链的延伸,分叉就会产生,这时分叉出有竞争关系的两条链,如图:
两个块都收到的节点,会把其中有更多工作量的一条会继续作为主链,另一条作为备用链保存(保存是因为备用链将来可能会超过主链难度称为新主链)。
收到#3458A的(挖矿)节点,会立刻以这个区块为父区块来产生新的候选区块,并尝试寻找这个候选区块的工作量证明解。同样地,接受#3458B区块的节点会以这个区块为链的顶点开始生成新块,延长这个链(下面称为B链)。
这时总会有一方抢先发现工作量证明解并将其传播出去,假设以#3458B为父区块的工作量证明首先解出,如图:
当原本以#3458A为父区块求解的节点在收到#3458B,#3459B之后,会立刻将B链作为主链(因为#3458A为顶点的链已经不是最长链了)继续挖矿。
节点也有可能先收到#3459B,再收到#3458B,收到#3459B时,会被认为是“孤块“(因为还找不到#3459B的父块#3458B)保存在孤块池中,一旦收到父块#3458B时,节点就会将孤块从孤块池中取出,并且连接到它的父区块,让它作为区块链的一部分。
比特币将区块间隔设计为10分钟,是在更快速的交易确认和更低的分叉概率间作出的妥协。更短的区块产生间隔会让交易确认更快地完成,也会导致更加频繁地区块链分叉。与之相对地,长的间隔会减少分叉数量,却会导致更长的确认时间。