SegmentFault 区块链技术最新的文章
2018-03-22T13:39:11+08:00
https://segmentfault.com/feeds/blogs
https://creativecommons.org/licenses/by-nc-nd/4.0/
什么是51%攻击?
https://segmentfault.com/a/1190000013911969
2018-03-22T13:39:11+08:00
2018-03-22T13:39:11+08:00
Wancloud万云
https://segmentfault.com/u/wanyunbass
1
<p>本文内容翻译自Authorito Capital CEO的博文《WTF is The Blockchain?》和《Who Owns Blcockchain》,略有删减。<br>原文链接:<br><a href="https://link.segmentfault.com/?enc=9LNgXhheLXfvl75J9PB%2BVw%3D%3D.cHNCb80uzrk8BsiE7XZwrJfrJR70VPY5Ohc1QcncQVAmdommW6tIAMgIWjc7kPSp8pd8wrBl6tvSvQddKjGcNOcPAMDkU55v9heXaTKzVX0%3D" rel="nofollow">https://medium.com/@mohitmamo...</a><br><a href="https://link.segmentfault.com/?enc=0TB%2B7OvWe0ZCk7sgFlu3kQ%3D%3D.Z%2BnRLOf3z73QyQAyosjBQbyb19K8jfmVnjpQCfoNjFKr1rw%2F%2BR%2FZKb%2FYiSmYMpMGb2kg8eP0vsBwWp7vhKT%2FFQ%3D%3D" rel="nofollow">https://hackernoon.com/wtf-is...</a></p>
<p>我们把区块链假设为一个账本,每个区块就是每页账本页,当一页账本页记满帐的时候,就需要把它用“密码”(哈希值)封印起来,并把这页内容存到一个文件夹中。</p>
<p>现在想象一下,在这个文件夹中已经存有5页内容了,所有的页面都被一个“封印密码”封印起来。如果我回到第二页,修改了其中一些交易数据,来使我获得利益,会怎样?封印密码会让所有人发现交易的不一致性,对不对?如果我为已修改的内容重新算一个封印密码,并将其标记在页面上,又会怎样呢?</p>
<p><strong>这有个小把戏保护封印密码不被修改</strong></p>
<p>还记得我之前告诉大家的吗?有两个盒子,一个盒子里包含数字20893,另一个盒子是空的,等待玩家计算一个数值,使得两个盒子里的内容相加,得出我们要求的结果。</p>
<p>实际上,计算区块链的封印密码更为复杂,它需要三个盒子而不是两个盒子。这三个盒子中的两个已提前包含内容,其中一个盒子包含本页中的所有交易列表,另一个盒子包含前一页经过“魔法机器”(哈希加密)加工后输出的结果,第三个盒子要装的是玩家自己计算得出的封印密码。当三个盒子中都装满东西,并输入进机器中时,从机器右边输出的结果必须满足我们预设的条件。</p>
<p><img src="/img/bV6xg4?w=800&h=800" alt="clipboard.png" title="clipboard.png"></p>
<p>区块链中这个巧妙的“小把戏”,能够确保每一页的密封都需要依靠它的前一页。因此,如果有人想修改已经被封印起来的某页内容,他就必须修改这页之前的所有页面内容和封印密码,以保证链条的一致性和连续性。</p>
<p>在上篇文章的最开始,我们假设有10个玩家,如果这些玩家中的某个人试图欺骗大家,修改某页账本中的内容,他就不得不修改很多页的内容并重新计算这些页面上的封印密码。我们都知道计算封印密码有多难!从他修改的那页开始,他就得在网络中重新建立另外一条链。但是这条链永远追不上另外9个人维护的那条诚实的链的,因为一个人的工作能力和速度是赶不上9个人合在一起的工作能力和速度的。因此,保证了最长的那条链是“诚实的”链。因此,在这局游戏中,1个不诚实的家伙是打不过9个诚实的玩家的,他是不可能修改成功的。</p>
<p><img src="/img/bV6xhj?w=1000&h=637" alt="clipboard.png" title="clipboard.png"></p>
<p><strong>如果不是一个人,而是六个人变得不诚实呢?</strong></p>
<p>这种情况,用专业术语来说就是“51%攻击”。</p>
<p>如果网络中的大部分人变得不诚实并欺骗网络中的其他人时,那这个区块链协议就会面临失败。虽然这几乎不可能发生,但我们也要知道区块链系统的脆弱之处,它是建立在“群体中的大多数总是诚实的”假设之上的。</p>
<p>因此,在区块链中,如果一个人能掌握系统51%的算力,他就能重写区块链中的数据,从而让自己获利。</p>
<p>“系统中51%的算力”是什么意思?</p>
<p>系统中的玩家为记账和计算“封印密码”所花费的CPU耗能和电力,就是我们所说的算力。</p>
<p><strong>如何解决这个问题</strong></p>
<p>现在已经有人提出一些解决办法,比如不依靠电脑算力的“权益证明(proof of stake)”方法。权益证明是指系统中的玩家不用解决数学难题来算出“封印密码”,而是将他们手中持有的币作为赌注压在他们提出的解决方案上。如果大部分人都同意这个方案,那这个玩家就能得到奖励。如果大部分人不同意,那这个玩家之前押注的币就会被从他的钱包扣除。这个方法引入了惩罚方案。</p>
<p>但这个方法也存在问题。虽然不诚实的家伙会受到惩罚,但也会导致系统中的玩家“富者更富,穷者更穷”。如果我这次赢得了赌注并得到奖励,下次会押上更多的币,再次赢得赌注和奖金,再押入更多的资产。循环往复,最后,区块链中的大部分资产就会聚集到很少的人手中。如果掌握了多数财富的这几个人想要改写区块链,那他们就能办到。</p>
<p>无论何种情况,只要少数几个人掌握了区块链,那么区块链中的大多数人就处于风险之中。</p>
<p>在Twitter上有一段Vitalik和其他人的对话:<br>Bug Spencer:银行指定规则和核心开发者指定规则有什么不同吗?这两者都要依靠他人。<br>Vitalik Buterin:如果你发现JP Morgan滥用权力欺骗了你,你和其他对JP Morgan不满意的客户会分离出一个“JP Morgan经典”吗?</p>
<p>Vitalik的观点是:如果一个区块链中有对其规则不满意的用户,那这些用户可以分离出来重新创建一个分叉的链,就像以太经典区块链和以太坊区块链一样。</p>
<p>这个方法虽然不完全适用,但也是一个方法。</p>
<p>还有更好的方案吗?肯定会有,毕竟有那么多的区块链爱好者在为之付出。</p>
<p>本文首发自万向区块链,未经授权不允许转载。</p>
Nick Szabo:智能合约与传统合约的区别及其用途
https://segmentfault.com/a/1190000013786261
2018-03-16T17:14:24+08:00
2018-03-16T17:14:24+08:00
Wancloud万云
https://segmentfault.com/u/wanyunbass
0
<p>Nick Szabo:密码学家,智能合约之父。</p>
<p>智能合约理念可追溯至1993年,为密码学家Nick Szabo所发明。自从以太坊引入智能合约之后,其在区块链领域被越来越多的人所熟知。本文正是Nick Szabo在第三届区块链全球峰会(2017年9月14-16日)上的演讲内容,Nick从智能合约的发展着手,用通俗易懂的语言为我们解释了智能合约与传统合约的区别及其用途。</p>
<p>以下为演讲正文,Enjoy!</p>
<p>大家好,我给大家介绍一下智能合约。我在1993年发明了这个词,自此以后这个词的含义也有了不同的发展。</p>
<p>我先谈一下为什么要制定智能合约。传统合约是因为在生产产品和提供服务时,需要把不同的人和物整合在一起,从而可以为其他人创造价值。比如汽车发动机,由几千个不同的部件组成。如果在一个工厂生产这么多的元器件是不可能的,因为它涉及到很多方面的专业,所以我们要建立这样一种合约——要把某个部件的生产外包给其他人,他们再外包给其他人,就形成一个合约网络。所以每一次交易都会制定一个合约。</p>
<p>在典型的合约当中,一般会有两方,Bob和Alice,他们都希望这个交易有利于他们,所以他们需要的是创造共赢。根据合同法,大家就关系制定规则,而且还可以就自己的商业规则来制定一些条款。做交易需要制定规则,有些时候通过规则可以控制资产,如果有法律诉讼就涉及到对于钱的控制。合同法是整个社会的基础层或者基础协议,不管是企业、经济,以及其他的社会都依赖于合同法的存在。合约实际上自中世纪就开始在欧洲等地发展,中世纪时在地中海的世界出现了一种新的合约叫做保险合约。传统合约非常简单,一般只有一页,不像现在合约那么复杂。我们制定智能合约,其实理由和传统合约是一样的,希望创建双赢的交易。</p>
<p>那为什么要使用智能合约呢?因为干代码比湿代码更有优势。智能合约是干代码,而传统的律师、传统合约是湿代码。传统合约是基于合同法制定的,法律主要是基于主观的看法和类比。智能合约是基于软件的,软件主要建立在比特位之上。传统合约在安全性方面,可能面临法律的束缚,软件的特性是基于复制和密码学,还有其他的电脑科学,他们也是非常强大的。在预测性方面法律是比较灵活的,因为涉及到人的主观判断,这可能是好事,但是也意味着有时候会有模糊的判断或漏洞,但软件就比较固定和僵硬。在成熟度方面,法律已经打磨了成百上千年,软件和智能合约则比较新,应用经验也比较少,所以我建议大家要从法律的设计模式当中看看有没有启发我们的地方。传统的法律一般是人工、本地、不确定的,而公共的区块链往往是自动化的、全球的、无情的。</p>
<p>一些人觉得智能合约就是区块链上运行的电脑程序,这种看法没问题,但是和定义有所不同,我会谈谈我的见解。以太坊的合约仍然是智能合约的中心,它可以控制资产,可以控制在什么样的情况下发生什么样的事情,会影响到激励机制。同时合约也需要人们之间达成共识,要使人们之间达成共识就需要用户的界面,比如有搜索,让双方找到彼此,而且双方要能够进行谈判,对合约进行定制化。还有执行的监控,用户可以彼此监控对方合约的执行。还有一部分是在链下的,那就是执行的检验,比如说社交网络的营销等,看看是不是在某个时间确实举行了这样的活动。有一些东西我们可以在链上进行检验,比如代币的支付。</p>
<p>其实我们在区块链上能做的东西还有很多,智能合约是可以被定制化、被谈判的。这里用两个人谈判远期的合约举例子,你会看到交易所只能处理一些标准的合约,而且交易所并不是信任最小化的、去中心化的市场,它可能要牺牲很多的安全性,甚至响应的时间也比较慢,所以这样的买卖盘记录很难逃离中心化的机制,如果交易量很小的话买卖盘记录也没什么意义的。如果交易是在区块链上进行的,那么整个交易生命周期就是这样的,对Bob来说是签订一个智能合约,首先要有搜索、有谈判、有合约的执行,执行合约之后可能要管理抵押品或者仲裁等等。在合同执行的阶段,我们能很清楚的看到,交易双方是否执行了自己的义务、是否付了钱,或者准时交付自己的产品等等。</p>
<p>再来看一下交易阶段的创新,在交易阶段有很多创新,像亚马逊、Uber、谷歌都进行了创新。比如Uber在搜索阶段有地图告诉你驾驶员在哪里,你知道哪里有车可以载你,GPS告诉你在哪里,驾驶员在哪里,这样可以匹配,这是用户和提供商的匹配。谈判阶段你要么接受,要么不接受,这就是一个价格匹配的算法。在零售当中一般就是你接受或者不接受,因为讨价还价的成本比较高。Uber这里比较灵活一点,它考虑到了成本差异,比如说在不同的时间段,价格不同。所以只要双方就成本达成共识,他们就不需要再去讨价还价了。那么在执行阶段,有用加密的信用卡付款,也有GPS验证你到底去了哪里。执行后的阶段有评分、退款等。Uber会对司机进行评分,如果司机有不当行为就会把他们解聘,这是用算法解聘的,有了这样的算法,能提升整个交易效率。</p>
<p>智能合约还适用于现金流产品,把债券、股票等传统的资产放在区块链上,绕过传统的金融信息传递者可以进行更多的跨境投资,这样可以减少交易摩擦,而且信任最小化,全球是无缝的。现在加密货币和代币有超过1400亿的价值,但是并没有华尔街的支持、没有中心机构的支持。虽然GFA这家聚焦于金融的合约公司,把智能合约定义上为一种程序,但智能合约还是人与人之间的关系,所以我们也希望具有专业知识的人进行智能合约谈判。</p>
<p>把固定收益、贷款、场外交易、期权、远期集合在一起,我们建立了一些工具来减少这些交易的信任中介,那就是公有链。那些具有金融专业知识的非程序员可以在链上撰写智能合约,现在美国有1200万的专业的编程人员,但金融专业人士的数量远远超过编程人员的数量,所以应该充分利用这个庞大的群体。既懂金融知识又懂编程的人很少,所以我们专注于具有金融知识的非编程人员。智能合约是可以谈判的,可以从合同法和传统合约当中得到一些启发,你会看到Alice可以提出报价,Bob可以拒绝报价,也可以接受,这和以前的合约形式是非常相似的。智能合约也是可以定制化的,在智能合约合伙人的过程中Alice和Bob对智能合约进行定制化。所以智能合约是对简单的交易进行信任最小化的结算,非常直接,可以用在贷款、远期、互相、差价合约等等。</p>
<p>有两个涉及到人的因素:Composer,这是智能合约谈判的UI;Performance Manager,这是智能合约执行检验和资产账户监控的PI,这些成对的交易形成了一个自然的网络市场。这里的市场不是买卖盘的记录,而是双边合约的网络,是现在经济当中存在的网络,我觉得这也是智能合约的核心,也是我们所研究的方向。我们希望建立成对的交易使得在全球形成自发的网络,这样在全球进行交易就没有任何摩擦,可以实现全球无缝交易。离岸的互助基金、存托凭证、ETF流动性很差,而且成本较高、渗透性差,所以要进行跨境投资很难。比如阿根廷人或中国人很难在其他国家进行投资,但在新兴市场有很高的投资需求,他们却没有办法使用到全球最为可靠的投资。我们的解决方案是要安全反映区块链上金融资产最重要的特征,我们一直在思考如何使得现金流能够不需要这么多的信任中介,所以我们充分利用了加密货币和智能合约的能力,来大幅减少中介和交易对手的风险。</p>
<p>在上面大家看到有存托凭证,存托凭证实际上是投资于海外股票的一种非常普遍的方式。现在有很多的交易摩擦,比如存托凭证的流动性特别差,但交易量很大,而且还涉及到国际政治风险以及交易对手的风险,因为是私有银行发起的,透明度也比较差,此外还涉及到跨境合约,所以当有争执的时候不知道要去哪里进行起诉。通过我们这样一种基于区块链的解决方案,可以解决上面所描述的这些问题。我们可以利用高流动性的市场价格来决定,这样可以减少政治的风险,还可以实现现金流交易的及时到账,不需要等待几周的时间。</p>
<p>我知道有很多人正在开发区块链,我也有自己的愿望清单,我希望区块链是全球无缝化的,是安全无许可的,而且有简单保守的治理。我们现在的创新不是说没有治理,实际上我们在电脑科学方面是一个重大的突破,要设计全新形式的治理太过理想化,所以我还是希望我们的治理机构是很简单保守的。关于软件更新方面,我希望能由具有电脑科学技术的人来决定,不需要让会计师和律师见证这个交易合法不合法,这样会大大减少交易成本。</p>
<p>区块链上的智能合约就是一种金融找到服务,使得金融资产能够无缝跨境。当然软件没有办法解决湿代码的问题,湿代码涉及到人类主观判断,比如保险理赔或风险评估,不仅涉及到人的主观判断,还涉及到本地支持,所以不能够完全依赖于区块链。</p>
<p>充分利用区块链。区块链不可能什么都能做,传统的金融业也是如此。所以为了最优的利用区块链,我们必须把两者结合在一起,比如现金流产品就是把金融和区块链技术整合在一起,金融行业的人如果希望能够利用私有链的话,我觉得是错误的,纯粹主观者认为公有链可以做一切,不需要任何传统金融,我觉得这样的观点也是错的。比特币和以太坊世界的人也不太了解金融这个领域的实际情况,金融领域的人也不懂以太坊或者比特币的世界,他们有时候可能没办法达成统一的意见而进行争执,这就是文化的障碍。但是如果能够把这两者整合在一起,可能会创造最有价值的解决方案。</p>
<p>最后一点,持久存在的法律已经演进的非常成熟了,比如合同法在欧洲,来自于中世纪,演进得非常成熟,比重新发明交易机制更有效。我们的智能合约是可以定制的,也可以进行谈判,就像平常的合约一样。至于干代码和湿代码,我们现在还在学习什么时候要使用传统合约,什么时候要使用智能合约。所以我们也希望从这样一种传统的售货机转换为全球的金融机器,向大家提供金融的智能合约。谢谢大家。</p>
<p>本文首发于万向区块链微信公众号,未经授权不允许转载。</p>
Cosmos互联链通信技术规范(上)
https://segmentfault.com/a/1190000013488758
2018-03-02T15:18:36+08:00
2018-03-02T15:18:36+08:00
Wancloud万云
https://segmentfault.com/u/wanyunbass
1
<p>Cosmos被誉为“区块链的互联网”,旨在解决区块链可互操作性和可扩展性问题。其区块链间通讯协议可以实现区块链的互联,支持不同区块链之间的资产转移。随着区块链协同操作的需求越发强烈, Cosmos作为跨链技术的佼佼者,值得我们关注和学习。</p>
<p><strong>摘要</strong><br>本文给出了Cosmos IBC(互联链通信)协议的技术规范,这个协议在2016年6月Cosmos白皮书中有过首次描述[1]。其它一些技术也可以在一个原子操作中涵盖两个链,比如“哈希时间锁定合同”[2],不过很多(此类技术)都仅限于保证两个交易同时成功或失败。IBC则创建了完整的双向“侧链”,真正地允许跨链传递价值,并充分利用Tendermint的即时最终性来实现代币的快速传递。</p>
<p>IBC使用消息传递范式,并允许参与链保持独立。每个链都维护一个局部的部分顺序,而消息则用于跟踪所有跨链的因果关系。一旦两个链之间注册了信任关系,就可以安全地将数据包从一个链发送到另一个链上,代表从一个链上的一个账户转移代币到另一个链上的账户。该协议也可扩展到代币转移之外(的其它功能) – 尽管为其他应用类型设计安全的通信逻辑还待深入研究。该协议对链之间传输数据包时的阻塞时间或网络延迟不做假设,因此在异构环境中具有很强的鲁棒性。</p>
<p>本文阐述了Cosmos IBC协议的要求和结构,目标是提供足够的细节来充分理解和分析协议的安全性。</p>
<p>以下是《Cosmos互联链通信技术规范》译文的前半部分。</p>
<p><strong>一 、简介</strong></p>
<p>Cosmos IBC是围绕Cosmos网络和Tendermint共识引擎而设计的,从根本上依赖于Tendermint的即时最终性属性(意味着永远不会创建分叉)。Cosmos网络将由Cosmos枢纽和多个独立的分区组成,这些分区都通过IBC与枢纽进行通信。Cosmos枢纽还可以通过在它们之间中继IBC消息来桥接不同的分区。</p>
<p>我们从一个简单情形的具体例子入手,它可用于为后续的抽象解释提供一个形式框架。在此之后,将解释这个例子中使用的消息传递语义。接下来就是安全证明和数据包传输所依赖的技术基础。</p>
<p>在此之后,将讨论更高级的消息类型,例如超时和路由(以使更大的网络在相当长时间内能高效运作),还要对协议处理所有可能情况的能力予以充分考虑。</p>
<p>除了为IBC协议提供理论理解和参考文档之外,本文还旨在为协议的安全基础提出令人信服的论据。本文是对正在进行的Cosmos项目的一个报告,随着来自实践的数据不断更新理论,我们也将持续调整它的内容。</p>
<p><strong>二、 示例场景</strong></p>
<p>为了使讨论不那么抽象,这里用例子说明一个具体情形是如何工作的。Alice想从她在Cosmos分区X上的账户发送30个wink币(示例代币名称)给Cosmos枢纽上的Bob。假设分区X已经跟枢纽建立了一个IBC连接,Alice将在分区X上创建一个交易来发起传输。分区X会将那些代币冻结在某个托管账户,然后创建一个IBC数据包请求枢纽在Bob的账户中创建相应数量的代币。本质上,分区X上的验证节点集合会保证销毁这些代币以换取在枢纽上重铸它们。</p>
<p>一个独立的中继进程(任何人都可运行的客户端软件)可以从分区X提取那个IBC数据包的证明并将其发布到枢纽。枢纽将验证区块头,Merkle证明和顺序号来确保这是一个从分区X来的有效的IBC数据包。这下我们面临两个选择:要么分区X在枢纽上有足够信用来铸这30个wink币从而数据包被接受,要么信用不够而数据包被拒绝。如果数据包被接受,枢纽就在Bob的账户中铸30个新鲜的wink币,并将数据包连同成功记录存在它的传入队列中;如果数据包被拒绝,则不会创建代币,且队列中会存入一个失败记录。</p>
<p>我说的“信用”指的是什么?我们不希望每个连接到枢纽的链都能在枢纽上随意创建任意数量的任意代币,否则所有经济保证很快就变得毫无意义。枢纽必须使用它自己的逻辑来验证它是否足够信任分区X并接受那30个wink币。如果分区X是wink币的本源(X的原生代币),那么在发送wink币到枢纽这件事上,它将得到枢纽的极大信任。如果枢纽之前已经向分区X发送过500个wink币,那么它必须记住这个信息并允许分区X将(不超过)那500个wink币发送回枢纽,从而实现代币的自由流动。这个逻辑可以为代币传输提供安全性,其它应用则需要在不完全信任网络中所有分区的情况下,运用它们自己的逻辑来维护全局约束条件。</p>
<p>在枢纽成功或不成功地执行了那个交易之后,我们希望将交易的收据(连同证明)传回到分区X以完成这个循环。此收据只是另一种类型的IBC数据包,其执行方式与发送一样。唯一区别是,在发起分区处理收据绝不能产生错误。(根据收据内容)如果交易是成功的,则分区X将销毁托管的30个wink币,代币在分区间转移成功;如果交易因任何原因被拒绝,那么托管代币就会释放回Alice的账户 – 就像什么都没有发生过一样。</p>
<p>这意味着,在收到响应(成功或失败)之前,谁也不能碰分区X上的托管代币。除非我们有证据证明该数据包被接收链拒绝,已经发出的代币不会被释放。没有代币会被无端创建或销毁,也不可能执行双花,代币不会莫名消失在跨链操作中。发送方只需要等待两个数据包的转发和执行(很多情况下是十来秒钟)。对处理硬分叉分区(如ETH/ETC或BTC/BCH)的考虑会在下面的高级章节讨论。</p>
<p><strong>三、 消息传递语义</strong></p>
<p>在试图扩展区块链时,必须找到一种不违反任何安全保证的可行方法,来增加并行写的数量。防止双花需要为任何给定账户提供严格的串行访问(读和写),但是我们需要一些安全的方法来允许多个交易同时执行,而又不给恶意利用竞态条件提供可能性。</p>
<p>通过IBC协议,我们寻求避免一个问题,那就是允许多个独立节点将交易应用到相同的状态空间。如果你不想丢失任何数据(比如:强最终一致性),这个问题即便不考虑拜占庭角色也是困难的,在面对恶意行动人寻求利用任何不一致为自身牟利的情况下,则变得极其困难。安全地将不同的部分排序协调成一致的全局排序的最严谨方法是CRDTs(无冲突数据复制类型),它保证一组固定交易的所有可选的部分排序都将收敛到相同结果。CRDTs确实很有趣,但由于其固有特性,不允许在区块链用例中强制执行约束条件(例如,账户余额永远不能为负数)。</p>
<p>这个问题的另一个解决方案是使用分片,每个分片都只能访问状态空间的一部分。这可以增加吞吐量,但也会使任何涉及多个分片的交易极难正确执行。触及多个分片并需要一致视图的查询可以通过使用快照来执行,但是在高度分布的环境中这可能很困难。如果您想在两个分片上安全地、原子地查询和修改数据,就需要类似锁和三阶段提交的机制,这在许多数据库中都使用过。但是,如果您想要保证顺序并在通信层引入同步和定时假设,这就是一个阻塞操作,这使得它不适合分布式(多)区块链的场景。</p>
<p>我们通过定义“分区”而走了一条不同的路。每个分区都是一个独立的区块链,有自己的应用逻辑,自己的交易和数据存储。分区应该沿使用界线分开,因此绝大多数交易只影响一个分区,但我们可以保证任何跨链交易拥有安全和非阻塞的语义。每个分区都是一个完整的独立系统,它们使用消息传递进行通信。它们能够保证本地分区中的交易正确排序和执行,同时允许其它分区里的交易并行执行。唯一需要全局排序的东西是系统之间发送的消息。</p>
<p>分布式系统中的消息传递是一个已经被深入研究的领域,也是许多其它系统的搭建基础。我们能够对异步消息进行建模,且对信道不做时序假设。这样的结果是,我们允许每个分区以自己的速度行动,不被任何其它分区阻塞,却能够以当时网络允许的最快速度通信。</p>
<p>使用消息传递作为原语的另一个好处是,接收方能够对传入的消息应用自己的安全检查。仅仅因为一个我们了解的分区发送了一条消息给某个特定帐户添加50个以太币,并不意味着我们必须增加余额。我们可以在接收消息时添加我们自己的业务逻辑,以决定我们是否想拒绝该消息,以及我们想如何处理它(如果我们接受它)。在一个共享状态的场景中,很难甚至不可能做到这一点。消息传递允许每个分区确保其安全性和自治性,同时允许不同的系统作为一个整体协同工作。这可以看作是微服务体系架构的一个类比,但是跨越了组织边界。</p>
<p>为了在一个可证明的异步消息传递原语上构建有用的算法,我们需要定义一些更高阶的结构在所有系统间共享,从而允许我们和一些更容易的保证打交道。</p>
<p><strong>3.1 可靠消息队列</strong></p>
<p>我们在这里引入的第一个原语是可靠的消息队列(以下简称队列),这是异步消息传递的典型构造,它使我们能够确保因果排序并避免阻塞。</p>
<p>这个队列在每个区块链的Merkle数据存储中以多个键值对的形式永续保存。每个队列有一个独特的前缀,键是通过把一个代表其顺序号的8字节大端模式整数追加在这个前缀后面生成的。注意这个编码方式为我们提供了一个与键的顺序号相一致的键的字典序,这让我们能快速找到最新的数据包,也能证明在某个给定顺序位的数据包内容(或没有数据包) -- 假设像在我们的IAVL+ Merkle树[3]里那样访问范围证明。</p>
<p>新增的任何一个数据包的顺序号只能比当前最高数据包的顺序号大1。为了使证明更容易,我们会将顺序号也存在数据包本身(键值对的值)里面。一旦一个数据包被写入,它就是不可变的(除了在清理期间删除,这在后面会解释)。这使得接收分区可以接受位于源分区高度H的数据包Z的证明,而接收分区处理交易时尽可放心数据包在源分区里仍然以相同状态存在(异步性的要求)。区块链应用逻辑必须为所有队列保证这些约束条件,以确保消息层的正常运行。</p>
<p>假设我们的IBC队列的前缀是0xCAFE,我们可以看到多个数据包是如何存在Merkle树中的,而它们的顺序号又是如何追加(生成键)的,这样我们就可以轻松地为某个给定数据包的存在(或不存在)提供一个Merkle证明。下面图示了构建顺序号为2的数据包的Merkle证明的路径,用橙色高亮显示。</p>
<p><img src="/img/bV4Lcg?w=640&h=712" alt="clipboard.png" title="clipboard.png"></p>
<p>本节的其余部分将定义可通过此队列发送的基本消息类型。</p>
<p><strong>3.2 注册链(需经许可)</strong></p>
<p>在两个链之间建立起连接之前,我们需要先让它们彼此注册。这一点尤为重要,因为所有轻客户端证明都需要一个对验证消息头至关重要的信任种子,当有未经共识算法批准的恶意分支存在时,它能让我们确认那条真的链。</p>
<p>为了在A和B之间形成连接,我们必须在B上注册A,也要在A上注册B。这些过程是对称的,所以在这里我们只描述如何在A上注册B。在注册时,A为B添加一个可信的消息头和验证节点集合,保存在它的安全数据存储中。这用于验证来自B的所有未来的消息头,以及验证节点集合的变更。A还要创建两个具有不同名称(前缀)的队列。</p>
<p>ibc:<B的链标识>:out – 存放所有以B为目的地的传出数据包</p>
<p>ibc:<B的链标识>:in – 存放所有来自B的传入数据包连同它们的执行结果</p>
<p>注意,注册链应该是一个需要获得许可的操作,且执行时要有人工验证。这将产生一个信任声明,即这个消息头和验证节点集合代表了对应链的正确状态,它们不属于试图镜像这条链的某些影子链。不像PoW的最长链胜出算法,对权益证明而言信任必须在某个时点被明确授予。</p>
<p>而且,注册过程还必须定义好我们用来验证Merkle证明的算法(这些证明存在于队列中的IBC数据包里)。缺省设置是来自我们的IAVL树的Merkle证明格式,但是其他Merkle化的数据存储,比如Patricia Trie,也可以得到支持。这个算法必须在注册时设置一次,并且必须被参与链所支持。队列的整个生命周期都会基于可信的消息头,一致地使用该算法验证每个数据包或收据。</p>
<p><strong>3.3 验证节点变更</strong></p>
<p>任何生产链的验证节点集合都会随着时间推移而发展变化。当我们注册一个新链时,会针对一个特定的验证节点集合做一个信任声明 (更具体而言,我们的信任绑定的是这样一个条件:消息头拥有超过一定阈值数量的与给定公钥集相匹配的数字签名)。当我们信任的这组公钥变化时,我们需要一个消息来把这个变更通知给其它链。由于验证节点变更对共识算法至关重要,所以我们用一个标准格式把它存储在Tendermint的区块头内。</p>
<p>我们定义一个特殊的更新数据包,它包含一个Tendermint区块头和新的验证节点集合,我们可以将它发送给接收链。接收链可以核实验证节点集合变更的有效性,并使用它来验证所有未来的数据包。</p>
<p><strong>3.4 发送数据包</strong></p>
<p>发送一个IBC数据包涉及区块链应用逻辑调用IBC模块,告诉它需要发送的数据包以及目标链的标识。如果目标链已经注册好,IBC模块只需计算下一个顺序号并将其添加到传出队列out queue。顺序号与特定连接相关并由发送链生成,它们必须是单调递增和连续的。</p>
<p>数据包被写入Merkle化的数据存储,这样它就嵌入了和区块头相关联的证明当中。这些代表了数据包的键值对证明接下来就会被传送给其它链。</p>
<p>区块链应用程序必须对谁可以写一个队列的键空间做出限制,不是随便哪个智能合约都可以在那里写交易数据,只有当区块链逻辑判定数据包有效,且与数据包类型相关的全局约束条件得到满足(比如:上面例子中的托管代币被冻结),才会生成(并写入)数据包。</p>
<p><strong>3.5 中继数据包</strong></p>
<p>为了让数据包到达目标链,我们依靠一个或多个中继进程把链A上的传出证明out proof发布到链B的传入队列in queue中。由于这里只需要轻客户端证明,中继进程不需要是验证节点,甚至都不需要是全节点。实际上,如果每个发起创建IBC数据包的用户也负责将它中继到接收链,那就太理想了。唯一的限制是,中继进程必须能够在目标链上支付适当的费用。</p>
<p>为了系统自举,链开发人员可以提供一个有足够资金的特殊账号给中继进程,为所有数据包支付费用,直到用户在两个链上都有代币。不过,使用IBC的人应该自己负责支付这些费用。注意,更新消息头是一种代价高昂的交易(大约100个数字签名校验),而为一个已知消息头发布证明则要便宜得多(大约20个哈希计算)。因此,为了优化,许多数据包可以捆绑在一起在同一区块高度发送,即使它们是在不同的区块高度创建的,这样可以通过增加一点延迟来节省计算成本。</p>
<p>系统必须允许多个中继进程安全地并行运行,拒绝掉任何重复的消息发布。但更理想的是能在起初就防止他们尝试重复发布,因为这会浪费带宽和链上的计算时间。</p>
<p><strong>3.6 收据</strong></p>
<p>当一个IBC数据包发布到另一个链上并被认为是有效的(即,数据包的证明跟源链的已知消息头相匹配),则不管执行是否成功,我们都必须将它存储在传入队列in queue里,这样就有证据表明它已经被处理过。相关交易应该发送到合适的智能合约加以验证和执行,然后返回标准的ABCI结果(成功或错误);收到的数据包连同处理结果被写进传入队列。</p>
<p>另一个中继进程可以获得这个数据包已经在链B上处理过的证明,把它作为收据发布到链A。此收据将由链A处理,触发进一步的应用逻辑,以及对队列的清理(参见高级部分)。将请求从A中继到B的那个进程可以将响应从B中继回A,但也可以使用一个不同的进程来做这件事。</p>
<p>作者:Ethan Frey, frey@tendermint.com<br>译者:奚海峰 Haifeng Xi<br>校对:曹恒 Harriet Cao<br>本文首发于万云Wancloud微信号,未经授权不允许转载。</p>
<p>。</p>
干货 | 区块链快速通道:从技术原理到应用落地
https://segmentfault.com/a/1190000013270714
2018-02-12T10:34:37+08:00
2018-02-12T10:34:37+08:00
Wancloud万云
https://segmentfault.com/u/wanyunbass
15
<p>作者:万云首席架构师兼产品总监李晨<br>原文链接:<a href="https://link.segmentfault.com/?enc=2PcjMUjmjrEM1BibFuQroQ%3D%3D.nGaBlFJD8doRSlPO0u3EZ5ouDTetZzMMlGCzE71P6uBgb5YsvrSwCt4x8RA7WmLs9%2By1HX4O5YnzEBvZGaWC9A%3D%3D" rel="nofollow">http://mp.weixin.qq.com/s/snl...</a><br>如需转载请联系万云官方微信:万云Wancloud</p>
<p>2018年开始,好像所有的人都在谈论区块链,资本、精英、草根不断进场投身到区块链的浪潮之中。在外围观望的你或许懂技术而对区块链一知半解,或许有场景与创意却碍于其研发门槛,或许是已身处于行业却难于前行。区块链是机遇也是挑战,如何在这风起云涌的区块链世界里获得加速卡实现弯道超车?没有区块链技术基础的你又怎样迅速部署属于自己的第一个应用?<strong>本文整理自2018年2月7日万云首席架构师兼产品总监李晨在infoQ社群的分享内容,详读此文,将为你打开通向未来世界的快速通道。</strong></p>
<p>以下是分享正文,enjoy!</p>
<p>大家好!我是万向区块链万云平台的李晨Leo。感谢主办方的邀请,很高兴有这个机会跟infoQ社区的朋友们分享我和万云团队对区块链技术及应用的思考。</p>
<p>我今天的演讲将主要从以下两个方面进行:</p>
<p><strong>第一,对区块链技术进行基本介绍,尤其是区块链的发展历史和核心技术。</strong><br><strong>第二,分享万云平台在区块链行业当中的探索。万云专注于将区块链技术应用于各个行业,促进区块链在业务中的真正落地。</strong></p>
<p><strong>Part 1 技术原理</strong></p>
<p><strong>1.我们先看当下的区块链。</strong>下面这张图所展现的是区块链在互联网上的热度,两个最大的互联网平台Google和百度均显示区块链的搜索指数呈数级增长,可以发现当下区块链的热度十分高。</p>
<p><img src="/img/bV3QpU?w=837&h=467" alt="clipboard.png" title="clipboard.png"></p>
<p><strong>2.然后我们来看资本市场。</strong>二级市场相比一级市场更为严肃,更为传统也相对稳健,从公告和研报的数量来看,区块链在资本市场的表现也十分出色,公告有443篇,研报1000+。综合以上只能用一个字来形容当下的区块链——“热”,非常“热”。</p>
<p><img src="/img/bV3Qqk?w=838&h=465" alt="clipboard.png" title="clipboard.png"></p>
<p>从以上两张图所呈现的数字也反映出两种情况:从搜索指数来看,普通大众对区块链关注度日益增高且势头不减,从相关二级市场的情况来看,专业机构对区块链也越来越青睐有加。</p>
<p><strong>那么,区块链到底是什么?区块链有哪些技术特色?</strong></p>
<p>区块链的诞生之路:在人类历史上经历了几次重大技术革命,第一次工业革命解放了基本生产力;第一台计算机的诞生开启了信息化的进程;而互联网时代的到来建立起数据在不同主体之间的瞬间连接和交换,对信息流通产生了根本性变革;2008年“中本聪”第一次提出了区块链的概念,开启了信息互联网到价值互联网的变迁,其根本意义在于将原来的数据交换变成价值互联,而价值互联也正是区块链所重构的商业逻辑的关键所在。</p>
<p><img src="/img/bV3Qqn?w=848&h=471" alt="clipboard.png" title="clipboard.png"><br>从技术的角度定义区块链 :“区块链是以区块结构存储数据,多方参与、多方维护,通过密码学、P2P网络、共识算法等保证数据可靠的传输、存储、访问的技术体系”。</p>
<p><strong>区块链有哪些特点?最主要的技术特点是三个:去中心化、不可篡改、可追溯。</strong></p>
<p><img src="/img/bV3Qqs?w=839&h=467" alt="clipboard.png" title="clipboard.png"><br><strong>1.去中心化。</strong>在区块链的网络中分布着众多的节点,节点和节点之间地位平等,可以自由连接进行数据交换,不存在中心节点。所谓的去中心化和传统的分布式有稍微意义上的不同,传统分布式还是有中心的节点,最常见的就是所谓的负载均衡节点(Load Balance),只不过在中心节点后有很多其它节点,在数据结构上通常会形成“树”的形式,去中心化是“图”的结构,“图”的结构中每个节点是对等的。</p>
<p><strong>2.不可篡改性。</strong>利用密码学的技术保证区块链上的数据不可被篡改,主要是两个点:①哈希;②非对称加密。</p>
<p><strong>3.可追溯性。</strong>区块链的数据结构保证了从第一个区块(创世区块)开始所有的数据形成了一条链,在链上的任何记录都可以通过链的结构追溯到本源(也就是创世区块的信息)。</p>
<p>以上就是区块链最大的三个技术上的特点。要实现以上三个技术特点需要有三块重要的技术基石。</p>
<p><img src="/img/bV3Qqv?w=1080&h=602" alt="clipboard.png" title="clipboard.png"><br>1.第一块基石是P2P网络,P2P的网络去中心化,高性能,高可靠通讯的保证。</p>
<p>2.第二块基石是密码学,密码学保证数据无法被篡改而且是安全并可验证的。</p>
<p>3.第三块基石是共识算法,区块链网络各节点达成一致性的保障,也是现在评判区块链技术的核心指标之一。</p>
<p><strong>接下来我分别讲讲这三块重要的技术内容。</strong></p>
<p><strong>1.P2P网络。</strong>在传统的网络是中心化的网络,大家可以看左边这张图所有的机器、通讯都要走过一个中心化的节点完成通讯,一旦这个节点出现了问题整个网络就瘫痪了。就像现在如果电信、移动、联通的基站出现问题周围的网络通讯将会受到影响。右边这张图所显示的是P2P网络,大家可以看到它并没有一个中心化的节点,所有的节点之间直接互联互通。同时也因为没有中心化的节点,其中任意一点出现问题依旧能够保证整个网络还能通讯,因为你可以连接到其它节点上。所以P2P网络是去中心化的,参与各方地位对等,从而保证网络的健壮性、扩展性、高性能。</p>
<p><img src="/img/bV3Qqx?w=848&h=470" alt="clipboard.png" title="clipboard.png"><br>其实所有区块链的底层技术大多都在区块链概念提出之前就已经存在,只是区块链的出现将它们天才有效地结合在一起。比如P2P网络很早就出现了,我们常用的BT下载,它就是最早的P2P网络。</p>
<p><strong>2.密码学。</strong>密码学在区块链当中用的非常多,因为时间关系这里不作展开说明。讲一下如何通过“Merkle Tree”保证区块链上的数据不可被篡改。大家可以看这张区块链数据结构图,上方每一个大长方形就是一个区块(block),该区块内所有的交易数据都被存储在这个区块上;最下方的第三个交易 Tx3,简单说每一个交易会生成一个哈希,Hash3就是第三笔交易Tx3的哈希值。Hash2下面没有画,是第二笔交易Tx2的值,Hash3和Hash2组合在一起就是Hash23,最后变成“Merkle Tree”的根节点“Merkle Root”。每一个区块都有Merkle Tree,区块上所有的交易都会被存储在Merkle Tree上。区块和区块之间也是相互链接的,每一个区块都知道上一个区块的Hash值。</p>
<p><img src="/img/bV3QqC?w=848&h=479" alt="clipboard.png" title="clipboard.png"><br>那为什么这样的区块结构能实现数据不可篡改呢?假设我要篡改 Tx3,那我们将要篡改Hash3的值,接下来改变了Hash3就要改变Hash23,以此类推一直要改变Merkle Root的Hash值。因为区块的HASH中包括了该区块Merkle Tree Root的HASH值,所以一旦你改变了区块的HASH,就必须要修改之后所有区块的哈希值。同时这样的修改还要被网络中超过共识算法要求的节点接受。这就造成了篡改数据树的成本极高,几乎是不可能的。比特币网络运行了那么久,在没有一个人去专门维护它的情况下,从来没有发生过任何篡改,也就是这个道理。</p>
<p><strong>3.共识算法。</strong>共识算法是区块链比较核心的技术之一,保证区块一致性是其主要作用。常用的共识算法有:POW、POS、DPOS、PAXOS、PNFT。</p>
<p><img src="/img/bV3QqS?w=846&h=475" alt="clipboard.png" title="clipboard.png"></p>
<p><strong>①POW共识算法。</strong>也就是常见的比特币网络的共识算法,它通过哈希算力作为工作量证明去竞争记账权。POW的几个缺点:性能比较低;消耗大量的资源,尤其是算力;出块比较慢,10分钟左右。但它也优点,抗容错性很好,只有超过51%的节点攻击网络,网络才会失败, 容错性50%。</p>
<p><strong>②POS共识算法。</strong>相对POW,POS是用所谓的权益计算法。相对POW来说它有几大改进:不再消耗资源;提高性能,2分钟左右出块;同样容错性也是50%。</p>
<p><strong>③DPOS共识算法。</strong>POS实现2分钟左右出块是比较大的提高,但距离业务的要求还有一定距离,所以在此基础上进行优化产生了DPOS,简单来说DPOS不要求每个节点记帐,而是有代理节点来记帐,这比较像现实生活当中的议会制度,大家选出代表帮忙记帐,这样参与记帐的节点会相对集中,性能也就会提高。所以在DPOS情况下基本可以做到秒级出块,容错性也是50%。</p>
<p><strong>④PBFT共识算法。</strong>PBFT也就是所谓的拜占廷容错,它的性能非常非常快,可以达到秒级出块甚至比秒级还要快,但是它的容错性相对差一些,一般是33%左右。</p>
<p><strong>⑤PXOS共识算法。</strong>PXOS假设的前提是没有恶意参与者,简单说就是节点不会发送错误的信息,但有可能漏发信息。在这种前提下容错性50%,性能也是很快的,基本上秒级出块。</p>
<p>以上就是目前常见的5种共识算法。我们也可以看到评判共识算法大概有3个标准:1.效率,达成共识确认的效率,简单就是出块的效率。2.资源消耗,可能消耗电力、存储或者其他资源;3.容错性,就是网络可以抵抗多大比例的节点出错。</p>
<p>接下来再给大家讲一下区块链的分代和分类,首先说下区块链分代。</p>
<p><img src="/img/bV3Qra?w=845&h=472" alt="clipboard.png" title="clipboard.png"></p>
<p>按照《区块链:新经济蓝图》一书中的概念,把比特币以及相关的数字货币划分为区块链1.0,以以太坊为代表的智能合约划分为区块链2.0,而在非货币和金融领域外,在其他领域里的区块链的应用划分为区块链3.0。区块链1.0是基础的区块链,实现了数字货币所需的所有特性。区块链2.0的核心概念是智能合约,简单说就是可编程的数字货币。虽然只是加了一个前缀,但却是巨大的进步。这意味着不仅仅价值本身,价值相关的商业规则也可以被数字化,是价值互联网的一个巨大进度。关于区块链3.0,我图上画了一个问号,因为我也不知道怎么算区块链3.0。目前看有几大技术可以算是区块链3.0的潜在标准,比如解决链上数据隐私和协作矛盾的零知识证明技术,或者解决连接各种不同链的跨链技术等。</p>
<p><img src="/img/bV3Qrd?w=850&h=472" alt="clipboard.png" title="clipboard.png"></p>
<p>由于时间关系这里简单介绍一个<strong>跨链技术COSMOS。</strong>我们认为世界不可能是有一两个区块链所主导的,会有比较多的区块链,每一个链都完成它自己特有的功能,我们会将来生活在一个多链的世界里。通过跨链技术可以形成一个统一的生态系统,包括联盟链和私有链。跨链技术是实现价值互联网的关键,它连接起不同区块链的孤岛,也是区块链向外拓展的桥梁。</p>
<p><strong>COSMOS是基于Tendermint共识引擎的前沿跨链技术。</strong>Tendermint共识引擎实现了跨链技术中的基本技术需求(高性能和一致性)。同时Tendermint将共识引擎和底下的P2P网络层打包在一起形成Tendermint Core,加上具有很好扩张性的COSMOS SDK(实现多代币账户体系,见证人机制和出块等功能),这些都为跨链功能打下了扎实的技术基础。 COSOMS跨链网络通过IBC(inter-blockchain communication)协议通信,而COSMOS HUB扮演枢纽角色,简单说就是链之间的路由。通过COSMOS网络不但可以进行价值跨链转移,扩展IBC协议中的PAYLOAD,还可以进行其他信息的跨链转移。</p>
<p>区块链分类目前有三种:<strong>①公有链、②联盟链、③私有链。</strong></p>
<p><img src="/img/bV3Qrs?w=846&h=472" alt="clipboard.png" title="clipboard.png"></p>
<p>所谓的公有链是任何人都可读取的、任何人都能发送交易且交易能获得有效确认的、任何人都能参与其中共识过程的区块链。 随着公链规模的扩大,目前一些主流公链的性能都有待提高。 联盟链主要针对有竞争又需要合作的场景,技术上联盟区块链是指其共识过程受到预选节点控制的区块链。只有获准进入联盟的节点才可以参与其中。私有链一般仅在一个公司或者组织内使用,我觉得私有链更像一个分布式账本。</p>
<p><strong>Part 2 应用实践</strong></p>
<p>第一部分我介绍了区块链的发展历史及基本的技术概念。接下来我结合自身以及万云团队一直以来所做的实践,来分享区块链怎么帮助各行各业?也就是怎样让区块链结合现实以实现应用落地?</p>
<p>区块链技术的两大核心特征:第一个是不可篡改性,第二个是可追溯性。在区块链解决行业的问题当中,我们万云团队也提炼了一些解决方案,基本上也是遵从这两个目的。</p>
<p><strong>1.数据不可篡改性。</strong>基于这个特征行业中用的比较多的场景是信托。在市场加速释放的前提下,传统信托行业所存在的如文档安全性、时间有效性等信任问题日益凸显,而利用区块链不可篡改的特性能有效解决信托业务中所存在“互不信任”的市场痛点。如何实现?利用区块链技术可以将信托业务中的关键材料经过哈希加密处理,转换成不可逆推的特征值存储在区块链上,信托公司和用户如需进行数据验证,只要将已有的材料和信息经过哈希加密处理,再次与区块链上与其对应的信息进行对比,即可验证材料是否曾经被进行篡改。值得一提的是,2018年1月,万云团队帮助万向信托所开发的基于区块链的家族信托业务已上线使用,通过区块链技术,为万向信托可持续发展注入了新的生命力。</p>
<p><strong>2.可追溯性。</strong>钻石一直以来被视为是爱情、权利、地位和富贵的象征,一方面因人类的情感赋予让钻石有了高昂的价值,另一方面也因其价格诱人让市场滋生了走私的风气,从而使得产品与价格混乱,国家税收损失和难于监管。而利用区块链的可溯源特性,以构造共享数据库的联盟链为基础,通过多中心的方式与海外钻石平台、钻石交易所等共享数据,以行业4C为标准定义每一颗钻石的身份标签和流转体系,促进钻石交易的正规化。通过可溯源让每一颗存储在区块链上的钻石信息都可查证,让市场上存在的黑手无孔可寻,从而让钻石市场真正回归“透明”。</p>
<p>当然除此之外,区块链技术还可为更多行业提供解决方案,如版权交易、数字存证、智慧医疗等。</p>
<p>接下来我们讲区块链应用开发的模式,因为我们的所开发的应用都是以万云平台为基础,因此我将先对万云平台作一个简单的分享。</p>
<p>万云有一个宗旨,所有的技术都是为业务来服务的,我们不是为了技术而技术,不为了区块链而区块链,而是切实想让区块链真正帮助到这个行业。所以万云在产品的架构、设计之初我们就考虑到这点。万云的服务流程从底层的技术到上层的业务:不仅能提供底层技术、也能帮助企业设计解决方案,越往底越靠技术端,越往上越靠业务端。任何的区块链的开发者都可以从中选择一个适合自己的纬度,在万云上开发一条链,或者开发区块链相关的应用程序。</p>
<p><img src="/img/bV3QrE?w=822&h=468" alt="clipboard.png" title="clipboard.png"></p>
<p>万云生态的底层,主要是底层链。我们有两部分,一部分是公链的节点,一部分是联盟链的节点,所有的这些节点都部署在万云高性能的基础设施上,在万云产品的模块中称之为“极速万云”。在所有的这些点的节点之上有跨链技术,我们会把所有的链整合在一起,联盟链和公链上面会有一层跨链技术,这样即做到了统一,又各具特色,这都万云生态中最底层的架构。在底层链上提供两套模块:1.万云API,直接提供万云上承载的链原始的API,你可以在上面部署一个智能合约,也可以直接查询区块链数据。2.万云的IDE。其特色是可以即直接在万云上使用,也可以在本地安装。</p>
<p>我认为更有价值的是在上层。上层不仅有业务API,也提供行业解决方案,根据不同的行业,万云梳理出业务API,设计合适的解决方案。业务API落地在区块链上,但是对外呈现的形式和业务本身比较契合。通过业务API,可以节省开发和运维成本从而更专注于业务创新。区块链底层技术相关的工作,以及实现高可用、高性能、强安全的技术保障,所有这些都可以由万云轻松帮你实现。</p>
<p>在万云生态的更上层,还提供解决方案的设计、应用发布市场及交流论坛。部署在万云平台的优质的区块链项目可以选择在万云市场上进行推广;而万云论坛致力为所有区块链技术爱好者提供一个可自由交流的平台。</p>
<p><strong>下面我将以“万云抽奖”——一个完全部署在万云平台上的DApp为例,来介绍其诞生的流程,我将会重点从技术角度来还原。</strong></p>
<p>万云抽奖是我们所做的基于公有链的应用,主要是为解决抽奖过程中的“公开”、“公正”问题,是万云团队开发的一款基于区块链的抽奖程序。通过将所有抽奖的信息记录在区块链上,保证数据不可被篡改以及可溯源来实现抽奖结果公开,这点大家都比较容易懂。而实现“公正”是抽奖的难点所在,我们通过基于区块链来生成随机数解决了这个问题,下面我将会重点详细说明。</p>
<p>传统算法生成的随机数实际上并不是完全不可预测的,在随机种子的基础上结合算法自动生成的的数实际上是可复制的,算不上真正的随机(伪随机数)。随机数的随机性问题是基础算法面临的问题。我们的思路是随机性的生成,不被任何个体所控制,通过这个来解决随机性问题。</p>
<p>随机数通过所有参与者共同产生。首先,在区块链中创建一个合约,它定义了参与规则。具体的生成一个随机数的基本过程可以分为三个阶段:</p>
<p><img src="/img/bV3QrI?w=846&h=473" alt="clipboard.png" title="clipboard.png"></p>
<p><strong>第一阶段:收集有效的HASH(S),其中S就是随机种子。</strong>参与随机数生成的账号都在指定的时间段内向合约发送一定的代币作为质押,同时提供HASH(S),S是参与者选择的随机种子。</p>
<p><strong>第二阶段:收集有效的S。</strong>在第一步完成之后,成功申请HASH(S)的人需要在第一阶段的指定时间内发送随机种子的S到合约。合约将运行HASH并将结果与之前提交的数据进行比较来检查S是否有效。有效S将被保存到种子集合中,用来生成随机数。</p>
<p><strong>第三阶段:计算随机数,退还质押的代币和奖金。</strong>在所有随机种子被成功收集之后,合约通过这些种子生成随机数。同时将来自于消费随机数方提供的利润分配给参与方,并将质押的代币退回参与方。</p>
<p>以上,就从技术上实现了一个基本的区块链抽奖应用。同时利用了公有链的激励机制使得这个模式可以运行。</p>
<p>抽奖DApp从开发到落地只用了两周不到的时间,如此快的开发速度,离不开万云所搭建的“底层链 --> 开发工具 --> 解决方案 -->DApp应用”的一站式解决方案。当然这个应用也比较简单,下面是万云抽奖的一些截图。</p>
<p><img src="/img/bV3QrV?w=1080&h=571" alt="clipboard.png" title="clipboard.png"></p>
<p><strong>结语</strong></p>
<p>作为本次活动的最后一张PPT,我放了一张这样的图。这是2016年两张关于区块链技术的研报。其中两句话在当时说的特别好:“区块链是互联网的诗和远方”、“理论照进现实”。当时大家都看好区块链,认为它是未来有可能会改变整个商业模式至关重要的技术。但当时区块链技术还不成熟,只是停留在想法层面,并没有找到切实落地的场景和方案。<br><img src="/img/bV3QrY?w=838&h=472" alt="clipboard.png" title="clipboard.png"></p>
<p>当时间的车轮驶向2018年以后,我们相信区块链将不再是诗和远方,理论最终也会照进现实,成为时代变迁的标志。而我们身处浪潮之中,所要做的是心无旁骛,努力让区块链实现落地,让所构想的未来图纸成为现实,不只是吟唱诗与远方,而是真正地走到远方。</p>
权威解读 | DPOS委托权益证明 vs POW工作量证明
https://segmentfault.com/a/1190000013231891
2018-02-09T11:21:11+08:00
2018-02-09T11:21:11+08:00
Wancloud万云
https://segmentfault.com/u/wanyunbass
0
<p>本文首发万云Wancloud,翻译:任重远,万向区块链业务专家,参与工信部区块链白皮书撰写</p>
<p>本文摘自“BitShares 101”中关于委托权益证明和工作量证明的讨论。</p>
<p>在这一章节中,我将会向大家解释一下诞生于2014年8月的某项技术。该技术所带来的飞跃将会使得DACs(分布式自治公司)变得更为切实可行。首先,我要警告一下大家这篇文档比较偏技术,如果你对技术并不感兴趣的话可以直接跳过不看。</p>
<p>如果你真正了解清楚这些概念,将会对你未来的投资决策带来相当大的益处。<br>第一个跃入你脑中的问题就是:“如果比特币是世界上第一个DAC,为什么其他DAC不能够模仿它?”</p>
<p>这是一个非常好的问题,为了回答它,我们首先必须理解比特币是如何工作的。<br>一个叫做中本聪的匿名发明家创造了比特币。他把比特币的概念发布在一个小论坛里面。论坛里面有很多能为他提供帮助的人,包括:Dan Larimer.<br>五年后,在数以百万计的人已经学习过比特币代码后,人们发觉比特币的算法在某些领域已经无法达到它所期望到的高效。</p>
<p><strong>我们将解释这些问题以及可能的解决方案</strong>。</p>
<p>我们回顾一下比特币是如何工作的。比特币的共识算法被称为Proof Of Work(POW工作量证明)<br>目前,每10分钟,比特币网络会奖励成功记账的矿工25个比特币。(2017年,由于已经经历了两次半衰,所以其实是奖励12.5个比特币)</p>
<p>让我们来做一些数学题吧。假设每个比特币的价格是500美元。尽管这可能不是比特币的最新现价,但也比较接近2014年的平均价格了,并且这个数字会让计算变得更为简便。<br>所以,每十分钟,接近12500美元价值的比特币会被创造出来,并且支付给矿工作为他们记账服务的费用。每天创造了180万美元的比特币,每年创造6.5亿美元的比特币。这个数字是非常令人震惊的。2014年,价值6亿多美元的比特币被支付给了矿工。<br>所以这些美元从何而来?答案是比特币的持有者,包括你和我,以及任何试图利用比特币机制对抗通货膨胀的人。当这些新的比特币被创造出来以后,比特币的持有者可以选择稍微降价把比特币快速出手(矿工必须考虑到自己的软硬件成本以及电力费用的投入),或者他们认为比特币还有更大的上涨空间,于是仍然持有比特币等到价格合适后放到交易所里出手。</p>
<p><strong>通货膨胀是一个非常复杂的概念,所以我尽量将它简单解释清楚。</strong><br>在2014年,6.5亿的比特币被创造出来。如果新币的买家数量少于预期,供大于求,可能比特币的价格会降低。反过来,如果求大于供,那么比特币会涨价。<br>为了证明这点,我们玩一个游戏。比特币的价格升高一个量级,从500美元一个,变成5000美元一个。<br>所以相应的在2014年,进入市场用来兑换比特币的美元,就不止6.5亿,而是需要65亿。如果达不到这个数量,那比特币的价格就会下降。<br>如果越来越多的人涌入市场购买比特币,那么每10分钟被创造出来的25个比特币的价格就会提升。所以每个人如果想要获得比特币,那他的付出也会相应提高。<br>如果一个新的比特币公式算法能够大幅度降低挖矿所需要的能耗,那么比特币价格将必然会扶摇直上,在我看来,可能会超过10万美元一个。<br>如果有一种方法能够降低比特币网络的花费,而且不会影响网络的安全性,对于比特币而言,这将会一个巨大的胜利,并且使得DACs更有希望早日实现。</p>
<p>所以让我们研究一下比特币每年赚到的6.5亿美元吧。<br>想要运行起比特币网络实际上花费不大,差不多每年几千美元。比特币持有者尝试用每年6.5亿美元购买的其实是去中心化的结构。<br>比特币网络只有当它是去中心化的时候,它才是安全的。<br>越多的矿工进入比特币网络保障其安全,那么比特币网络就越来越变得去中心化。每个矿工都尝试将其变得更健壮。<br>为了比特币去中心化的结构,每年需要花费6.5亿美元,这是否值得?</p>
<p>首先,让我们看看一个趋势。由于比特币网络的规模变大,很明显中心化的挖矿能力变强。<br>以前,任何人都可以使用台式机或者笔记本来挖矿。<br>后来,挖矿变得越来越专业,先是用显卡(GPU),接着用专用的集成电路芯片称为ASICs来挖矿,这些芯片被设计制造的目的,就是比特币挖矿。<br>这也意味着人们需要花费数以千计的硬件来挖矿获取比特币,同时也导致了挖矿的能力越来越集中化。ASICs也使得人们尝试在家里挖矿的方法破灭了,人们在世界范围内建立起庞大的矿场以及专业的设施进行挖矿作业。</p>
<p>在不远的未来,业内人士普遍认为专用的、配备水冷设备的矿场将会诞生,以便通过比特币获得更多的利润。<br>现在,比特币实际上已经变得非常中心化了。只要你能够控制3个矿池,你就能够控制比特币网络超过51%的算力。而四家ASIC芯片制造商只要联合起来,就能够控制未来90%以上的哈希算力。所以人类只要快速搭建矿场到一定的数量级,就可以掌握比特币网络51%的哈希算力。</p>
<p>这投入对于每年6.5亿美元而言真是不值一提。</p>
<p>大家不要理解错了,我这里尝试说明的并不是比特币网络已经完蛋了,或者比特币网络并不够去中心化。我只是陈述事实,比特币的哈希算力的发展情况。<br>如果发明一种算法,并将其运用至比特币网络中,可以同时满足实现网络的更去中心化,或保持原有去中心化水平的同时,降低算力的消耗,势必将会进一步提升比特币的价值。</p>
<p>请大家记住一点,中本聪解决的拜占庭将军问题,只是为了发明一种不可攻破的协议,这一点比特币已经完成了。<br>相比较解决拜占庭将军问题为人类带来的价值,四个芯片制造商、两个矿池以及一堆矿场所带来的麻烦简直就是小菜一碟。<br>我们是否需要等一年、两年、五年还是超过十年,我相信,最终肯定会有一种更为有效的共识算法能够替代现有的POW工作量证明。<br>换个角度来看,当新的算法被发明以后,比特币如何接收它也是非常有意思的一件事。比特币未来很可能就是一种软件,可能只要达成共识以后,比特币就能够进行更新。</p>
<p>比特币就像是一个重达四百磅加密货币的“庞然大物”,其中有数以百万计的VC资金涌入其中。当更有效率的共识算法真正来到以后,比特币能够更新自己的代码,并且保证自己第一位的数字加密货币地位。然而,如果比特币无法接受新的算法,我认为长远来看,它一定会丢失自己的市场份额。</p>
<p><strong>所以如何达成共识?在我看来,想要通过一个未经验证的理论来达成共识是不可能的。我认为这也是山寨币的价值所在。</strong><br>我认为山寨币是需要实验运行的环境。我们能够观测到许多山寨币的失败,总结教训,并找到真正能够成功的案例。这一切都不会威胁到比特币主网的稳定。<br>只要当山寨币经历过一段时间的验证,证明自己是安全并更有效的,当然它的价格也会狂飙,比特币社区的核心成员们才可能考虑到更新比特币网络的共识算法。</p>
<p><strong>所以我提出了这样一个振奋人心的想法:</strong><br>即使我们处于技术的早期,我不认为还需要等5年、10年才能够发明一个更有效的算法。在2014年7月,这个算法已经被发明并展示在世人眼前了。<br>接下来的几年内,监督这个算法将会变得非常有趣。<br>新的算法被称为DPOS委托权益证明, 是由Dan Larimer发明的。<br>根据我的计算,如果这个算法能够成为现在比特币网络的核心算法,将能够只需要现在5%的消耗,即可提供更强大的去中心化保障。这结果也会降低通货膨胀,并提升比特币的价格。<br>DPOS可以每10秒钟就能提供交易的确认。而现在的比特币网络,平均需要花6轮确认时间,每一轮10分钟左右,也就是60分钟才能够确认一笔交易真正发生。10秒钟相比60分钟而言是一个飞跃。<br>DPOS已经投入实际使用,成为比特股的核心共识算法。</p>
<p><strong>比特股在2014年正式发布。</strong><br>DPOS是如何运行的?比特股依靠使用信誉系统以及无摩擦、实时投票的机制,来创造出一个有限信任的团体。团体中的参与成员有权利创造区块,将其加入区块链并禁止非受信的参与方加入其中。这些受信任的参与方通过随机分配的方式决定创造区块,并且每一轮还会被改变。<br>值得一提的是,其中并不需要过多的信任基础。区块的创造者(称为委派见证人)能够创造区块或不创造区块,把交易信息放入区块或不放入区块。但他们无法改变交易的详情,例如交易的发起人、接收人、或者余额。所以他们无法作恶。如果见证人无法创作区块链或者把交易信息放入区块,那么下一位见证人创造出的区块,将会变成两倍大的区块,包括前一位交易者遗漏的交易信息,而确认时间将会延长至20秒而不是10秒。对于网络而言并不会有严重的影响。恶意或者迟到见证人的行为也会被公之于众,那么社区可能将他们简单快速地投票驱逐出去。被驱逐出去的见证人会失去他们记账的权利,以及对应的收入。</p>
<p><strong>比特股网络有着严格的投票机制。每一位比特股的持有者,都能够通过投票,选举出一个拥有101位见证人的理事会来创建区块。</strong><br>101这个数字是随机的。社区能够允许出现更多的见证人,从而使其更为去中心化,但是同样,成本就会上升。同样,也可以降低101个见证人的数量,来降低网络的开销。101只是社区第一个尝试的切入点,并且根据实际情况,可能未来会更改这个数字。<br>因为见证人位置的数量是有限的,见证人实际上也会互相竞争来获得记账的工作。如果见证人主动降低他们获得的收入,那么他们就可以吸引到更多人的投票,同样,保护网络安全的费用将通过见证人之间的竞争维持到一个合理的水平。</p>
<p><strong>比特股持有人会牢牢控制住比特股去中心化的程度,因为他们能够决定谁成为他们的见证人来创建区块。</strong><br>同时,恶意的见证人将会因为自己的作恶行为被快速投票出局。<br>比特币通过通货膨胀的方式支付矿工费用(比特币总量2100万个,总体看是通货紧缩的,但比特币每10分钟被创造出25个,从这个角度看是通货膨胀的)。比特币网络会稀释比特币持有者,比特股能够独立支付101个见证人,从而不会造成稀释。事实上,见证人会主动降低自己的工作来赢得更多投票,剩下的工资会作为股息,支付给所有的比特股持有人。</p>
<p><strong>这个模型中还有非常酷的想法。</strong><br>见证人除了降低自己的工资来获得选票以外,他们同样会因为将见证人工资支付在更多工作而获得选票,例如进行比特股的市场推广、法务。他们的行为,就像其他类型的公司中承担相应工作的雇员一样。<br>所以对于见证人而言,除了维护网络稳定,他们会通过其他方式向比特股的股东创造更多价值。<br>比特币使用点对点的方式实现共识,DPOS有一个已经搭建完成,并且实时变化的股东投票机制。这使得比特股更像一个24小时不间断的股东大会,股东们可以在任意时间通过投票改变公司的组织架构。与比特币相比,比特股网络中投票的权利被牢牢地掌握在股东们的手中,而不是被雇员控制。</p>
<p>比特币的POW算法可能对于一个货币而言是行得通的。我认为DPOS所具有的特征和高效性使得他对于建设DACs是非常合适匹配的。<br>我相信DPOS的发展将会把更多的DACs带入现实社会。对于未来机遇的探讨,也是本书内容中的一部分。</p>
<p>原文链接:<br><a href="https://link.segmentfault.com/?enc=1fE0fG1TNrr2z0cDJFDN5Q%3D%3D.4mecsPWs4ZI7L%2FqT%2BPxUwyCHAtwnhATw7HLdB7skcGlxRDcun2%2FFlHqg3zaD9D84JKycKT1OmICS7OHqCEPZyI6NEayRp7OGlGJHS0tmXUUdBIW8zVwwN02yYMU3G9BA" rel="nofollow">https://bytemaster.github.io/...</a></p>
<p>本文由万云团队编译,如需转载请联系万云官方微信:万云Wancloud</p>
干货 | 手把手教你快速撸一个区块链
https://segmentfault.com/a/1190000013217829
2018-02-08T17:11:36+08:00
2018-02-08T17:11:36+08:00
Wancloud万云
https://segmentfault.com/u/wanyunbass
5
<p>本篇文章由万云团队编译<br>原文链接:<a href="https://link.segmentfault.com/?enc=lCpDbqOOlIhhYKQjG8NbvQ%3D%3D.m5aDGMmIEUSeW3%2FSuky0CmGlFFkBDNZoCGZ746k77n5y5qEX48R5QtIwD2FOBomF75q92d8%2FuckY35uPP9dtWg%3D%3D" rel="nofollow">http://mp.weixin.qq.com/s/5-O...</a><br>如需转载请联系万云官方微信:万云Wancloud</p>
<p>2018年的门刚打开,区块链的火就烧成了火焰山。徐小平放言要拥抱区块链,朋友圈刷屏不止,连上班地铁上都能听到区块链,一夜起,区块链成了茶前饭后的谈资。于是乎,那个经常听到的问题又开始抓耳挠腮:区块链到底是什么鬼?关注的订阅号不停推送“一篇文章让你搞懂区块链”,“三分钟Get区块链”等不尽相同的内容,声音从四面八方聚焦到你耳边。</p>
<p>万云也在思考能为想了解区块链的老铁们做点什么,鉴于已有如此多区块链概念普及文,此次我们不聊枯燥的概念,而是回归区块链“技术”,一步步认真教你获得一个属于自己区块链。放心,只要你稍微懂一点技术,你就可以实现并拥有它。</p>
<p>|| 以下翻译自Daniel van Flymen的《Learn Blockchains by Building One》,有所删改。<br>|| 原文地址:<a href="https://link.segmentfault.com/?enc=Xjk3WnMdtQUqRCcrAqwCVA%3D%3D.L4SGMdMqr8EKKXVUxW6rWegTujO78OeYq7FaxeW3irQo158BErnSm49V8Lpfk8BYeuHZYPImI5mk4dd3QqailnHeM1%2FGyShVqeXKTKbV9to%3D" rel="nofollow">https://hackernoon.com/learn-...</a></p>
<p><strong>前言</strong></p>
<p>概念了解:在开始前你需要知道,区块链是一种按时间将数据区块以顺序相连的方式组合在一起的链式数据结构,并通过密码学来保证其不可篡改和不可伪造的分布式账本。这些区块可以包含交易、文件以及任何你想要的数据,重要的是它们通过哈希链接在一起。<br>目标读者:可以轻松地阅读和编写一些基本的Python,并且对HTTP有一些了解。<br>所需工具:Python 3.6+、Flask、Requests:<br>pip install Flask==0.12.2 requests==2.18.4 <br>除此之外还需安装HTTP工具,如Postman、cURL。<br>源代码地址:<a href="https://link.segmentfault.com/?enc=HQUFI8G3qroGY3uUVzXYHQ%3D%3D.HGxBZmP8yHummqiuhuSOWeaU3IJJwDcuZRZkfA0MR8kyv2KjXIOU%2Bew7sSTsUGXl" rel="nofollow">https://github.com/dvf/blockc...</a></p>
<p>**第一步:建立区块链<br>①实现一个Blockchain类**<br>打开一个你常用的文本编辑器或者IDE,新建一个blockchain.py的python文件,并创建一个Blockchain类,在构造函数中创建两个空的队列,一个用于存储区块链,另一个用于存储交易。下面是Blockchain类的模板代码:</p>
<pre><code>class Blockchain(object):
def __init__(self):
self.chain = []
self.current_transactions = []
def new_block(self):
# Creates a new Block and adds it to the chain
pass
def new_transaction(self):
# Adds a new transaction to the list of transactions
pass
@staticmethod
def hash(block):
# Hashes a Block
pass
@property
def last_block(self):
# Returns the last Block in the chain
pass
</code></pre>
<p>我们所创建的Blockchain类将用来管理链,它会存储交易,并且提供一些方法来帮助添加新的区块到链。下面是详细的实现方法。</p>
<p>每个区块所包含5个基本属性:index,timestamp (in Unix time),交易列表,工作量证明和前一个区块的哈希值。我们来看一个例子:</p>
<pre><code>block = {
'index': 1,
'timestamp': 1506057125.900785,
'transactions': [
{
'sender': "8527147fe1f5426f9dd545de4b27ee00",
'recipient': "a77f5cdfa2934df3954a5c7c7da5df1f",
'amount': 5,
}
],
'proof': 324984774000,
'previous_hash': "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
}
</code></pre>
<p>到这里,我们对于链的概念应该比较清楚了,每个新的区块都会包含上一个区块的哈希值,从而让区块链具有不可篡改的特性。如果攻击者攻击了链中比较靠前的区块,则所有后面的区块将包含不正确的哈希值。如果不能理解,慢慢消化——这是理解区块链技术的核心思想。</p>
<p><strong>②将交易添加到区块</strong></p>
<p>接下来我们实现一个将交易添加到区块的方法,继续看代码:</p>
<pre><code>
class Blockchain(object):
...
def new_transaction(self, sender, recipient, amount):
"""
Creates a new transaction to go into the next mined Block
:param sender: <str> Address of the Sender
:param recipient: <str> Address of the Recipient
:param amount: <int> Amount
:return: <int> The index of the Block that will hold this transaction
"""
self.current_transactions.append({
'sender': sender,
'recipient': recipient,
'amount': amount,
})
return self.last_block['index'] + 1
</code></pre>
<p>在new_transaction()方法中向列表中添加一笔交易之后,它返回值是本次交易的index,该index会被添加到下一个待挖掘区块,后面在用户提交交易时也会用到。</p>
<p><strong>③建一个新的区块</strong></p>
<p>当Blockchain被实例化后,我们需要创建一个创世区块,同时为我们的创世区块添加一个工作量证明,这是挖矿的结果,我们稍后会详细讨论挖矿。</p>
<p>除了创建创世区块的代码,我们还需要补充new_block(),new_transaction()和hash()的方法:</p>
<pre><code>import hashlib
import json
from time import time
class Blockchain(object):
def __init__(self):
self.current_transactions = []
self.chain = []
# Create the genesis block
self.new_block(previous_hash=1, proof=100)
def new_block(self, proof, previous_hash=None):
"""
Create a new Block in the Blockchain
:param proof: <int> The proof given by the Proof of Work algorithm
:param previous_hash: (Optional) <str> Hash of previous Block
:return: <dict> New Block
"""
block = {
'index': len(self.chain) + 1,
'timestamp': time(),
'transactions': self.current_transactions,
'proof': proof,
'previous_hash': previous_hash or self.hash(self.chain[-1]),
}
# Reset the current list of transactions
self.current_transactions = []
self.chain.append(block)
return block
def new_transaction(self, sender, recipient, amount):
"""
Creates a new transaction to go into the next mined Block
:param sender: <str> Address of the Sender
:param recipient: <str> Address of the Recipient
:param amount: <int> Amount
:return: <int> The index of the Block that will hold this transaction
"""
self.current_transactions.append({
'sender': sender,
'recipient': recipient,
'amount': amount,
})
return self.last_block['index'] + 1
@property
def last_block(self):
return self.chain[-1]
@staticmethod
def hash(block):
"""
Creates a SHA-256 hash of a Block
:param block: <dict> Block
:return: <str>
"""
# We must make sure that the Dictionary is Ordered, or we'll have inconsistent hashes
block_string = json.dumps(block, sort_keys=True).encode()
return hashlib.sha256(block_string).hexdigest()
</code></pre>
<p>到此,我们的区块链已经基本上实现了雏形。这时候,你肯定想知道新区块是怎么被挖出来的,也就是我们通常所说的“挖矿”。</p>
<p><strong>④什么是工作量证明?</strong></p>
<p>想了解什么是“挖矿”,就必须理解工作量证明(POW)是什么。区块链上每一个新的区块都来自于工作量证明(POW),POW的目标是计算出一串解决问题的数字,这个结果众所周知是很难计算的,但却十分容易验证,因为网络上的任何人都能够验证这个结果,这是“工作量证明”背后的核心思想。</p>
<p>我们来看一个非常简单的例子帮助理解:</p>
<p>假设整数X乘以另一个整数y的哈希值必须以0结尾,hash(x * y) = ac23dc...0. 设x = 5.求y。我们用Python来实现:</p>
<pre><code>from hashlib import sha256
x = 5
y = 0 # We don't know what y should be yet...
while sha256(f'{x*y}'.encode()).hexdigest()[-1] != "0":
y += 1
print(f'The solution is y = {y}')
</code></pre>
<p>得到的答案是当y = 21,哈希值的结尾为0:<br>hash(5 * 21) = 1253e9373e...5e3600155e860</p>
<p>在比特币中,工作证明算法被称为Hashcash,这和我们上面所举的例子差不多,结果难于发现却易于校验。Hashcash是矿工为了创建一个新区块而争相计算的问题,计算难度通常取决于字符串中搜索的字符数,通常也会花费一定的时间才能计算得到,最终计算出来的矿工们会通过交易获得一定数量的比特币作为奖励。</p>
<p><strong>⑤实现一个基本的工作量证明</strong></p>
<p>首先我们为Blockchain类实现一个类似的算法:</p>
<p>规则:找到一个数字p,使得它与前一个区块的 proof 拼接成的字符串的 Hash 值以 4 个零开头。</p>
<pre><code>import hashlib
import json
from time import time
from uuid import uuid4
class Blockchain(object):
...
def proof_of_work(self, last_proof):
"""
Simple Proof of Work Algorithm:
- Find a number p' such that hash(pp') contains leading 4 zeroes, where p is the previous p'
- p is the previous proof, and p' is the new proof
:param last_proof: <int>
:return: <int>
"""
proof = 0
while self.valid_proof(last_proof, proof) is False:
proof += 1
return proof
@staticmethod
def valid_proof(last_proof, proof):
"""
Validates the Proof: Does hash(last_proof, proof) contain 4 leading zeroes?
:param last_proof: <int> Previous Proof
:param proof: <int> Current Proof
:return: <bool> True if correct, False if not.
"""
guess = f'{last_proof}{proof}'.encode()
guess_hash = hashlib.sha256(guess).hexdigest()
return guess_hash[:4] == "0000"
</code></pre>
<p>通过修改前导零的数量,可以调整算法的难度,但是4个零完全足够了。你会发现,每当增加一个前导零,找到一个对应的解决方案与所需的时间之间会产生巨大的差异。</p>
<p>进行到这里,我们的Blockchain类已经基本完成,接下来我们实现HTTP服务进行交互。</p>
<p><strong>第二步:区块链API</strong><br>我们将使用Python Flask框架,Flask是一个轻量级的Web应用框架,这使我们可以通过web服务来调用Blockchian类。</p>
<p><strong>①创建三个API:</strong></p>
<p>•/ transactions / new为区块创建一个新的交易</p>
<p>•/mine告诉我们的服务器开采新的区块。</p>
<p>•/chain返回整个区块链。</p>
<p><strong>②使用Flask</strong></p>
<p>我们的“服务器”将基于Flask框架来实现区块链网络中的一个节点。 我们来添加一些模板代码:</p>
<pre><code>import hashlib
import json
from textwrap import dedent
from time import time
from uuid import uuid4
from flask import Flask
class Blockchain(object):
...
# Instantiate our Node
app = Flask(__name__)
# Generate a globally unique address for this node
node_identifier = str(uuid4()).replace('-', '')
# Instantiate the Blockchain
blockchain = Blockchain()
@app.route('/mine', methods=['GET'])
def mine():
return "We'll mine a new Block"
@app.route('/transactions/new', methods=['POST'])
def new_transaction():
return "We'll add a new transaction"
@app.route('/chain', methods=['GET'])
def full_chain():
response = {
'chain': blockchain.chain,
'length': len(blockchain.chain),
}
return jsonify(response), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
</code></pre>
<p>以下是对上面添加的内容的进行简要说明:</p>
<pre><code> Line15:实例化Flask web服务节点。
Line18:为我们的服务节点创建一个随机的名称。
Line21:实例化Blockchain类。
Line24-26:创建一个路由为/mine的GET请求的,调用后端Blockchain的new block方法。
Line28-30:创建一个路由为/transactions/new的POST请求,将数据发送给后端Blockchina的new transaction方法。
Line32-38:创建一个路由为/chain的GET请求,将返回整个链。
Line40-41:在端口5000上运行服务器。
</code></pre>
<p><strong>③实现交易</strong></p>
<p>下面是用户发起交易时发送到服务器的请求:</p>
<pre><code>{
"sender": "my address",
"recipient": "someone else's address",
"amount": 5
}
</code></pre>
<p>由于我们已经有了将交易添加到区块的方法,接下去就十分容易了。</p>
<p>下面我们来实现添加交易的函数:</p>
<pre><code>import hashlib
import json
from textwrap import dedent
from time import time
from uuid import uuid4
from flask import Flask, jsonify, request
...
@app.route('/transactions/new', methods=['POST'])
def new_transaction():
values = request.get_json()
# Check that the required fields are in the POST'ed data
required = ['sender', 'recipient', 'amount']
if not all(k in values for k in required):
return 'Missing values', 400
# Create a new Transaction
index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount'])
response = {'message': f'Transaction will be added to Block {index}'}
return jsonify(response), 201
</code></pre>
<p><strong>④实现挖矿</strong></p>
<p>我们的挖矿方法是魔法发生的地方。它十分容易,只做三件事情:计算工作量证明;通过新增一笔交易奖励矿工一定数量的比特币;创建新的区块并将其添加到链中来。</p>
<pre><code>import hashlib
import json
from time import time
from uuid import uuid4
from flask import Flask, jsonify, request
...
@app.route('/mine', methods=['GET'])
def mine():
# We run the proof of work algorithm to get the next proof...
last_block = blockchain.last_block
last_proof = last_block['proof']
proof = blockchain.proof_of_work(last_proof)
# We must receive a reward for finding the proof.
# The sender is "0" to signify that this node has mined a new coin.
blockchain.new_transaction(
sender="0",
recipient=node_identifier,
amount=1,
)
# Forge the new Block by adding it to the chain
previous_hash = blockchain.hash(last_block)
block = blockchain.new_block(proof, previous_hash)
response = {
'message': "New Block Forged",
'index': block['index'],
'transactions': block['transactions'],
'proof': block['proof'],
'previous_hash': block['previous_hash'],
}
return jsonify(response), 200
</code></pre>
<p>需要注意的是,开采块的交易接收者是我们自己服务器节点的地址,我们在这里所做的大部分工作只是与Blockchain类进行交互,基于以上我们区块链已经完成了,接下来开始交互演示。</p>
<p><strong>第三步:交互演示</strong><br>您可以使用cURL或Postman与API进行交互。</p>
<p>启动服务器:</p>
<pre><code>$ python blockchain.py
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
</code></pre>
<p>尝试通过向http:// localhost:5000 / mine发出GET请求来挖掘区块: </p>
<p><img src="/img/bV3CFt?w=800&h=573" alt="clipboard.png" title="clipboard.png"></p>
<p>创建一个新的交易,向<a href="https://link.segmentfault.com/?enc=JcazfDwPCSlfbLoTX8%2BnPQ%3D%3D.7M24K7njaOj0tkHNLhdGelQcVEJMP4M75ozCAb5AY7c%3D" rel="nofollow">http://localhost</a>:5000/transactions/new发出一个POST请求:</p>
<p><img src="/img/bV3CFD?w=639&h=411" alt="clipboard.png" title="clipboard.png"></p>
<p>也可以使用cURL发送请求:</p>
<pre><code>$ curl -X POST -H "Content-Type: application/json" -d '{
"sender": "d4ee26eee15148ee92c6cd394edd974e",
"recipient": "someone-other-address",
"amount": 5
}' "http://localhost:5000/transactions/new"
</code></pre>
<p>以上仅为交互演示的示例,你可以在你自己所完成的区块链上进行更多尝试。</p>
<p><strong>第四步:共识机制</strong><br>我们有一个基本的区块链可以进行交易和挖矿,但其实区块链更重要的意义在于它们是分布式的。那么我们需要确保所有的节点都运行在同一条链上,这就是回归到了共识问题,如果要满足在网络上有多个节点并且不断增加,我们必须要实现共识算法。</p>
<p><strong>①注册新的节点</strong></p>
<p>在实现共识算法之前,需要找到一种方式让网络上的节点知道其相邻的节点,每个节点都需要存储网络上其他节点的记录。因此,我们需要新增几个方法来帮助实现:</p>
<p>1./nodes/register接受URL形式的新节点列表。</p>
<ol><li>/ nodes / resolve来执行我们的共识算法,它可以解决任何冲突,确保节点具有正确的链。</li></ol>
<p> 下面我们将修改Blockchain的构造函数以提供注册节点的方法:</p>
<pre><code>...
from urllib.parse import urlparse
...
class Blockchain(object):
def __init__(self):
...
self.nodes = set()
...
def register_node(self, address):
"""
Add a new node to the list of nodes
:param address: <str> Address of node. Eg. 'http://192.168.0.5:5000'
:return: None
"""
parsed_url = urlparse(address)
self.nodes.add(parsed_url.netloc)
</code></pre>
<p>注意,我们使用set()集合来保存节点列表,这是确保新节点的添加是幂等的简便方法,这意味着无论我们添加特定节点多少次,它都只会出现一次。</p>
<p><strong>②实现共识算法</strong></p>
<p>如前所述,当一个节点与另一个节点有不同时会发生冲突,为了解决这个问题,我们遵循取最长链原则,通过使用此算法,让网络中的节点间达成共识。</p>
<pre><code>...
import requests
class Blockchain(object)
...
def valid_chain(self, chain):
"""
Determine if a given blockchain is valid
:param chain: <list> A blockchain
:return: <bool> True if valid, False if not
"""
last_block = chain[0]
current_index = 1
while current_index < len(chain):
block = chain[current_index]
print(f'{last_block}')
print(f'{block}')
print("\n-----------\n")
# Check that the hash of the block is correct
if block['previous_hash'] != self.hash(last_block):
return False
# Check that the Proof of Work is correct
if not self.valid_proof(last_block['proof'], block['proof']):
return False
last_block = block
current_index += 1
return True
def resolve_conflicts(self):
"""
This is our Consensus Algorithm, it resolves conflicts
by replacing our chain with the longest one in the network.
:return: <bool> True if our chain was replaced, False if not
"""
neighbours = self.nodes
new_chain = None
# We're only looking for chains longer than ours
max_length = len(self.chain)
# Grab and verify the chains from all the nodes in our network
for node in neighbours:
response = requests.get(f'http://{node}/chain')
if response.status_code == 200:
length = response.json()['length']
chain = response.json()['chain']
# Check if the length is longer and the chain is valid
if length > max_length and self.valid_chain(chain):
max_length = length
new_chain = chain
# Replace our chain if we discovered a new, valid chain longer than ours
if new_chain:
self.chain = new_chain
return True
return False
</code></pre>
<p>valid_chain()负责检查一个链是否有效,具体方法是循环读取每个区块并验证哈希和证明。</p>
<p>resolve_conflicts()负责循环读取所有相邻节点,获取它们的链并使用上面的方法验证它们的有效性。如果找到了一个更长的有效链,则取代我们当前的链。</p>
<p>我们将两个方法注册到我们的API中,一个用于添加相邻节点,另一个用于解决冲突:</p>
<pre><code>@app.route('/nodes/register', methods=['POST'])
def register_nodes():
values = request.get_json()
nodes = values.get('nodes')
if nodes is None:
return "Error: Please supply a valid list of nodes", 400
for node in nodes:
blockchain.register_node(node)
response = {
'message': 'New nodes have been added',
'total_nodes': list(blockchain.nodes),
}
return jsonify(response), 201
@app.route('/nodes/resolve', methods=['GET'])
def consensus():
replaced = blockchain.resolve_conflicts()
if replaced:
response = {
'message': 'Our chain was replaced',
'new_chain': blockchain.chain
}
else:
response = {
'message': 'Our chain is authoritative',
'chain': blockchain.chain
}
return jsonify(response), 200
</code></pre>
<p>最后,如果你愿意的话可以开启另一台机器,并在你的网络上运转不同的节点。或者使用同一台机器上的不同端口启动进程。我在我的机器的不同端口创建另外一个节点,并将其注册到当前区块链网络中。 因此,我有两个节点:http:// localhost:5000和http:// localhost:5001。</p>
<p><img src="/img/bV3CHF?w=654&h=349" alt="clipboard.png" title="clipboard.png"></p>
<p>为了确保链更长,我在节点2上挖掘了一些新的区块。 之后,我在节点1上调用GET / nodes / resolve,此处的链已经被共识算法计算后的得到的新链所替代。</p>
<p><img src="/img/bV3CHT?w=662&h=402" alt="clipboard.png" title="clipboard.png"></p>
<p>现在,你可以邀请一些朋友来一起测试你的区块链了。</p>
<p>本文教程到此结束,那么,属于你自己的区块链撸好了吗?别忘了分享给身边同为程序员的朋友,一起来撸区块链!</p>
<p>本篇文章由万云团队编译,如需转载请联系万云官方微信:万云Wancloud</p>
干货 | 以太坊Mist负责人教你建立无服务器应用
https://segmentfault.com/a/1190000012906006
2018-01-19T15:07:01+08:00
2018-01-19T15:07:01+08:00
Wancloud万云
https://segmentfault.com/u/wanyunbass
1
<p>作者:Alex Van de Sande<br>译者:王建/蔡佳慧<br>译者介绍:<br> 王建:万云平台区块链技术专家,拥有多年应用系统架构经验,目前在区块链落地方面进行积极探索<br> 蔡佳慧:万云平台实习生,区块链技术爱好者,英国帝国理工学院数学专业在读</p>
<p><strong>这篇教程是由以太坊Mist浏览器的负责人撰写,完整地介绍了如何开发一个标准的DApp。</strong></p>
<p><strong>以下是正文:</strong></p>
<p>以太坊并不是那种需要一个STEM文凭(1)才能理解的高深莫测的智能合约应用建立平台,它的目标其实是成为万维网中各种应用架构的支柱。在这篇文章里,我们尝试去阐述如何实现这个目标,并提供一些基本例子来展示如何开始构建一个去中心化的应用。</p>
<p>译者注:</p>
<p>(1)STEM文凭,指:科学-science,科技-technology,工程-engineering,及数学-mathematics相关文凭。</p>
<p><strong>目标读者</strong></p>
<p>这篇文章面向有以下背景的读者:对于Web技术有基本了解,并知道如何构建一个简单的基于javascript和html的应用。同时,希望使用这些技能为以太坊生态系统构建应用。</p>
<p><strong>没有服务器,应用是如何运行的</strong></p>
<p>当前,Web应用中的服务器所做的工作已经远超当初的设想。除了提供静态网页,它们还保管私有信息,处理用户验证,同时还提供复杂数据分析与保存。而用户计算机(在Web技术刚被发明的年代,这种设备会被认为是超级计算机)所做的仅仅是加载信息,并展示给用户而已。</p>
<p><img src="/img/bV2jo4?w=1280&h=553" alt="clipboard.png" title="clipboard.png"></p>
<p>Current server models</p>
<p>与此不同的是,更为去中心化的系统结构则会允许一种更加模块化的处理方式。在这种方式中,不同的机器与不同的协议将会处理特定的任务,有些属于用户方面,而也有些属于配置于点对点网络中的专用机器方面。因此所有的数据逻辑(什么会被储存,谁会去储存,如何解决冲突等)是由区块链上的智能合约解决的,静态文档由Swarm提供,同时实时通信在Whisper上进行。用户设备保留用户认证信息并运行程序界面。</p>
<p>几乎没有单节点保留大量未加密数据,这么做将会降低数据泄漏与攻击的危险。同时,通过将其分散于全网络,也可以降低应用的加载与花销成本。由于所有这些协议都是去中心化的,任何人都可以连接到网络并开始提供特定服务:比如说,如果用户在一个功能强大的笔记本电脑上浏览,这台电脑也可以向网络邻居们提供静态文件。</p>
<p><img src="/img/bV2jph?w=1280&h=539" alt="clipboard.png" title="clipboard.png"></p>
<p>Decentralised Server models</p>
<p>一个去中心化的系统结构同时鼓励创新:由于交互界面脱离于数据,任何人都可以为同一个应用提出一个全新的用户界面,创建一个更富生机与竞争力的生态系统。可以说,Twitter历史上最具趣味性及创新力的时期之一便是它作为中央数据中心提供服务,同时任何人都可以创建他们自己的Twitter应用。</p>
<p><strong>观察它如何运作</strong></p>
<p>如果你想在学习这个应用之前实验它,我们推荐你下载Mist并阅读我们关于如何安装应用并运行的入门教程(下载链接:<a href="https://link.segmentfault.com/?enc=s2NCRL3vj7LELWznYY9uPA%3D%3D.gwU3gE6Cd816zGfBTbSLDKqC9buCSW3%2B7pgiITqjp9gaxA8ZjL0o0dIfsJfiHL7lB6NcncpDPf1J1ubfQX1fNg%3D%3D" rel="nofollow">https://github.com/ethereum/m...</a>)。如果你只是想要看一看完整的应用,你可以直接从Github上将其下载下来(下载链接:<a href="https://link.segmentfault.com/?enc=g60LXLuqWNm%2BAbyNzBxgXA%3D%3D.%2Blx%2FmmzoW5%2BbZk84qMc36Jd7mxcKK3Q6Vn8YcgG0fj%2Bz0jgOU1DrjoiRuqEGCgts" rel="nofollow">https://github.com/ethereum/s...</a>)。</p>
<p><img src="/img/bV2jpA?w=1280&h=875" alt="clipboard.png" title="clipboard.png"></p>
<p>Stake Voice running on the Mist Browser</p>
<p><strong>我们现在上手操作</strong></p>
<p>我们将会建立一个叫做“Stake Voice”的非常简单的应用。其主旨是允许以太币投注人对任何他们想投的事情进行投票,同时这个应用将会计算所有同意与不同意这个陈述的以太币总和。 </p>
<p>下面代码是这个应用里用Solidity语言编写合约,Solidity是一种类似于javascript的语言,非常简单:<br><img src="/img/bV2jug?w=759&h=277" alt="clipboard.png" title="clipboard.png"><br>第一行建立了合约名称,同时第二行创建了一个命名为“LogVote”的事件,它将会在日志文件中记录以下内容:</p>
<p>将会被投票的提案的哈希值<br>投票者是同意还是反对提案<br>投票者的地址</p>
<p>函数“vote”接着会启动日志,应用程序稍后会计数。它同时会检查确保没有意外发送的以太币。当任何以太币被存入智能合约时,“匿名”函数会被执行,并会自动拒绝接收以太币。</p>
<p>如果你想要学习关于Solidity更多的编程内容,我们推荐你从以太网solidity教程( <a href="https://link.segmentfault.com/?enc=RDuAywp02eJXuAd7ZQLDYw%3D%3D.IUHbFf6Jx2ho%2BnButc8UmjkvfDG64j1zwz9C6714Dno%3D" rel="nofollow">https://ethereum.org/dao</a>)开始,阅读官方文档页面( <a href="https://link.segmentfault.com/?enc=I%2B7dizghZ2KQ24c7xQFNjw%3D%3D.rt55rHnGjd%2BSMvfjFxcJdGbxJ%2BuwX7yG4dg3z7N7okt6Odggi7LthpAVZjPS4dqY" rel="nofollow">https://solidity.readthedocs....</a>)并在你的浏览器上尝试在线编译器( <a href="https://link.segmentfault.com/?enc=SjFXKObwjUQJE%2FD3E%2FSjpQ%3D%3D.eBtt%2BENWo2AMuiCrrfD9qyxcEfLpuEHjOPp%2B7oGwhqPJwiMiP7Z58PVXwLu9STfAaeZ%2Be%2BSwt58bzZXavyVcI0PwRFv0oxxbjgiQruQlI2M%3D" rel="nofollow">https://ethereum.github.io/br...</a>)。</p>
<p>大致上就是如此了:你选择一个哈希值,选择一方然后运行Vote()。所以这又如何转化成一个投票应用?</p>
<p><strong>无服务器架构</strong></p>
<p>遵循KISS原则,我们正在制作尽量小却仍然可使用的产品。这意味着我们不会使用数据库来储存提案,也不会使用普通javascript与纯粹html之外的功能。</p>
<p>因此,我们将使用应用本身的URL来保存提案文本,并且我们会使用URL来向用户展示提案内容,再生成一个用来检测投票的哈希值。用户可以使用社交媒体来分享他们想要辩论的提案,或者直接使用链接。<br><img src="/img/bV2juF?w=758&h=418" alt="clipboard.png" title="clipboard.png"></p>
<p><strong>从基础开始</strong></p>
<p>拿出你最喜欢的html框架,并在你本地机器上建立一个简单网站,然后在Mist上打开它。Mist上所有的页面都可以访问一个名叫web3的javascript对象,这也是你的主要工作区域。我们要做的第一件事就是检查web3是否存在:<br><img src="/img/bV2juG?w=758&h=250" alt="clipboard.png" title="clipboard.png"><br>一些应用开发者也许会想要去加载他们自己的web3对象,以保证向前的兼容性。要做到这些,只需要在</body>标签前加上:<br><img src="/img/bV2juT?w=758&h=110" alt="clipboard.png" title="clipboard.png"><br>然后在初始函数上加上这个去加载你自定义的web3提供方(provider):<br><img src="/img/bV2ju2?w=758&h=359" alt="clipboard.png" title="clipboard.png"></p>
<p><strong>从区块链上加载信息</strong></p>
<p>你检查到你连接到区块链网络上了吗?但是到底是哪一个区块链网络呢?是主体(main)以太坊网络吗?也许是一个测试网络(testnet)或者是一个私有(private)网络?或许未来某一天,你会分叉(fork)一个以太坊源码,构建一个属于你自己的全新品牌区块链。检查网络的最好办法是查看你想要加载的合约地址中是否包含了代码。</p>
<p>此外,为了执行一个合约你需要知道两个基本事项:它的地址和ABI(ABI是使用json编码的接口文档)。<br><img src="/img/bV2jvm?w=756&h=191" alt="clipboard.png" title="clipboard.png"><br>现在有了上面这些内容,你就能够在启动函数上检测合约是否存在了:<br><img src="/img/bV2jvt?w=756&h=219" alt="clipboard.png" title="clipboard.png"><br>你甚至可以递归地运行这条命令,尝试用不同的地址去连接(假定你测试网络上)。一旦你找到你的合约,你就可以在这里加载它了:<br><img src="/img/bV2jvL?w=756&h=217" alt="clipboard.png" title="clipboard.png"><br>你用web3对象创建的javascript对象,能够直接在浏览器中执行所有以太坊命令。如果你仅仅想要加载一个合同的实例,你甚至可以在一行代码里做到:<br><img src="/img/bV2jvV?w=756&h=110" alt="clipboard.png" title="clipboard.png"><br>用户鉴别</p>
<p>获取用户账户披露了这个用户的大量信息:账户余额中有多少以太币和其他代币,以及其交易历史。因此,默认让所有应用获取这一信息将会创建一个超级cookie,由于对隐私的侵犯,这是不可以接收的。另一方面,要求用户为每一个网站创建一个带有登录信息的账户,这不仅对用户来说是一个痛苦,而且把你的隐私交给第三方来掌控,这种方式将会让个第三方变成一个可被黑客随意掘取的巨大蜂蜜罐。</p>
<p>面对这一困境,多数用户选择将自己个人信息及验证信息交由一个几十亿美元公司处理。隐私权不应该为了取得实用性而妥协:用户应该在掌控他们的个人信息的同时,能够轻松地验证身份信息以登入任何应用。</p>
<p>使用Mist,应用不拥有关于用户的信息,除非用户决定公布其自身信息给应用。当你想要查询自己的账户信息,你应该调用getAccounts函数:<br><img src="/img/bV2jv7?w=758&h=194" alt="clipboard.png" title="clipboard.png"></p>
<p>目前,返回对象是一个数组,其中包含了用户拥有本地访问权限的简单账户,但是在未来,其中还会包含用户用于自身识别的智能合约账户。这将会使得用户拥有权限来访问目前只供给集中式验证器(centralized authenticators)的特性,比如双重身份验证或者云备份。用户同样将会拥有权限来访问未来针对智能合约的改进,比如在你遗失密钥的时候允许一些受信任的朋友来给你访问账户的权限,或者对于不活动账户行使自动继承权。</p>
<p>每一个未来的以太坊浏览器将会解决用户如何向应用辨别自身的问题。在Mist中我们由两种方式:要么用户可以通过敲击“connect”按键(目前仅叫做“no accounts”按键)来启动它,或者应用可以通过调用“requestAccount”api来要求身份验证。</p>
<p>注意:这个列表上的账户仅仅只是用户声明拥有密钥的账户,但是用户并没有提供证明,因此你可以展示一个不同的界面,但是不要给用户发送任何与账户有关的加密信息。如果需要用户证明他们的身份,你需要让用户对信息签名,同时Mist也会在未来支持它,请注意这会要求用户做一个额外步骤--输入密码。所以只在必要的时候,你才会需要用户签名。</p>
<p><strong>投票</strong></p>
<p>一旦你有了合约对象,投票就仅仅只是从javascript中调用它。调用函数会下面这段代码处提供操作器将会解决用户们如何向应用辨别会包含用户们弹出一个Mist交易面板,用户可以在面板上检查交易内容,并输入密码。</p>
<p>因此,首先我们要创建两个可以调用投票函数的可点击对象:<br><img src="/img/bV2jwf?w=755&h=135" alt="clipboard.png" title="clipboard.png"><br>注意我们调用的一个函数参数为true,另一个则为false。投票函数可以像下面这么简单:<br><img src="/img/bV2jwj?w=757&h=139" alt="clipboard.png" title="clipboard.png"><br>“Ethervote”是我们之前创建的对象,并且“vote”是它函数中的一个,对应着合约函数的一个:<br><img src="/img/bV2jwl?w=758&h=85" alt="clipboard.png" title="clipboard.png"><br>根据函数的要求,我们需要传入两个参数,并增加包含交易信息的第三个对象,比如:谁发送了此交易,以及两个可选项:包含多少gas或者购买gas的费用。</p>
<p>由此,这将会创建一个面板,以要求用户确认交易——但是多数情况下它会返回一个错误信息,因为目前web3.eth.accounts对象默认是一个空数组,所以你需要检查其是否为空,若为空,则从用户处请求账户:<br><img src="/img/bV2jwp?w=759&h=586" alt="clipboard.png" title="clipboard.png"><br>你应该只在用户初始化一项操作的情况下请求账户:无中生有地显示一项交易只会理所当然地激怒用户,更可能使他/她关闭你的应用。如果我们观察到应用对于这一功能的滥用行为,我们可以对于何时弹出警报施加更为严格的要求。</p>
<p><strong>查看合约</strong></p>
<p>最后,为了累计所有的投票,我们需要查看合约事件,以及投票内容。为了完成这些工作,在我们实例化“ethervote”后我们需要去运行这个函数一次来查看事件:<br><img src="/img/bV2jwx?w=758&h=306" alt="clipboard.png" title="clipboard.png"></p>
<p>上述代码会从第180万(这是合约被上传的时间点)高度读取所有的区块,没读取一个区块时,都会执行receivedEvent()函数;并且,每产生一个新区块时,这个函数就会被再次触发,所以你不需要连续调用。那么,这个函数到底有什么用呢?<br><img src="/img/bV2jwD?w=758&h=220" alt="clipboard.png" title="clipboard.png"></p>
<p>从初始solidity合约中,你可以看到LogVote带有三个参数,proposalHash,Pro和Addr:<br><img src="/img/bV2jwN?w=758&h=85" alt="clipboard.png" title="clipboard.png"></p>
<p>所以这个函数的作用是它会使用函数web3.eth.getBalance来检查投票地址当下的以太币余额。所有的余额都会返回以wei为单位的数字,也就是一个以太币的1/1000000000000000000,这对于这个特定的应用并非非常的有用,所以我们也使用另一个包含的web3函数来将其转换为任何我们需要的以太币单位。这里,我们会使用finney,也就是一个以太币的一千分之一。</p>
<p>接下来,这个函数将会保存投票者的余额及位置于一个以用户地址为Key的Map上。所以如果有人投了两次票,只有他们最后的意见会被保留。</p>
<p>另外我们还能鉴别用户,并展示他们是否投票。<br><img src="/img/bV2jwZ?w=759&h=331" alt="clipboard.png" title="clipboard.png"></p>
<p>累积票数</p>
<p>最后,我们应该加入一个独立的函数来计算票数的总数:<br><img src="/img/bV2jxe?w=756&h=84" alt="clipboard.png" title="clipboard.png"></p>
<p>为什么我们会想要通过一个独立的函数来累积票数呢?因为票数权重是建立在每一个账户的当前余额之上的,我们应该对于每一个新区块重新计算余额,即使我们并没有收到新的事件。为了做到这个,你可以增加这个函数,使它每收到一个新区块时就会自动执行;<br><img src="/img/bV2jxT?w=758&h=193" alt="clipboard.png" title="clipboard.png"></p>
<p>最后,直到加到最终的总数为止。我们之前已经在同步模式下使用了eth.getBalance,在此模式下,应用会等待前一个操作的结果再继续。此处,因为我们可以对于每一个区块调用大量操作,我们将会在异步模式下运行它:你可以异步调用getBalance函数,等到节点返回后,再进行票数统计。<br><img src="/img/bV2jx5?w=756&h=528" alt="clipboard.png" title="clipboard.png"></p>
<p>就像你根据代码所作的一样,应用所做的就是在循环投票地址中的每一个并得到它们的余额,只要它返回结果,它会将其加到支持或反对阵营中,并计算总和。</p>
<p><strong>额外的好处</strong></p>
<p>一些附加说明:当没有事件时,什么也不会被返回,并且投票也不会被计算,所以你应该对依赖于区块链上事件的所有函数增加一个超时函数。<br><img src="/img/bV2jyd?w=760&h=137" alt="clipboard.png" title="clipboard.png"></p>
<p>现在你可以随意地使用所有你现有的网络开发工具来施展你想要的任何魔法。使用数字来构建一个漂亮的3D可视化效果或者关联你最爱的社交媒体来分享最佳问题。</p>
<p>Mist也尝试提供一些基本的导览,以及UI方式来简化你的代码。如果你想要你的应用不包含header并且占据mist应用的所有高度,只要将这个加入到你的<head>标签:<br><img src="/img/bV2jyo?w=758&h=86" alt="clipboard.png" title="clipboard.png"></p>
<p>并且如果你想要使用Mist自身来导览?你的应用,你可以使用Mist.menu对象:<br><img src="/img/bV2jyw?w=758&h=361" alt="clipboard.png" title="clipboard.png"></p>
<p>以太坊强大的一点是你可以在不需要许可的情况下,扩展这项简单的合约功能:你可以把每个额外的功能放到一个独立的合约里,让每个独立合约的功能简单且可以更轻松的调试。这也意味着别人可以在他们自己的应用中使用你创建的合约并增加新的功能。同时,所有的应用使用相同的数据和后端。</p>
<p>你可以在Github上(<a href="https://link.segmentfault.com/?enc=AwYorWjD09ux3x%2FxEtHrOw%3D%3D.F0DM%2FK1Ghbxf5zX0pldyu0kpUGp7WtlKVDOn5XmV7wScD2a3zF%2FuDB9Hhc16hFob" rel="nofollow">https://github.com/ethereum/s...</a>)在线体验这个应用,但是这不是权威的规范,只是它众多可能接口中的一个。同一个应用也可能在你的电脑上或一个IPFS网络( <a href="https://link.segmentfault.com/?enc=Fo08qRLcHcVhk2cAcD8GLw%3D%3D.aCBizt%2BIwnrVQ6gM%2Fzd4SA%3D%3D" rel="nofollow">https://ipfs.io</a>)中作为一个本地html文档工作,并且在未来它可以使用Swarm技术,在Mist里直接下载应用。</p>
<p><strong>关于如何尝试的一些建议:</strong></p>
<p>创建当前可用发言列表。任何人都可以通过查看提案文本的sha3来检查它们,所以你不需要任何许可。</p>
<p>创建线性化的评论,在这里用户可以回复评论并通过投票来表达支持或反对,就像一个基于Reddit的去中心化的投票制。</p>
<p>除了使用以太币余额,你还可以使用一些其它的以太坊代币,比如TheDAO或者Digix Gold来给你的问题加权。因为所有合约保存的原始位置是发送方,你可以检查全部发送方的余额。或者也许你可以基于信誉(reputation)、甚至是业力(karma)或者其它方式来创建你自己的货币。</p>
<p><strong>本文为万云BasS编译,未经允许不可转载</strong>。</p>