区块链技术琢磨
一直以来一个人琢磨了些区块链技术相关基础知识的整理和分享,一个人琢磨有很大的局限性,年前大胆设想聚集了些同学、朋友。大家一块利用闲暇时间琢磨些区块链技术相关内容。接下来所有的关于区块链技术知识的分享,都属于区块链技术琢磨。
有兴趣一块来琢磨的可以添加文末尾我的微信,一块交流学习,参与折腾项目的同学,则希望在不影响工作和学习的前提下,有一定的输出。
原则:
1.不影响正常工作学习,利用空余时间,折腾琢磨一些区块链技术。
2.不作为商用,大家兴趣琢磨,故没有相应报酬,一切以兴趣为主。
3.我们有学生、有专业从事区块链一线开发的工程师、有各类目前没有从事区块链行业但对区块链技术有兴趣的人。
目的是学习,实践。
以太坊白皮书-2
区块链相关的各类项目,一般都从阅读白皮书开始,耐心读一遍白皮书,了解清楚思路 。
这里简单对以太坊白皮书作一次阅读,以太坊白皮书由巨蟹、少平翻译。
以太坊-(Ethereum):下一代智能合约和去中心应用平台。
作为状态转换系统的比特币
从技术角度讲,比特币账本可以被认为是一个状态转换系统,该系统包括所有现存的比特币所有权状态和“状态转换函数”。状态转换函数以当前状态和交易为输入,输出新的状态。例如,在标准的银行系统中,状态就是一个资产负债表,一个从A账户向B账户转账X美元的请求是一笔交易,状态转换函数将从A账户中减去X美元,向B账户增加X美元。如果A账户的余额小于X美元,状态转换函数就会返回错误提示。所以我们可以如下定义状态转换函数:
APPLY(S,TX) > S' or ERROR
在上面提到的银行系统中,状态转换函数如下:
APPLY({ Alice: $50, Bob: $50 },"send $20from Alice to Bob") = { Alice: $30,Bob: $70 }
但是:
APPLY({ Alice: $50, Bob: $50 },"send $70from Alice to Bob") = ERROR
比特币系统的“状态”是所有已经被挖出的、没有花费的比特币(技术上称为“未花费的交易输出,unspent transaction outputs 或UTXO”)的集合。每个UTXO都有一个面值和所有者(由20个字节的本质上是密码学公钥的地址所定义[1])。一笔交易包括一个或多个输入和一个或多个输出。每个输入包含一个对现有UTXO的引用和由与所有者地址相对应的私钥创建的密码学签名。每个输出包含一个新的加入到状态中的UTXO。
在比特币系统中,状态转换函数APPLY(S,TX)->S’大体上可以如下定义:
1.交易的每个输入:
·如果引用的UTXO不存在于现在的状态中(S),返回错误提示
·如果签名与UTXO所有者的签名不一致,返回错误提示
2.如果所有的UTXO输入面值总额小于所有的UTXO输出面值总额,返回错误提示
3.返回新状态S’,新状态S中移除了所有的输入UTXO,增加了所有的输出UTXO。
第一步的第一部分防止交易的发送者花费不存在的比特币,第二部分防止交易的发送者花费其他人的比特币。第二步确保价值守恒。比特币的支付协议如下。假设Alice想给Bob发送11.7BTC。事实上,Alice不可能正好有11.7BTC。假设,她能得到的最小数额比特币的方式是:6+4+2=12。所以,她可以创建一笔有3个输入,2个输出的交易。第一个输出的面值是11.7BTC,所有者是Bob(Bob的比特币地址),第二个输出的面值是0.3BTC,所有者是Alice自己,也就是找零。
注:bitcoin中使用UTXO,没有账户的概念,ethereum中有外部账户和合约账户的概念。白皮书中几个状态转换函数,简单明了的描述了现在中心化系统,比如银行转账系统的逻辑。简单说明UTXO,首先,TX:transaction,称为交易,TXO TX output 称为交易输出,UTXO:未花费的交易输出,bitcoin中UTXO集合称为UTXO集,每一笔交易都代表UTXO集的变化,也就是状态的转换。有些人常会说,在bitcoin系统中,没有比特币只有UTXO。把UTXO理解为现实中的一张签名支票,从计算机科学来看,UTXO就是一个数据结构,包含了交易数据和执行的脚本(pubkey scripts)。UTXO的好处更加私密,用户可以每笔交易都更换一个地址,那么两个地址之间的关联性就比较难发现,账户的好处,节省空间,每一次交易只有一个输入、输出、签名,编码简单,不需要复杂脚本即可实现。当然设计初衷也有区别,bitcoin有隐私方面的考虑,ethereum则更重视的是商业应用。
挖矿
如果我们拥有可信任的中心化服务机构,状态转换系统可以很容易地实现,可以简单地将上述功能准确编码。然而,我们想把比特币系统建成为去中心化的货币系统,为了确保每个人都同意交易的顺序,我们需要将状态转换系统与一个共识系统结合起来。比特币的去中心化共识进程要求网络中的节点不断尝试将交易打包成“区块”。网络被设计为大约每十分钟产生一个区块,每个区块包含一个时间戳、一个随机数、一个对上一个区块的引用(即哈希)和上一区块生成以来发生的所有交易列表。这样随着时间流逝就创建出了一个持续增长的区块链,它不断地更新,从而能够代表比特币账本的最新状态。
依照这个范式,检查一个区块是否有效的算法如下:
1.检查区块引用的上一个区块是否存在且有效。
2.检查区块的时间戳是否晚于以前的区块的时间戳,而且早于未来2小时[2]。
3.检查区块的工作量证明是否有效。
4.将上一个区块的最终状态赋于S[0]。
5.假设TX是区块的交易列表,包含n笔交易。对于属于0……n-1的所有i,进行状态转换S[i+1] = APPLY(S[i],TX[i])。如果任何一笔交易i在状态转换中出错,退出程序,返回错误。
6.返回正确,状态S[n]是这一区块的最终状态。
本质上,区块中的每笔交易必须提供一个正确的状态转换,要注意的是,“状态”并不是编码到区块的。它纯粹只是被校验节点记住的抽象概念,对于任意区块都可以从创世状态开始,按顺序加上每一个区块的每一笔交易,(妥妥地)计算出当前的状态。另外,需要注意矿工将交易收录进区块的顺序。如果一个区块中有A、B两笔交易,B花费的是A创建的UTXO,如果A在B以前,这个区块是有效的,否则,这个区块是无效的。
区块验证算法的有趣部分是“工作量证明”概念:对每个区块进行SHA256哈希处理,将得到的哈希视为长度为256比特的数值,该数值必须小于不断动态调整的目标数值,本书写作时目标数值大约是2^190。工作量证明的目的是使区块的创建变得困难,从而阻止女巫攻击者恶意重新生成区块链。因为SHA256是完全不可预测的伪随机函数,创建有效区块的唯一方法就是简单地不断试错,不断地增加随机数的数值,查看新的哈希数值是否小于目标数值。如果当前的目标数值是2^192,就意味着平均需要尝试2^64次才能生成有效的区块。一般而言,比特币网络每隔2016个区块重新设定目标数值,保证平均每十分钟生成一个区块。为了对矿工的计算工作进行奖励,每一个成功生成区块的矿工有权在区块中包含一笔凭空发给他们自己25BTC的交易。另外,如果交易的输入大于输出,差额部分就作为“交易费用”付给矿工。顺便提一下,对矿工的奖励是比特币发行的唯一机制,创世状态中并没有比特币。
注:现在bitcoin的奖励是12.5个BTC。这里大致说明的都是bitcoin的一些机制,挖矿的目的不是创造新币,这是一种激励机制,挖矿是一种机制,这种机制实现了去中心化的安全(来自精通比特币),这段话深刻说明了挖矿的意思。POW:proof-of-work工作量证明,这个最简单的理解就是多劳多得,说的书面化,“通过工作以获得指定成果,成果证明付出的努力”,工作量证明最早出现的应用场景是哈希现金,Adam Back于1997年发明用于抵抗邮件的拒绝服务及垃圾邮件网管滥用。比特币中通过计算哈希函数(Hash Function)来作工作量证明,这里简要说明下哈希函数:也称为散列函数,给定一个输入x,它会算出相应的输出H(x),输入x可以是任意长度的字符串,输出结果即H(x)的长度是固定的,计算H(x)的过程是高效的(对于长度为n的字符串x,计算出H(x)的时间复杂度应为O(n)关于函数碰撞等具体问题将来另作一文说明)。比特币中计算方式是SHA256(Secure Hash Algorithm)输出为256位的哈希算法,
为了更好地理解挖矿的目的,让我们分析比特币网络出现恶意攻击者时会发生什么。因为比特币的密码学基础是非常安全的,所以攻击者会选择攻击没有被密码学直接保护的部分:交易顺序。攻击者的策略非常简单:
1.向卖家发送100BTC购买商品(尤其是无需邮寄的电子商品)。
2.等待直至商品发出。
3.创建另一笔交易,将相同的100BTC发送给自己的账户。
4.使比特币网络相信发送给自己账户的交易是最先发出的。
一旦步骤(1)发生,几分钟后矿工将把这笔交易打包到区块,假设是第270000个区块。大约一个小时以后,在此区块后面将会有五个区块,每个区块间接地指向这笔交易,从而确认这笔交易。这时卖家收到货款,并向买家发货。因为我们假设这是数字商品,攻击者可以即时收到货。现在,攻击者创建另一笔交易,将相同的100BTC发送到自己的账户。如果攻击者只是向全网广播这一消息,这一笔交易不会被处理。矿工会运行状态转换函数APPLY(S,TX),发现这笔交易将花费已经不在状态中的UTXO。所以,攻击者会对区块链进行分叉,将第269999个区块作为父区块重新生成第270000个区块,在此区块中用新的交易取代旧的交易。因为区块数据是不同的,这要求重新进行工作量证明。另外,因为攻击者生成的新的第270000个区块有不同的哈希,所以原来的第270001到第270005的区块不指向它,因此原有的区块链和攻击者的新区块是完全分离的。在发生区块链分叉时,区块链长的分支被认为是诚实的区块链,合法的的矿工将会沿着原有的第270005区块后挖矿,只有攻击者一人在新的第270000区块后挖矿。攻击者为了使得他的区块链最长,他需要拥有比除了他以外的全网更多的算力来追赶(即51%攻击)。
注:白皮书中清楚解释了BTC的一个流程,这里扩展说下分叉。软分叉:官方定义:A temporary fork in the block chain which commonly occurs whenminers using non-upgraded nodes violate a new consensus rule their nodes don’t know about.(当新共识规则发布后,没有升级的节点会因为不知道新共识规则下,而生产不合法的区块,就会产生临时性分叉。)说实话官方定义感觉有点模糊。
当整个区块链网络中,系统版本或协议升级后,且和老版本协议不兼容,那么升级后的新节点就无法接受老节点挖出来的全部或者部分区块,因为新节点的算力较大,所以老的节点挖出来的区块没有机会得到认可,老节点产生的区块最终会被认为是短链而被放弃,新老节点始终还是在同一条链上工作,这种情况称作软分叉。新节点要求比老节点严格多。
硬分叉:官方定义:Apermanent divergence in the the block chain, commonly occurs when non-upgradednodes can’t validate blocks created by upgraded nodesthat follow newer consensus rules.(区块链发生永久性分歧,在新共识规则发布后,部分没有升级的节点无法验证已经升级的节点生产的区块,通常硬分叉就会发生。)
当整个区块链网络中,系统版本或协议升级后,且和老版本协议不兼容,未升级的老节点无法接受新节点挖出的全部或者部分区块,导致出现了两条链,假设新节点的算力较大,新节点们在维护一条链,老节点也始终在维护一条他认可的链,如果这时候大多数的节点都开始升级为新版本,那么老节点维护的链能不能存活就看算力有多少了,这就称作硬分叉。
总结说下ethereum的挖矿共识:ethereum的核心算法是Ethash,每12-15秒产出一个区块,每个区块奖励5个以太币。除了和bitcoin一样的挖矿奖励和手续费外,ethereum的挖矿收益还包括叔块奖励和引用叔块奖励。ethereum使用混合型的安全协议,其技术的演进分成了四个阶段,即Frontier、Homestead、Metropolis、Serenit。在前三个阶段,ethereum共识算法采用工作量证明机制(PoW),在第四阶段则切换到Capser算法——一种高拓展性的权益证明机制(PoS),其基础是投注共识,核心思想是为验证人提供机会,以协议对赌哪个块会被最终确定,从而平衡矿工和持币者的权利和利益。
作者微信:
领取专属 10元无门槛券
私享最新 技术干货