关于以太坊:Swarm-BZZ节点和矿机该如何选

2021年2月15日,以太坊(官网)启动的存储和通信基础架构Swarm向曾经在测试网络上运行的Bee节点空投了100万个BZZ。 历经了3个月的空投测试,演绎一下目前常见的几种节点挖机: 1、家用电脑搭建节点挖机,5.3版本晚期可行,4月下旬后很难再出票; 2、物理矿机(服务器),办公室企业级光纤搭建,只有一个企业固定IP可用,5月中旬后很难再出票; 3、物理矿机(服务器)IDC机房搭建,单台物理机上几十上百个节点共享一个IP,5.3版本临时还能挖,出票效率偏低,6.2版本有待考验; 4、国内云搭建,一个节点一个IP,带宽老本过高,不倡议驳回; 5、海内云搭建,一个节点一个IP,5.3版本出票效率较高,6.2版本暂无数据,应该不会太差。 综上,第3和第5是接下来次要的抉择方向。 矿机对接aacd314 物理矿机(IDC机房)及海内云的差别剖析: 1、物理矿机产权有保障,头矿开挖时,入场工夫就是致胜法宝; 2、物理矿机洽购、装置、搭建调试等周期较长,间接影响空投产票量; 3、物理矿机节点数量大,单节点价格优,更适宜小微客户批发; 4、海内云节点,只能租赁,无云产权,不利于头矿开启; 5、海内云节点仅须搭建调试,次天即可挖空投支票; 6、海内云节点无带宽下限,产票效率较高; 7、海内云节点单节点价格较高,不适宜小微客户批发; 综上,两种矿机各有优劣,最好是两种计划同时运行。 IP、CPU、硬盘、带宽什么最重要? Swarm白皮书没有提供挖矿产票的阐明,在这种不确定的环境中,造成了市场的自觉洽购及营销,深圳某公司投入大量资金购买高端物理机,租用大型场地搭建顶级企业光纤,因为IP不够,导致产票率极低。四川某公司将大量低配物理机投入IDC机房,造成客户极大损失等。咱们通过上述7种计划的深度测试,论断是,海内云带宽不限的独立IP产票第一,IDC机房的物理机用多个节点一个IP产票第二,因而IP才是要害,其次才是带宽、硬盘、CPU等。 有没有更好的计划可供选择? 海内云该如何抉择? 哪个国家的云更好,性价比更高? 物理机配置如何抉择? Swarm矿机的稳定性越高,传输网络的带宽越好,数据的多样性越好您能够取得的BZZ就会越多。 SWARM主网行将上线,工夫耽搁不起,抉择一家牢靠的技术公司,才是参加SWARM空投及头矿的最佳路径!矿机对接aacd314 早在SWARM测试网百万空投挖矿打算,链芯云证便早早入场布局并对该我的项目进行深度考查,链芯云证之前已胜利推出过FIL,CHIA挖矿产品并且在业内获得很好的问题和口碑,追随咱们的客户都赚的盆满钵满,在存储板块挖矿具备成熟且最优挖矿解决方案,真正让您实现轻松躺赚!早布局,早交付,早收益!总体上来说,链芯云证是入场SWARM BZZ抢头矿最牢靠的抉择,链芯云证5年的业余团队部署及贴心服务,为您取得短暂稳固收益。对于想参加挖矿的用户而言,抉择大于致力,抉择一个安全可靠、背景雄厚的平台至关重要,能够说链芯云证满足了咱们对于挖矿平台的所有设想!更多BZZ矿机资讯加维aacd314理解

June 15, 2021 · 1 min · jiezi

关于以太坊:Swarm-Bzz矿机配置-swarm头矿避坑指南

因为头矿的微小利益,吸引了越来越多的人关注BZZ。“V神站台”、“极短回本周期”等等因素让很多人在脑袋一热的状况下一头就扎进来了! 矿机对接aacd314 当初这个市场真的是热闹非凡,大平台、小作坊的都来参加这个卖bzz节点的行当,价格从几千到几万的参差不齐,服务也是形形色色,须要大家擦亮眼睛去分辨其中利弊。 让咱们盘一下当初市场上存在的一些危险因素: 1.官网未颁布举荐配置 因为有过ipfs的前事不忘;后事之师,这次bzz的矿机配置问题就让很多人都放心。 正因为没人晓得主网上线之后矿机到底须要怎么去配置,所以才会呈现无从比价的情况,很多人可能买了节点之后,都不晓得本人到底买了什么,为什么是这个价格。 当初市面上卖的有两种,一种是云节点,就是租用腾讯云阿里云这样的云服务器搭建节点进行测试网获取支票。然而云节点在主网上线之后是大概率不能参加挖矿的,这个官网也有阐明。尽管云节点看上去便宜,但前面就没用了。 另一种是物理节点:就是蕴含cpu、内存、硬盘等的整机服务器搭建的节点。因为官网配置要求不明了,所以等到主网上线之后会面临着可能要换配置的问题,买的配置高了节约,低了还得补钱降级,有些矿商不必你补钱,那他后期收钱必定是高的,羊毛出在羊身上。 另外市面上会有一些卖的是有效的节点,出不了票的,或者是云服务器搭建了无数个老版本节点的,这样的票也是有效的票。要小心。 2.bzz空投处分的获取概率 现阶段是测试网阶段,有100万bzz会以支票的模式处分给测试者,所以当初是挖票阶段。 无论是本人搭建的节点还是云节点,还是物理节点,都是能出票的,然而进去的票值不值钱是没人晓得的。出的票必须得跟35个蜂后节点有过交互,才是有效票,有效票没价值,而有效票又须要依据你跟蜂后节点交互时的性能状况来判断价值大小。 也就是说你当初只是在抽奖,能不能抽到、抽到多少,都要看运气。 3.质押币是否须要,费用多高 当初看来其实是大概率质押,因为bzz也是分布式存储,为了保证数据存储有效性,质押是最好的方法,然而当初也没确定。 这个质押就波及到投入老本的问题了,不需要的话,你间接挖矿;然而如果须要质押,而这个质押费又相当高的话,你曾经买了矿机的状况下,那你挖呢还是不挖呢? 4.算力增长速度 这只是一个危险考量因素,尽管我集体不认为是大问题,但也给大家作为一个参考。因为Chia就呈现了算力增长速度过快的状况,导致日产降落,这个跟过后参加门槛极低有很大的关系。Bzz的话门槛要高出很多,配置机房之类的要求,再加上质押的话,应该还好。 当初有这么多危险因素,其实就是Swarm主网还未上线,经济模型不清晰,挖矿机制不明确,未知因素过多的起因。 另外,在市场上买bzz币也要小心。卖私募币的人手里可能基本就没有币,他会依据币价的状况来思考是否给你兑付。野鸡交易所的期货,你买了可能基本就提不进去。还有,1.92美元的公募币要在coinlist发售了,很人多在搞那个简单的kyc或者收买coinlist账号的,这个也有危险的,账号很有可能被封掉,不封的话也不肯定能抢失去bzz币的。 OK,头矿尽管很引诱,然而市面上的坑其实也特地多,大家要擦亮眼睛,依据本人对危险的断定进行感性投资。 矿机对接aacd314 在此,链芯云证科技再为大家说下物理节点和云节点的区别: 1、不会有所谓的官网矿机硬件配置;具体参考Filecoin就晓得了; 2、Swarm网络对硬件要求不高,不同的配置的服务器能够搭1-N个Bee节点,比方你的办公电脑可能能够部署5个Bee节点,而咱们配置的业余服务器则能够配置500个Bee节点,目前咱们还没有规范的服务器计划,所以目前不会有所谓的物理矿机(物理节点)的销售计划;兴许主网上线后会有,但其实意义并不大。 3、BZZ的次要老本是带宽,硬件老本占比拟小,所以不要过多关注于硬件所有权; 举个栗子:你家里装宽带,花300块钱买个路由器,一年宽带费是1200元;路由器所有权是你的,然而你第二年不续费,你还是一样上不了网; 不要纠结什么所有权,只有Swarm网络存在,权利能够说是永恒的,只有你按时缴纳足够的带宽费; 4、Swarm须要寰球部署节点,不同地区的硬件、带宽状况不一样,所以目前来看也没有方法用对立配置的服务器; 5、云节点并不就是虚构的,背地必定须要有对应的物理服务器、IP、带宽、防火墙、软件等一列货色组成的。不要听什么Bee主网上线后,云节点就报废的胡扯说法;其实逻辑和Filecoin的云算力是一个情理。所谓的矿机其实只是一台存储服务器,然而背地还有交换机、光纤、封装机、节点机、证实机、集群软件、防火墙等一系列的配套软硬件能力搭建一个残缺的矿池。而云算力只是在Filecoin网络上比拟好计量的一个单位而已。

June 15, 2021 · 1 min · jiezi

关于以太坊:Swarm-Bzz矿机配置方案-swarm头矿避坑指南

因为头矿的微小利益,吸引了越来越多的人关注BZZ。“V神站台”、“极短回本周期”等等因素让很多人在脑袋一热的状况下一头就扎进来了! 矿机对接aacd314 当初这个市场真的是热闹非凡,大平台、小作坊的都来参加这个卖bzz节点的行当,价格从几千到几万的参差不齐,服务也是形形色色,须要大家擦亮眼睛去分辨其中利弊。 让咱们盘一下当初市场上存在的一些危险因素: 1.官网未颁布举荐配置 因为有过ipfs的前事不忘;后事之师,这次bzz的矿机配置问题就让很多人都放心。 正因为没人晓得主网上线之后矿机到底须要怎么去配置,所以才会呈现无从比价的情况,很多人可能买了节点之后,都不晓得本人到底买了什么,为什么是这个价格。 当初市面上卖的有两种,一种是云节点,就是租用腾讯云阿里云这样的云服务器搭建节点进行测试网获取支票。然而云节点在主网上线之后是大概率不能参加挖矿的,这个官网也有阐明。尽管云节点看上去便宜,但前面就没用了。 另一种是物理节点:就是蕴含cpu、内存、硬盘等的整机服务器搭建的节点。因为官网配置要求不明了,所以等到主网上线之后会面临着可能要换配置的问题,买的配置高了节约,低了还得补钱降级,有些矿商不必你补钱,那他后期收钱必定是高的,羊毛出在羊身上。 另外市面上会有一些卖的是有效的节点,出不了票的,或者是云服务器搭建了无数个老版本节点的,这样的票也是有效的票。要小心。 2.bzz空投处分的获取概率 现阶段是测试网阶段,有100万bzz会以支票的模式处分给测试者,所以当初是挖票阶段。 无论是本人搭建的节点还是云节点,还是物理节点,都是能出票的,然而进去的票值不值钱是没人晓得的。出的票必须得跟35个蜂后节点有过交互,才是有效票,有效票没价值,而有效票又须要依据你跟蜂后节点交互时的性能状况来判断价值大小。 也就是说你当初只是在抽奖,能不能抽到、抽到多少,都要看运气。 3.质押币是否须要,费用多高 当初看来其实是大概率质押,因为bzz也是分布式存储,为了保证数据存储有效性,质押是最好的方法,然而当初也没确定。 这个质押就波及到投入老本的问题了,不需要的话,你间接挖矿;然而如果须要质押,而这个质押费又相当高的话,你曾经买了矿机的状况下,那你挖呢还是不挖呢? 4.算力增长速度 这只是一个危险考量因素,尽管我集体不认为是大问题,但也给大家作为一个参考。因为Chia就呈现了算力增长速度过快的状况,导致日产降落,这个跟过后参加门槛极低有很大的关系。Bzz的话门槛要高出很多,配置机房之类的要求,再加上质押的话,应该还好。 当初有这么多危险因素,其实就是Swarm主网还未上线,经济模型不清晰,挖矿机制不明确,未知因素过多的起因。 另外,在市场上买bzz币也要小心。卖私募币的人手里可能基本就没有币,他会依据币价的状况来思考是否给你兑付。野鸡交易所的期货,你买了可能基本就提不进去。还有,1.92美元的公募币要在coinlist发售了,很人多在搞那个简单的kyc或者收买coinlist账号的,这个也有危险的,账号很有可能被封掉,不封的话也不肯定能抢失去bzz币的。 OK,头矿尽管很引诱,然而市面上的坑其实也特地多,大家要擦亮眼睛,依据本人对危险的断定进行感性投资。 矿机对接aacd314 在此,链芯云证科技再为大家说下物理节点和云节点的区别: 1、不会有所谓的官网矿机硬件配置;具体参考Filecoin就晓得了; 2、Swarm网络对硬件要求不高,不同的配置的服务器能够搭1-N个Bee节点,比方你的办公电脑可能能够部署5个Bee节点,而咱们配置的业余服务器则能够配置500个Bee节点,目前咱们还没有规范的服务器计划,所以目前不会有所谓的物理矿机(物理节点)的销售计划;兴许主网上线后会有,但其实意义并不大。 3、BZZ的次要老本是带宽,硬件老本占比拟小,所以不要过多关注于硬件所有权; 举个栗子:你家里装宽带,花300块钱买个路由器,一年宽带费是1200元;路由器所有权是你的,然而你第二年不续费,你还是一样上不了网; 不要纠结什么所有权,只有Swarm网络存在,权利能够说是永恒的,只有你按时缴纳足够的带宽费; 4、Swarm须要寰球部署节点,不同地区的硬件、带宽状况不一样,所以目前来看也没有方法用对立配置的服务器; 5、云节点并不就是虚构的,背地必定须要有对应的物理服务器、IP、带宽、防火墙、软件等一列货色组成的。不要听什么Bee主网上线后,云节点就报废的胡扯说法;其实逻辑和Filecoin的云算力是一个情理。所谓的矿机其实只是一台存储服务器,然而背地还有交换机、光纤、封装机、节点机、证实机、集群软件、防火墙等一系列的配套软硬件能力搭建一个残缺的矿池。而云算力只是在Filecoin网络上比拟好计量的一个单位而已。

June 15, 2021 · 1 min · jiezi

关于以太坊:BZZ矿机越早进场有什么好处BZZ矿机早进场的九大理由

BZZ越早进场的几大理由: 一 :早进场早挖票能兑换寰球一百万空投 二:早进场节点能收费失去无效数据,等主网上线就不必充币去调他人数据,新节点要向老节点调数据,可间接产币 三: 当初硬件价格低,前事不忘;后事之师,供货商哄抬配件,价格疯涨 四 :头矿很重要,迟一天天差地别 五 :等配置进去市场价高,很难定到货,预估定矿机就得15天左右,加上装置调试,头矿就与你无缘了 六:有很大可能测试网期间质押的gbzz会转为主网上线的质押币,fil就有很多矿工因为一波提前布局的操作大赚 BZZ矿机对接aacd314 七:BZZ是天王级我的项目,次要解决以太坊拥挤和矿工费高问题,对技术团队要求高,带宽要求国家级别,不要错过这百年不遇的时机! 八:为什么最佳抉择是择挖矿?从老本、收益、危险这三个角度能够进行简略比照。1.买币是赚波段差,买多少是多少,币不能生币;挖矿最低都是3年,工夫越久,挖到的币数量越多;2.买币老本等于市价;挖矿老本相当于市价3折左右;3.买币容易守币难、投机跟币价涨跌非亲非故;挖矿是强制性长期持有,是一种价值投资! 九:为什么要布局BZZ头矿?因为头矿回本周期都是按小时来计算的!如: 1: IPFS头矿单P 300个FIL/天 2: CHIA头矿单P 65个XCH/天 3: 比特币头矿单台 357个BTC/天 4:SWARM头矿一天多少个BZZ?多少个小时回本? 5.Swarm的第一个矿很重要,晚进一天的支出能够说是不一样的,就像China的1P第一个矿一天65个币,当初一天挖不到0.4个币,差距大到你无奈设想。 所以头矿的第1个月比前面半年的产量都要高出很多!这就是为什么要提前购买BZZ矿机抢占矿头的外围起因! BZZ矿机对接aacd314早在SWARM测试网百万空投挖矿打算,链芯云证便早早入场布局并对该我的项目进行深度考查,链芯云证之前已胜利推出过FIL,CHIA挖矿产品并且在业内获得很好的问题和口碑,追随咱们的客户都赚的盆满钵满,在存储板块挖矿具备成熟且最优挖矿解决方案,真正让您实现轻松躺赚! 早布局,早交付,早收益! 总体上来说,链芯云证是入场SWARM BZZ抢头矿最牢靠的抉择,链芯云证5年的业余团队部署及贴心服务,为您取得短暂稳固收益。对于想参加挖矿的用户而言,抉择大于致力,抉择一个安全可靠、背景雄厚的平台至关重要,能够说链芯云证满足了咱们对于挖矿平台的所有设想!

June 15, 2021 · 1 min · jiezi

关于以太坊:BZZ矿机越早进场有什么好处BZZ矿机早进场的九大理由

BZZ越早进场的几大理由: 一 :早进场早挖票能兑换寰球一百万空投 二:早进场节点能收费失去无效数据,等主网上线就不必充币去调他人数据,新节点要向老节点调数据,可间接产币 三: 当初硬件价格低,前事不忘;后事之师,供货商哄抬配件,价格疯涨 四 :头矿很重要,迟一天天差地别 五 :等配置进去市场价高,很难定到货,预估定矿机就得15天左右,加上装置调试,头矿就与你无缘了 六:有很大可能测试网期间质押的gbzz会转为主网上线的质押币,fil就有很多矿工因为一波提前布局的操作大赚 BZZ矿机对接aacd314 七:BZZ是天王级我的项目,次要解决以太坊拥挤和矿工费高问题,对技术团队要求高,带宽要求国家级别,不要错过这百年不遇的时机! 八:为什么最佳抉择是择挖矿?从老本、收益、危险这三个角度能够进行简略比照。1.买币是赚波段差,买多少是多少,币不能生币;挖矿最低都是3年,工夫越久,挖到的币数量越多;2.买币老本等于市价;挖矿老本相当于市价3折左右;3.买币容易守币难、投机跟币价涨跌非亲非故;挖矿是强制性长期持有,是一种价值投资!BZZ矿机对接V:aacd314 矿机 九:为什么要布局BZZ头矿?因为头矿回本周期都是按小时来计算的!如: 1: IPFS头矿单P 300个FIL/天 2: CHIA头矿单P 65个XCH/天 3: 比特币头矿单台 357个BTC/天 4:SWARM头矿一天多少个BZZ?多少个小时回本? 5.Swarm的第一个矿很重要,晚进一天的支出能够说是不一样的,就像China的1P第一个矿一天65个币,当初一天挖不到0.4个币,差距大到你无奈设想。 所以头矿的第1个月比前面半年的产量都要高出很多!这就是为什么要提前购买BZZ矿机抢占矿头的外围起因! BZZ矿机对接aacd314早在SWARM测试网百万空投挖矿打算,链芯云证便早早入场布局并对该我的项目进行深度考查,链芯云证之前已胜利推出过FIL,CHIA挖矿产品并且在业内获得很好的问题和口碑,追随咱们的客户都赚的盆满钵满,在存储板块挖矿具备成熟且最优挖矿解决方案,真正让您实现轻松躺赚! 早布局,早交付,早收益! 总体上来说,链芯云证是入场SWARM BZZ抢头矿最牢靠的抉择,链芯云证5年的业余团队部署及贴心服务,为您取得短暂稳固收益。对于想参加挖矿的用户而言,抉择大于致力,抉择一个安全可靠、背景雄厚的平台至关重要,能够说链芯云证满足了咱们对于挖矿平台的所有设想!

June 15, 2021 · 1 min · jiezi

关于以太坊:Swarm主网即将上线头矿红利即将来袭bzz矿机该怎么选择

万众瞩目的Swarm我的项目终于有音讯了,Swarm官方消息称,Swarm(bzz)主网将于6月21号上线。Swarm主网上线就意味着头矿红利行将来袭,目前挖矿就是Swarm最晚期的参与者,收益将十分可观。Swarm主网邻近上线,BZZ矿机市场一片炽热,很多人关怀一个问题,到底是当初就抉择矿机挖矿还是等主网上线后再布局矿机?倡议抉择前者,上面就由链芯云证科技为大家解说一下起因!Swarm矿机对接V: bqyj133在抉择矿机前,咱们首先要理解其处分机制。理解剖析过Swarm挖矿的小伙伴们应该晓得,Swarm其实不是存储系统,而是散发零碎。Swarm是节点间的流量费互传,因而能够说,Swarm挖矿没有出块处分,挖矿挖的是流量费,即数据的申请节点向服务节点领取流量费,所以节点的收益来源于其余节点给的流量费。在流量费的领取上,Swarm采纳了更平安的“逐渐领取”机制。服务节点分段传输数据,并期待申请节点返回一条“支票”,如果拿不到支票,服务节点就不会发送后续数据,并将申请节点拉入黑名单。这样就能将服务节点的损失降到很低,而申请节点也不必放心一次性领取流量费后被“跑路”,从而实现了双向爱护的流量计费。这些支票会提交给链上,通过智能合约,依据收据的签名和指标将相应代币从数据申请节点转移到服务节点。深刻推断后,咱们还能够失去如下论断:1、Swarm节点收取流量费下限与带宽无关,两者成正比。2、节点传输流量受限于节点的零碎瓶颈,在Swarm计划中是磁盘IO。由此咱们便能够开始剖析Swarm矿机的硬件需要和配置。出于Filecoin的前事不忘;后事之师,或者有的小伙伴会认为Swarm的矿机要求也会那样多变。但其实并非如此,根据上述论断,Swarm矿机的配置计划与限度是能够推断进去的。Swarm将文件宰割为4KB的片段进行传输,数据存储于磁盘上,因而数据的拜访能力受限于磁盘IO,所以咱们能够依据磁盘的IOPS(每秒读写IO次数)性能计算出每种磁盘的Swarm读写性能。Swarm矿机对接V: bqyj133举例来说,HDD硬盘的IOPS最高约为在76(7200转)到166(15000转)之间,因而读写性能在 (76~166)x4KB=300KB-664KB每秒,折算成带宽就是一个3-6Mbps。也就是说,如果应用一个机械硬盘作存储,即便跑多个节点,应用再多带宽,也只有最高3-6Mbps带宽的收益下限。而SSD硬盘的IOPS最高大概在4万,因而读写性能的极限在40000x4KB = 160000KB = 160MB。折算成带宽约为1.6Gbps,也就是说收益下限能达到1.6Gbps。扣除片段信息管理用掉的磁盘IO,每个SSD磁盘大概能够反对1Gbps的带宽。又因为文件片段会主动推送到不同节点,读取时也会主动从不同节点上读取,所以在一台物理节点下来运行多个节点就能收到更多片段数据,进步被读取概率,也就能取得更多收益。(在网络带宽足够的前提下)当然咱们也还须要依据集体状况思考CPU性能等零碎瓶颈,以及跑多个节点时因为代码未做优化而导致带宽没满但磁盘IO先满了等问题。具体问题须要具体解决,本篇就不多赘述了。Swarm矿机对接V: bqyj133SWARM挖矿剖析其实数据的存储也是一样,数据的存储正确与否,大小多少也是只有存储的需求者和提供者晓得,要想让其他人晓得怎么办?须要应用零常识证实,Filecoin就是实现了这个零常识证实,此处按下不表。流量传输的这个问题导致另外一个问题:因为流量传输的内容和大小,其余节点不晓得,因而链上不能应用这个流量的大小作为算力。大家晓得,区块链外面的算力是出块的根据,即节点算力占全网算力的比例就是节点出块的概率,这样才是偏心的出块机制。流量不能作为算力就意味着不能通过流量进行出块处分。因而SWARM无奈实现仅基于流量的区块链零碎,即流量必须依赖于另外一条主链。在swarm中,主链依赖以太坊,目前应用的以太坊的测试链,官网号称将来将基于以太坊主网,在这里我可很明确地和大家说,这是99%不可能的。那不通过流量给过出块处分,挖矿挖个啥,难道挖了个寂寞?其实也不是,挖的是流量费,即数据的申请节点向服务节点领取流量费,所以节点的收益来源于 其余节点给的流量费。那这样也有问题,流量费是后领取还是先领取?如果是后领取,申请节点会不会拿了数据后不领取流量费?如果是先领取,服务节点会不会拿了流量费不给数据?为了解决这个问题,能够采纳逐渐领取的机制,即服务节点每传输一段数据(比如说1M),期待申请节点回一个收据(或者叫支票),如果你不回支票给我,那我前面就不传数据给你,并且把你拉入黑名单,这样服务节点即便损失,也就损失一小部分流量费。而申请节点作恶多了,全网就没有节点会答理他了,也是千里之堤;溃于蚁穴。通过这样的形式能够实现流量的计费。然而上述计划有一个总是,一段数据设置成多大比拟适合?如果设置的比拟小,比方是1MB,如果100Mbps的网络节点,每秒都须要产生一个收据,全网如果几十万节点,这个收据(支票)的数据量微小无比,基本不可能解决的过去。如果设置的比拟大,那申请节点可能会逃费。这个问题就须要可合并的收据(支票),swarm里没有做这个事,会不会有问题?目前测试网24万个节点曾经很堵了(别忘了测试网的流量应该很小哦),将来主网上,应该问题会更重。这些收据(支票)提交给链上,链上依据收据的签名和指标,将相应的代币从数据的请求者节点转移到服务者节点,这个是通过智能合约来实现的。因而,咱们能够失去以下几个论断:1、Swarm挖矿没有出块处分,是节点之间的流量费互传。2、节点可能收到的流量费的下限与带宽无关,带宽越高,流量费下限越高。3、节点可能传输的流量还受限于节点的零碎瓶颈,而在swarm计划中,零碎瓶颈是磁盘IO。Swarm矿机对接V: bqyj133 给大家讲一下矿机的品种,有什么区别:第一种:个人电脑搭建物理单节点矿机,5.3版本晚期可行,4月下旬就很难出票。第二种:物理矿机(服务器),办公企业级光纤搭建,只有企业固定的IP可用,5月中旬后很难出票。第三种:物理矿机(服务器),IDC机房搭建,单一个节点一个ip带宽,5.3版本临时还能挖,出票效率比拟优异,6.2版本有待考验。第四种:国内云搭建:一个节点一个ip带宽老本过高,不倡议驳回。第五种:海内云搭建,一个节点一个ip,5.3版本出票效率高,6.2版本暂无数据,官网公示不能参加前期主网挖矿。综上,链芯云证科技建第三种和第五种是接下来次要抉择的方向,物理矿机(IDC机房)及海内云的差别剖析:1,物理矿机:物理矿机产权有保障,头矿开挖时,入场工夫就是制胜法宝。2,物理矿机洽购,装置,搭建调试等周期较长,间接影响产量。3,物理矿机节点数量大,单节点价格优,更适宜小微客户批发。4,海内云节点,只能租赁,无云产权,不利于头矿开启。5,海内云节点仅需搭建调试,次天即可开挖。6,海内云节点无宽带下限,产票率较高。7,海内云节点单节点价格较高,不适宜小微客户批发。综上,两种矿机各有劣势,也能够两种计划同时运行,依据本身条件抉择。但要思考到海内云节点是否参加主网挖矿。所以,链芯云证科技倡议大家抉择物理矿机抢挖BZZ头矿,这是最好的办法! IP /CPU/ 硬盘/ 带宽/质押数量到底哪一个最重要?IP不够会间接导致产票率低,造成客户极大的损失,CPU的配置有余会导致前期节点扩容受限不易进步性能。我的项目方提醒目前测试网络须要100G硬盘存储空间,因为Swarm是一个存储我的项目也会对硬盘存储空间有进一步要求。Swarm我的项目对于稳固的带宽要求比拟严格,目前咱们测试出的数据是最低5m的带宽最好是专线独享带宽,20m以上的带宽出票比较稳定。最初质押代币的数量也会影响出票的面值大小。下面的参数在主网没有上线的最初一刻都有可能呈现变动,然而咱们能够通过测试的数据得悉Swarm我的项目是一个门槛稍高的区块链我的项目,门槛越高那么它的利润也会越可观。当初市面上可能有一些物理矿机的价格在3千,4千的,或者价格比失常价格低很多,这个咱们须要留神,因为当初官网机制还没有确定,所以当初高价卖的,很有可能在主网开启挖矿时你的节点并不能第一工夫参加到头矿福利。链芯云证科技揭示大家,不要贪便宜,抉择最合适最靠谱的,保障能抢到BZZ头矿的矿商,这才是最重要的。Swarm矿机对接V: bqyj133BZZ是业余赛道,技术服务很要害,早布局,早交付,早收益!早在SWARM测试网百万空投挖矿打算,链芯云证便早早入场布局并对该我的项目进行深度考查,链芯云证之前已胜利推出过FIL,CHIA挖矿产品并且在业内获得很好的问题和口碑,追随咱们的客户都赚的盆满钵满,在存储板块挖矿具备成熟且最优挖矿解决方案,真正让您实现轻松躺赚!早布局,早交付,早收益!总体上来说,链芯云证是入场SWARM BZZ抢头矿最牢靠的抉择,链芯云证5年的业余团队部署及贴心服务,为您取得短暂稳固收益。对于想参加挖矿的用户而言,抉择大于致力,抉择一个安全可靠、背景雄厚的平台至关重要,能够说链芯云证满足了咱们对于挖矿平台的所有设想!更多BZZ矿机资讯敬请关注公众号“链芯云证矿业”

June 15, 2021 · 1 min · jiezi

关于以太坊:官宣Swarm将于21日分发代币BZZ开启现货交易

官宣:Swarm将于6月21日散发代币BZZ,开启现货交易!6月21日主网将正式上线,目前挖矿就是Swarm最晚期的参与者,收益预计也将十分可观。 官方消息,以太坊存储我的项目Swarm(BZZ)发表将在6月21日散发除 CoinList公募和空投外的所有代币 Swarm示意,此次散发代币蕴含种子轮和私募轮,而CoinList公募参与者将在8月2日前后取得代币。此前音讯, Swarm将于6月15日在CoinList上开启公募,并将于6月21日启动主网。矿机对接V:aacd314 以太坊SWARM主网将于 6 月 21 正式启动!最新的 Swarm 客户端,名为“Bee 1.0 候选版本”,曾经公布。SWARM主网将于6月21日正式启动! Swarm 是一个用于势力数字社会的去中心化存储和通信零碎,由点对点网络节点组成的零碎,可创立扩散的存储和通信服务。因为通过以太坊区块链上的智能合约执行的内置激励零碎,该零碎在经济上可实现自我运行。 Swarm网络由有数的节点组成去中心化存储和流量散发零碎,创立了一个永远不停机、零故障和防审查、高效的点对点存储和CDN解决方案。利用这些节点的存储、带宽和算力资源将用来反对基于以太坊生态甚至将来互联网的去中心化利用。 Swarm从字面上了解直译过去是「蜂群」的意思,寓意小而快。Swarm 对「蜂群」堪称情有独钟,其最新客户端被命名为 Bee,代币符号 BZZ 也模仿蜜蜂航行时的声音。矿机对接V:aacd314 Swarm通过用智能合约来实现流量激励, 激励零碎围绕 Swap (替换)、Swear (保障)、和 Swindle (欺诈)三个重要合约组件建设而成。 实质上是建设一种信赖关系用以带宽调换,让节点能够像中间人一样帮忙别的节点去接管或者去发送信息给另外的节点。最简略了解是有那么三个节点A,B,C。无论A要发给C货色还是C反馈给A,都有大概率有可能通过B的转发。打个比方:A节点如何和另外的每个节点产生间接分割?这就须要两头者,能够只有一个B或者很多B1,B2,B(n+1)。 因而,Swarm就是靠这个模型来upload(上传)和download(下载)的。转换下就很容易了解了,A如果要下载货色,发送了申请,B或B(n+1)没有,那么B或B(n+1)转发,巧了,C正好有,这时候C会按原门路把区块发还回去。上传同理。 Swap:替换合约记录带宽应用状况,为提供内容服务的节点给予弥补,促成受欢迎的内容被更宽泛的流传和被更疾速获取。 Swear:保障合约解决长期存储,在容许节点发售他们存储空间的同时,也容许用户在 Swarm 上长期牢靠地存储数据。 Swindle:欺诈合约由一个解决纠纷的诉讼引擎形成,它是零碎中状态裁决的候选者。 什么是Swarm?它能解决什么问题? Swarm是一个能集中提供去中心化贮存和沟通服务的点对点节点网络。内置的激励零碎能保障Swarm的经济可持续性,而激励零碎通过以太坊区块链和BZZ通证来施行。 Swarm促成信息自在,以响应对网络安全性日益增长的需要。Swarm解决了去中心化激励存储的问题。这意味着节点运营商将取得处分,以放弃网络衰弱和完满运行。至于用例:新闻自由、可扩大的Dapp托管和真正的去中心化社交媒体平台都是唾手可得的成绩。矿机对接V:aacd314 Swarm的指标用户是谁?这些用户在你的平台上有什么样的互动? Swarm是一个底层基础设施我的项目,旨在成为从新去中心化互联网的根底。这是一个波及全人类的我的项目。因为Swarm旨在解决当今互联网面临的最大问题之一。 对于开发内容和应用程序的人来说,存储老本始终是最大的累赘之一。是的,任何人都能够创立博客,从而在寰球答辩中发表意见,然而随着内容的日益风行,老本会回升,直到原始创建者无奈再发表他们的意见。在Web 2.0 中,这个问题以一种对用户来说不是最佳的形式解决了:大公司领取了存储和带宽的费用,作为回报,他们要求领有数据。 用户的数据最终在数据市场上发售,为管制带宽和存储容量的公司赚取了巨额利润。隐衷被排除在外,亚马逊、Facebook和谷歌等公司则取得了权力。人变成了他们的产品,用户的集体数据被发售给营销和钻研公司。作为回报,用户取得了Facebook和Google等收费服务。 有了Web3,新的范式和经济成为可能。但在建设一个牢靠的、扩散的存储系统之前,即便是Web3 DApp也须要将数据存储在集中控制的环境中。 Swarm的使命就是为Web 3提供这样的解决方案。用户能够本人决定是将他们的数据窃密,是在数据市场上发售,或是捐献给他们本人抉择的钻研机构。因为存储和带宽不是由开发人员/内容创建者领取的,他们能够专一于创立好的内容和服务,从而可能疾速采纳。矿机对接V:aacd314 总结一下,Swarm作为以太坊网络的外围协定之一,是第一个实现去中心化流量散发激励的区块链我的项目。由以太坊创始人V神和波卡的创始人加文·伍德等技术大神亲自操刀,其含金量显而易见。加之以太坊的利用生态先发劣势,Swarm将来前景不可限量。

June 15, 2021 · 1 min · jiezi

关于以太坊:swarm主网软启动正式开始将于6月21日分发代币BZZ

6月21日主网将正式上线,目前挖矿就是Swarm最晚期的参与者,收益将十分可观。 以后Swarm主网未上线,BZZ矿机市场一片炽热,很多敌人都在思考是当初提前购买矿机,还是等主网上线后在购买?链芯云证科技倡议大家提前布局Swarm矿机!Swarm矿机对接V: bqyj133因为主网上线后,硬件市场会哄抬价格,导致整个行业矿机价格上涨,Swarm头矿红利来了,往年不容错过的我的项目。在4月初,chia(奇亚)矿机上线后,原本20万1P(1024T)以内的矿机价格,在3天内飙升到26万1P,一周工夫涨到40万1P的期货和60万1P的现货,硬盘间接从2500元左右涨到了8000元一个,硬件价格间接飙涨3倍以上。可能对于投入几千块钱的人来说没有太大感觉,然而对于原来只需投入20万,后果最初要投入60万,整个落差老本还是很高的。所以,Swarmbzz主网上线后硬件价格很大可能都会整体上涨,毕竟硬件供应商也会乘着这个趋势赚一波。而对于投资BZZ节点的人来说,头矿利润高,只有跌价不太过分,都会抉择买物理矿机抢头矿,以下是链芯云证官网报价表!官方消息,以太坊存储我的项目Swarm(BZZ)发表将在6月21日散发除 CoinList公募和空投外的所有代币 Swarm示意,此次散发代币蕴含种子轮和私募轮,而CoinList公募参与者将在8月2日前后取得代币。此前音讯, Swarm将于6月15日在CoinList上开启公募,并将于6月21日启动主网。软启动正式开始了, 这些重要的信息咱们须要通晓:1、6月13号是软启动,次要还是运行测试网节点。2、软启动期间还是不能间接挖币(bzz),须要期待6月21号之后。3、6月21号之后新退出的新节点须要质押,之前测试网节点能够在该主网上操作全功能节点。4、软启动中包含 Swarms 官网 BZZ 代币地址,该代币尚未公开流通。能够在CoinList上找进行公募价格是1.92美金。5、脱离节点运行超过12小时将触碰惩办机制。Swarm矿机对接V: bqyj133以太坊SWARM主网将于 6 月 21 正式启动!最新的 Swarm 客户端,名为“Bee 1.0 候选版本”,曾经公布。SWARM主网将于6月21日正式启动! Swarm从字面上了解直译过去是「蜂群」的意思,寓意小而快。Swarm 对「蜂群」堪称情有独钟,其最新客户端被命名为 Bee,代币符号 BZZ 也模仿蜜蜂航行时的声音。什么是Swarm?它能解决什么问题?Swarm的指标用户是谁?这些用户在你的平台上有什么样的互动?Swarm是一个底层基础设施我的项目,旨在成为从新去中心化互联网的根底。这是一个波及全人类的我的项目。因为Swarm旨在解决当今互联网面临的最大问题之一。对于开发内容和应用程序的人来说,存储老本始终是最大的累赘之一。是的,任何人都能够创立博客,从而在寰球答辩中发表意见,然而随着内容的日益风行,老本会回升,直到原始创建者无奈再发表他们的意见。在Web 2.0 中,这个问题以一种对用户来说不是最佳的形式解决了:大公司领取了存储和带宽的费用,作为回报,他们要求领有数据。 用户的数据最终在数据市场上发售,为管制带宽和存储容量的公司赚取了巨额利润。隐衷被排除在外,亚马逊、Facebook和谷歌等公司则取得了权力。人变成了他们的产品,用户的集体数据被发售给营销和钻研公司。作为回报,用户取得了Facebook和Google等收费服务。有了Web3,新的范式和经济成为可能。但在建设一个牢靠的、扩散的存储系统之前,即便是Web3 DApp也须要将数据存储在集中控制的环境中。Swarm的使命就是为Web 3提供这样的解决方案。用户能够本人决定是将他们的数据窃密,是在数据市场上发售,或是捐献给他们本人抉择的钻研机构。因为存储和带宽不是由开发人员/内容创建者领取的,他们能够专一于创立好的内容和服务,从而可能疾速采纳。Swarm作为以太坊网络的外围协定之一,是第一个实现去中心化流量散发激励的区块链我的项目。由以太坊创始人杰弗里维尔克和波卡的创始人加文·伍德等技术大神亲自操刀,其含金量显而易见。加之以太坊的利用生态先发劣势,Swarm将来前景不可限量。认知是常识的积攒,财产是认知的变现。区块链能够重构社会的财产与经济秩序!投资是一场马拉松,不在于你起跑多快,而在于跑在正确的跑道上,跑到起点或者更远。在投资的世界里,抉择比致力更重要,认知高度决定你所能领有的财产Swarm矿机对接V: bqyj133BZZ是业余赛道,技术服务很要害,早布局,早交付,早收益!早在SWARM测试网百万空投挖矿打算,链芯云证便早早入场布局并对该我的项目进行深度考查,链芯云证之前已胜利推出过FIL,CHIA挖矿产品并且在业内获得很好的问题和口碑,追随咱们的客户都赚的盆满钵满,在存储板块挖矿具备成熟且最优挖矿解决方案,真正让您实现轻松躺赚!早布局,早交付,早收益!总体上来说,链芯云证是入场SWARM BZZ抢头矿最牢靠的抉择,链芯云证5年的业余团队部署及贴心服务,为您取得短暂稳固收益。对于想参加挖矿的用户而言,抉择大于致力,抉择一个安全可靠、背景雄厚的平台至关重要,能够说链芯云证满足了咱们对于挖矿平台的所有设想!更多BZZ矿机资讯敬请关注公众号“链芯云证矿业”

June 15, 2021 · 1 min · jiezi

关于以太坊:Swarm将于6月21日分发代币Bzzswarm物理矿机销售方案

6月21日主网将正式上线,目前挖矿就是Swarm最晚期的参与者,收益将十分可观。 以后Swarm主网未上线,BZZ矿机市场一片炽热,很多敌人都在思考是当初提前购买矿机,还是等主网上线后在购买?链芯云证科技倡议大家提前布局Swarm矿机! 因为主网上线后,硬件市场会哄抬价格,导致整个行业矿机价格上涨,Swarm头矿红利来了,往年不容错过的我的项目。 在4月初,chia(奇亚)矿机上线后,原本20万1P(1024T)以内的矿机价格,在3天内飙升到26万1P,一周工夫涨到40万1P的期货和60万1P的现货,硬盘间接从2500元左右涨到了8000元一个,硬件价格间接飙涨3倍以上。可能对于投入几千块钱的人来说没有太大感觉,然而对于原来只需投入20万,后果最初要投入60万,整个落差老本还是很高的。所以,Swarmbzz主网上线后硬件价格很大可能都会整体上涨,毕竟硬件供应商也会乘着这个趋势赚一波。而对于投资BZZ节点的人来说,头矿利润高,只有跌价不太过分,都会抉择买物理矿机抢头矿 以下是链芯云证官网报价表! bzz矿机对接aacd314 官方消息,以太坊存储我的项目Swarm(BZZ)发表将在6月21日散发除 CoinList公募和空投外的所有代币 Swarm示意,此次散发代币蕴含种子轮和私募轮,而CoinList公募参与者将在8月2日前后取得代币。此前音讯, Swarm将于6月15日在CoinList上开启公募,并将于6月21日启动主网。 软启动正式开始了, 这些重要的信息咱们须要通晓: 1、6月13号是软启动,次要还是运行测试网节点。 2、软启动期间还是不能间接挖币(bzz),须要期待6月21号之后。 3、6月21号之后新退出的新节点须要质押,之前测试网节点能够在该主网上操作全功能节点。 4、软启动中包含 Swarms 官网 BZZ 代币地址,该代币尚未公开流通。能够在CoinList上找进行公募价格是1.92美金。 5、脱离节点运行超过12小时将触碰惩办机制。 以太坊SWARM主网将于 6 月 21 正式启动!最新的 Swarm 客户端,名为“Bee 1.0 候选版本”,曾经公布。SWARM主网将于6月21日正式启动! Swarm从字面上了解直译过去是「蜂群」的意思,寓意小而快。Swarm 对「蜂群」堪称情有独钟,其最新客户端被命名为 Bee,代币符号 BZZ 也模仿蜜蜂航行时的声音。 什么是Swarm?它能解决什么问题? Swarm的指标用户是谁?这些用户在你的平台上有什么样的互动? Swarm是一个底层基础设施我的项目,旨在成为从新去中心化互联网的根底。这是一个波及全人类的我的项目。因为Swarm旨在解决当今互联网面临的最大问题之一。 对于开发内容和应用程序的人来说,存储老本始终是最大的累赘之一。是的,任何人都能够创立博客,从而在寰球答辩中发表意见,然而随着内容的日益风行,老本会回升,直到原始创建者无奈再发表他们的意见。在Web 2.0 中,这个问题以一种对用户来说不是最佳的形式解决了:大公司领取了存储和带宽的费用,作为回报,他们要求领有数据。 用户的数据最终在数据市场上发售,为管制带宽和存储容量的公司赚取了巨额利润。隐衷被排除在外,亚马逊、Facebook和谷歌等公司则取得了权力。人变成了他们的产品,用户的集体数据被发售给营销和钻研公司。作为回报,用户取得了Facebook和Google等收费服务。 有了Web3,新的范式和经济成为可能。但在建设一个牢靠的、扩散的存储系统之前,即便是Web3 DApp也须要将数据存储在集中控制的环境中。 Swarm的使命就是为Web 3提供这样的解决方案。用户能够本人决定是将他们的数据窃密,是在数据市场上发售,或是捐献给他们本人抉择的钻研机构。因为存储和带宽不是由开发人员/内容创建者领取的,他们能够专一于创立好的内容和服务,从而可能疾速采纳。 Swarm作为以太坊网络的外围协定之一,是第一个实现去中心化流量散发激励的区块链我的项目。由以太坊创始人V神和波卡的创始人加文·伍德等技术大神亲自操刀,其含金量显而易见。加之以太坊的利用生态先发劣势,Swarm将来前景不可限量。 bzz矿机对接aacd314 认知是常识的积攒,财产是认知的变现。区块链能够重构社会的财产与经济秩序!投资是一场马拉松,不在于你起跑多快,而在于跑在正确的跑道上,跑到起点或者更远。在投资的世界里,抉择比致力更重要,认知高度决定你所能领有的财产。 BZZ是业余赛道,技术服务很要害,早布局,早交付,早收益! 早在SWARM测试网百万空投挖矿打算,链芯云证便早早入场布局并对该我的项目进行深度考查,链芯云证之前已胜利推出过FIL,CHIA挖矿产品并且在业内获得很好的问题和口碑,追随咱们的客户都赚的盆满钵满,在存储板块挖矿具备成熟且最优挖矿解决方案,真正让您实现轻松躺赚! 总体上来说,链芯云证是入场SWARM BZZ抢头矿最牢靠的抉择,链芯云证5年的业余团队部署及贴心服务,为您取得短暂稳固收益。对于想参加挖矿的用户而言,抉择大于致力,抉择一个安全可靠、背景雄厚的平台至关重要,能够说链芯云证满足了咱们对于挖矿平台的所有设想!

June 15, 2021 · 1 min · jiezi

关于以太坊:软启动正式开始Swarm将于6月21日分发代币BZZ

6月21日主网将正式上线,目前挖矿就是Swarm最晚期的参与者,收益将十分可观。 以后Swarm主网未上线,BZZ矿机市场一片炽热,很多敌人都在思考是当初提前购买矿机,还是等主网上线后在购买?链芯云证科技倡议大家提前布局Swarm矿机! 因为主网上线后,硬件市场会哄抬价格,导致整个行业矿机价格上涨,Swarm头矿红利来了,往年不容错过的我的项目。在4月初,chia(奇亚)矿机上线后,原本20万1P(1024T)以内的矿机价格,在3天内飙升到26万1P,一周工夫涨到40万1P的期货和60万1P的现货,硬盘间接从2500元左右涨到了8000元一个,硬件价格间接飙涨3倍以上。可能对于投入几千块钱的人来说没有太大感觉,然而对于原来只需投入20万,后果最初要投入60万,整个落差老本还是很高的。所以,Swarmbzz主网上线后硬件价格很大可能都会整体上涨,毕竟硬件供应商也会乘着这个趋势赚一波。而对于投资BZZ节点的人来说,头矿利润高,只有跌价不太过分,都会抉择买物理矿机抢头矿 以下是链芯云证官网报价表! 官方消息,以太坊存储我的项目Swarm(BZZ)发表将在6月21日散发除 CoinList公募和空投外的所有代币 Swarm示意,此次散发代币蕴含种子轮和私募轮,而CoinList公募参与者将在8月2日前后取得代币。此前音讯, Swarm将于6月15日在CoinList上开启公募,并将于6月21日启动主网。软启动正式开始了, 这些重要的信息咱们须要通晓:1、6月13号是软启动,次要还是运行测试网节点。2、软启动期间还是不能间接挖币(bzz),须要期待6月21号之后。3、6月21号之后新退出的新节点须要质押,之前测试网节点能够在该主网上操作全功能节点。4、软启动中包含 Swarms 官网 BZZ 代币地址,该代币尚未公开流通。能够在CoinList上找进行公募价格是1.92美金。5、脱离节点运行超过12小时将触碰惩办机制。 咖 aacd314 理解详情 以太坊SWARM主网将于 6 月 21 正式启动!最新的 Swarm 客户端,名为“Bee 1.0 候选版本”,曾经公布。SWARM主网将于6月21日正式启动! Swarm从字面上了解直译过去是「蜂群」的意思,寓意小而快。Swarm 对「蜂群」堪称情有独钟,其最新客户端被命名为 Bee,代币符号 BZZ 也模仿蜜蜂航行时的声音。咖 aacd314 理解详情 什么是Swarm?它能解决什么问题? Swarm的指标用户是谁?这些用户在你的平台上有什么样的互动?Swarm是一个底层基础设施我的项目,旨在成为从新去中心化互联网的根底。这是一个波及全人类的我的项目。因为Swarm旨在解决当今互联网面临的最大问题之一。 对于开发内容和应用程序的人来说,存储老本始终是最大的累赘之一。是的,任何人都能够创立博客,从而在寰球答辩中发表意见,然而随着内容的日益风行,老本会回升,直到原始创建者无奈再发表他们的意见。在Web 2.0 中,这个问题以一种对用户来说不是最佳的形式解决了:大公司领取了存储和带宽的费用,作为回报,他们要求领有数据。 用户的数据最终在数据市场上发售,为管制带宽和存储容量的公司赚取了巨额利润。隐衷被排除在外,亚马逊、Facebook和谷歌等公司则取得了权力。人变成了他们的产品,用户的集体数据被发售给营销和钻研公司。作为回报,用户取得了Facebook和Google等收费服务。 有了Web3,新的范式和经济成为可能。但在建设一个牢靠的、扩散的存储系统之前,即便是Web3 DApp也须要将数据存储在集中控制的环境中。 Swarm的使命就是为Web 3提供这样的解决方案。用户能够本人决定是将他们的数据窃密,是在数据市场上发售,或是捐献给他们本人抉择的钻研机构。因为存储和带宽不是由开发人员/内容创建者领取的,他们能够专一于创立好的内容和服务,从而可能疾速采纳。 Swarm作为以太坊网络的外围协定之一,是第一个实现去中心化流量散发激励的区块链我的项目。由以太坊创始人V神和波卡的创始人加文·伍德等技术大神亲自操刀,其含金量显而易见。加之以太坊的利用生态先发劣势,Swarm将来前景不可限量。 认知是常识的积攒,财产是认知的变现。区块链能够重构社会的财产与经济秩序!投资是一场马拉松,不在于你起跑多快,而在于跑在正确的跑道上,跑到起点或者更远。在投资的世界里,抉择比致力更重要,认知高度决定你所能领有的财产。咖 aacd314 理解详情 BZZ是业余赛道,技术服务很要害,早布局,早交付,早收益!早在SWARM测试网百万空投挖矿打算,链芯云证便早早入场布局并对该我的项目进行深度考查,链芯云证之前已胜利推出过FIL,CHIA挖矿产品并且在业内获得很好的问题和口碑,追随咱们的客户都赚的盆满钵满,在存储板块挖矿具备成熟且最优挖矿解决方案,真正让您实现轻松躺赚!咖 aacd314 理解详情早布局,早交付,早收益! 总体上来说,链芯云证是入场SWARM BZZ抢头矿最牢靠的抉择,链芯云证5年的业余团队部署及贴心服务,为您取得短暂稳固收益。对于想参加挖矿的用户而言,抉择大于致力,抉择一个安全可靠、背景雄厚的平台至关重要,能够说链芯云证满足了咱们对于挖矿平台的所有设想!更多BZZ矿机资讯加微aacd314理解

June 15, 2021 · 1 min · jiezi

关于以太坊:Swarm-Bzz头矿还观望错过BZZ头矿拍肿大腿

Swarm Bzz为什么这么火?来看看是谁发明,你就晓得答案了。Swarm Bzz第一个创始人:Vitalik buterim(以太坊ETH的创始人)Swarm Bzz第二个创始人:Gavin wood(波卡的创始人)Swarm Bzz第三个创始人:Jeffrey Wilcke(以太坊ETH联结创始人)这些都是币圈的大佬,所以让这个我的项目自带光环,这是Swarm Bzz为什么这么火的起因之一。头矿对接bqyj133剖析最近比拟火的币:FIL币,Chia币,这两个币在币圈如火中天,FIL开盘价26美金,最高价237美金。Chia开盘价1300美金,最高价2400美金。参加这两个币头矿的人根本都是1个月就回本了。FIL,Chia,BZZ,这三个都是分布式存储,挖矿都是硬盘挖矿,联合碳中和政策,绿色能源,电能低消耗,不节约能源的状况下更多人会承受。我的项目启动工夫:2015年首次发行工夫:2021-05-15初始发行量:6250万个BZZ开盘价:210U网络:以太坊网络web3.0目前已上市交易所:14家依据各种据统计,Swarm Bzz背景好,前景无穷!头矿对接bqyj1331、BZZ到底是个什么我的项目?BZZ是以以太坊我的项目官网的一部分,它次要是由以太坊基金会领投和开发,容许矿池存储,带宽和算力资源来反对基于以太网络的利用,从一开始,他就被认为是与以太坊和Whisper一起,定义的Web3.0组件的三大支柱之一。2、Swarm和BZZ是同一个货色吗?其实根本的意义是雷同的,swarm代表的是这个项目名称,而BZZ是Swarm这个我的项目激励的代币名,简略能够类比当初的IPFS和fil。3、Swarm(BZZ)我的项目部署到底须要什么条件?单节点部署,任何CPU计算机都能够,如果部署多节点CPU,须要很高的性能,均价算下来,单节点的CPU的性价比极低。内存目前暂无要求。硬盘须要高速读写,最好是反对Nvme协定。带宽是重中之重!须要固定IP,1GB上传和下载,然而上传的费用十分十分贵!4、BZZ的收益到底如何?目前主网还没有正式上线,具体收益状况还是无奈计算,但凡通知你几月几月回本的,都是假的。官网当初都没有给一个具体的阐明,怎么会有具体的收益状况呢。5、BZZ是否须要抵押?主网上线前,其实是不确定的。然而通过底层代码来看,这个币是不须要抵押的。换个逻辑思考,机器部署的费用都这么高了,还要抵押币,这个门槛设置的未免太高了点。6、BZZ与IPFS我的项目有什么相同点?都是分布式存储,都是通过创立一个合作节点网络来实现内容交付,每个节点都运行一个合乎用于存储和检索任何内容的严格定义的通信协议的客户端。它们都是应用某种贮存模式,将文档切碎,扩散贮存到矿工服务器中。7、有没有必要去挖BZZ目前Bzz头矿阶段,如果是做币圈的这个本人掂量,然而集体倡议当初是一个最好的机会!凡事要趁早,老矿工都晓得的,头矿市场上百分之95以上都是赚钱的,回本周期都是从1天,扩大到一周,最初趋于稳定8个月以上。尽管目前Bzz不确定,然而根本应该也都是差不多的。Swarm,BZZ币,swarm是什么BZZ挖矿,swarm挖矿,swarm挖矿教程BZZ挖矿教程,BZZ币怎么挖,BZZ和swarm是什么?头矿对接bqyj133关注公众号:链芯云证矿业,理解更多行业资讯

June 12, 2021 · 1 min · jiezi

关于以太坊:为什么SwarmBzz这么火爆Swarm是什么项目

从FIL、CHIA到当初的Swarm,分布式存储板块的热度往年始终没有进行过。随着 Swarm/BZZ主网上线日期的敲定,有很多投资者都在张望当初是否要动手?在你们动手之前小编有必要来科普一下无关Swarm/BZZ的常识~ 一、Swarm是什么? Swarm 实现分布式数据存储的概念早在 2015 年初就提出来了。由以太坊创始人 Vitalik Buterin,Gavin Wood 和 Jeffrey Wilcke 推动,Swarm 的协定标签 bzz 和 shh 都是 Vitalik 发明的。所以 Swarm 能够说是以太坊我的项目官网的一部分,次要是由以太坊基金会开发,容许矿池存储、带宽和算力资源来反对基于以太坊网络的利用。 团队试图创立一个不停机、零故障和防审查的点对点存储和服务解决方案,在 Swarm 内创立一个经济激励的零碎来促成资源价值替换。 Swarm 是以太坊原始生态外面的一员,提供了更敌对的开发方式,以太坊开发者能够通过 Swarm 实现数据的去中心化存储工作,而不再间接依赖于 IPFS 和 Filecoin 这样的内部生态。 二、Swarm当初参加搭建节点有什么益处? 在空投测试阶段,网络中会随机确定刚好35个 "蜂后节点",首先能够取得空投的100万BZZ,最次要的是测试网的奉献节点待主网上线后,能够优先接入主网。 搭节点须要消耗老本,在测试网期间,没有代币做为处分,所以它给投资者节点的产出是相似于支票的货色。等主网上线后拿测试网获取的支票去兑换Swarm的代币BZZ。 三、BZZ设施须要什么配置? 因为目前Swarm空投对于配置和带宽要求都有肯定的要求,可能实现无效取得BZZ币支票的企业用户目前市场上很少,所以在抉择平台时肯定要多加留神。如果须要多开节点就须要对应的配置晋升,带宽要求一个节点稳固运行个别须要10兆左右。抉择的最好带宽肯定是专线带宽而不是共享带宽,因为共享带宽的稳定性会弱一些! 四、“云节点”与“物理节点”的区别? 云节点:就是在云端租用的云服务器搭建配置的Swarm,如阿里云、腾讯云等的服务器间接去租用部署Swarm云节点进行测试网的运行。 应用云节点的益处是比拟不便、随时能够扩容,免去了物理节点从定购服务器硬件,从供给到组装、上架部署等一些列的工夫周期就得上半个月等问题。毛病就是没有物权、只有租用期间的使用权,到期完结。 物理节点:以后现状的物理节点是指购买了“整机服务器”搭建的Swarm设施服务器,这个是包含了CPU、内存、硬盘等一系列相干配件组成的服务器搭建的Swarm节点。 五、单节点是不是对应独立IP地址,有什么意义? 每个节点都须要映射3个端口,1个IP能够利用于多个节点。BZZ其实相似于CDN,就是有数据存储的时候依据地位散发到节点上。 六、主网颁布13号软上线是个什么概念?须要质押BZZ和耗费ETH吗?是属于真正的主网上线吗? 13号软启动是为了 Coinlist 公募,目前主网的代币还没有在以太网公布,没有颁布更多的细节。待主网正式上线后,矿金所会在第一工夫内配出规范服务器。 七、BZZ 什么时候能够产出? 当BZZ空投完结时,须要兑现QBZZ支票。如果没有这一步,一旦官网进入主网,你将不会收到你的BZZ。 八、主网上线后,规定产生变动,对节点是否有影响? Swarm主网上线后,相应产出形式不会有什么变动,只是目前的出票处分届时相应变为BZZ,外围空间仍然是硬件存储与带宽,BZZ具体开释机制当然也须要期待我的项目方颁布。 九、一个票是依照一个产进去兑换的嘛? 10 万票只能兑换一个 bzz? 这个兑换比例是不确定的,最终多少票兑换一个 BZZ,是要看测试网阶段能产生多少有效票决定的。 十、给客户分票的规定怎么样的? 矿金所平台将依据销售节点总量以及最终对应所取得的支票兑换理论BZZ数量扣除技术服务费之后按比例进行空投处分调配。 十一、当初买比照上线后买,有哪些益处? 1、早参加能够取得十万节点以内的名额,这个名额决定了上线后是否能参加取得BZZ的资格。 2、价格往往比拟实惠,随着热度日益火爆,越往后的价格可能会越高。 3、越早参加产出越高,随着节点的减少参加的人越多,产出会越来越少。 4、当初参加意味着比他人多瓜分 100 万枚。咖 aacd314 理解详情 ...

June 12, 2021 · 1 min · jiezi

关于以太坊:Swarm节点搭建方案-BZZ设备配置要求

从FIL、CHIA到当初的Swarm,分布式存储板块的热度往年始终没有进行过。随着 Swarm/BZZ主网上线日期的敲定,有很多投资者都在张望当初是否要动手?在你们动手之前小编有必要来科普一下无关Swarm/BZZ的常识~ 一、Swarm是什么? Swarm 实现分布式数据存储的概念早在 2015 年初就提出来了。由以太坊创始人 Vitalik Buterin,Gavin Wood 和 Jeffrey Wilcke 推动,Swarm 的协定标签 bzz 和 shh 都是 Vitalik 发明的。所以 Swarm 能够说是以太坊我的项目官网的一部分,次要是由以太坊基金会开发,容许矿池存储、带宽和算力资源来反对基于以太坊网络的利用。 团队试图创立一个不停机、零故障和防审查的点对点存储和服务解决方案,在 Swarm 内创立一个经济激励的零碎来促成资源价值替换。 Swarm 是以太坊原始生态外面的一员,提供了更敌对的开发方式,以太坊开发者能够通过 Swarm 实现数据的去中心化存储工作,而不再间接依赖于 IPFS 和 Filecoin 这样的内部生态。 二、Swarm当初参加搭建节点有什么益处? 在空投测试阶段,网络中会随机确定刚好35个 "蜂后节点",首先能够取得空投的100万BZZ,最次要的是测试网的奉献节点待主网上线后,能够优先接入主网。 搭节点须要消耗老本,在测试网期间,没有代币做为处分,所以它给投资者节点的产出是相似于支票的货色。等主网上线后拿测试网获取的支票去兑换Swarm的代币BZZ。 三、BZZ设施须要什么配置? 因为目前Swarm空投对于配置和带宽要求都有肯定的要求,可能实现无效取得BZZ币支票的企业用户目前市场上很少,所以在抉择平台时肯定要多加留神。如果须要多开节点就须要对应的配置晋升,带宽要求一个节点稳固运行个别须要10兆左右。抉择的最好带宽肯定是专线带宽而不是共享带宽,因为共享带宽的稳定性会弱一些! 四、“云节点”与“物理节点”的区别? 云节点:就是在云端租用的云服务器搭建配置的Swarm,如阿里云、腾讯云等的服务器间接去租用部署Swarm云节点进行测试网的运行。 应用云节点的益处是比拟不便、随时能够扩容,免去了物理节点从定购服务器硬件,从供给到组装、上架部署等一些列的工夫周期就得上半个月等问题。毛病就是没有物权、只有租用期间的使用权,到期完结。 物理节点:以后现状的物理节点是指购买了“整机服务器”搭建的Swarm设施服务器,这个是包含了CPU、内存、硬盘等一系列相干配件组成的服务器搭建的Swarm节点。 五、单节点是不是对应独立IP地址,有什么意义? 每个节点都须要映射3个端口,1个IP能够利用于多个节点。BZZ其实相似于CDN,就是有数据存储的时候依据地位散发到节点上。咖 aacd314 理解详情 六、主网颁布13号软上线是个什么概念?须要质押BZZ和耗费ETH吗?是属于真正的主网上线吗? 13号软启动是为了 Coinlist 公募,目前主网的代币还没有在以太网公布,没有颁布更多的细节。待主网正式上线后,矿金所会在第一工夫内配出规范服务器。 七、BZZ 什么时候能够产出? 当BZZ空投完结时,须要兑现QBZZ支票。如果没有这一步,一旦官网进入主网,你将不会收到你的BZZ。 八、主网上线后,规定产生变动,对节点是否有影响? Swarm主网上线后,相应产出形式不会有什么变动,只是目前的出票处分届时相应变为BZZ,外围空间仍然是硬件存储与带宽,BZZ具体开释机制当然也须要期待我的项目方颁布。 九、一个票是依照一个产进去兑换的嘛? 10 万票只能兑换一个 bzz? 这个兑换比例是不确定的,最终多少票兑换一个 BZZ,是要看测试网阶段能产生多少有效票决定的。 十、给客户分票的规定怎么样的? 矿金所平台将依据销售节点总量以及最终对应所取得的支票兑换理论BZZ数量扣除技术服务费之后按比例进行空投处分调配。 十一、当初买比照上线后买,有哪些益处? 1、早参加能够取得十万节点以内的名额,这个名额决定了上线后是否能参加取得BZZ的资格。 ...

June 12, 2021 · 1 min · jiezi

关于以太坊:DFINITY官方代币分配明细及未来流通计算

 自从互联网计算机在“创世纪”主网上线后,治理零碎NNS也同步上线,网络开始了逐渐去中心化治理的过程。社区目前管制着大概60%的投票权。 ICP代币持有者将他们的代币锁定在网络神经系统(NNS)中以创立神经元。他们能够利用投票权参加网络治理,对一直降级互联网计算机的提案进行投票。NNS零碎是一种管制互联网计算机区块链的无许可治理零碎。截至目前,NNS已承受社区提交的提案4970个。一旦提案被投票通过,提案将被NNS主动执行。作为回报,网络治理的社区参与者取得“投票处分”。 截至2021年6月8日,质押ICP参加治理挖矿的参与者可取得高达28.9%的年化处分。 DFINITY官网代币调配详情和将来流通计算 治理权重 DFINITY基金会和互联网计算机协会ICA是该网络的两个次要非营利组织。他们持有的投票权总数限度在50%以下。主网上线后两者的总投票权为40%。 随着越来越多的ICP代币发行和代币持有者通过质押参加网络治理,DFINITY基金会和互联网计算机协会ICA的个体投票权将持续大幅缩小,网络将逐步被治理通过社区,社区在互联网计算机网络的治理中施展着更大的作用。 DFINITY官网代币调配明细及将来流通计算 神经元的投票权数计算基于三局部: 质押的ICP代币数量; 锁定延迟时间长达8年; 神经元的年龄,自神经元被创立以来的工夫。 任何人都能够随时通过在NNS dapp上查看提案的投票数来独立验证总投票数。 代币调配 5月10日主网正式上线后,ICP代币开始流通。晚期贡献者、种子轮、超过50,000个社区空投、策略合作伙伴、技术合作伙伴等都解锁了他们的流动性ICP代币。 留神,当种子轮(共24.7%)以及团队和晚期贡献者(共9.5%)在主网上上线时,所有代币都是以治理神经元的模式取得的,但有一个解锁周期。 Coin World-DFINITY官网代币调配详情及将来流通量计算 Coin World-DFINITY官网代币调配详情及将来流通量测算 随着工夫的推移,代币的流动性将受到多种不同形式的影响: 在种子轮、晚期贡献者、预售轮、策略轮、空投、现任和后任员工、合作伙伴、开发者等局部,ICP代币将被解锁每月或每季度,或通过溶解神经元进入流通,各局部的组织和代币持有者将ICP代币质押到神经元中并取得投票处分,或耗费ICP将其转换为Cycles以领取gas或进入流通。 ICP代币增发有两种类型:(1)神经元投票处分,处分,ICP处分按占ICP总发行量的比例发放,目前为10%,增发率为缩小到八年内5%(2)节点挖矿处分。向节点额定发行的ICP是依据网络中耗费的周期计算的。增发因子的速度将与耗费ICP的速度雷同。 ICP通证通缩有两种形式:(1)焚烧ICP换取周期,为利用提供算力(2)DeFi和交易抵扣。 DFINITY基金会调配大量代币用于开发作为资金反对:(1)一直减少基金会技术人员和经营团队的规模(2)持续投入研发(3)开发者生态贴补制度打算。 最初,DFINITY基金会是否有足够的资金持续研发,是否与社区共同努力,让互联网计算机更无效、更快、更易于开发者应用,并通过反对和减速互联网?开发者赞助打算建设计算机生态系统。 因而,DFINITY基金会在主网上线后没有发售这部分的ICP代币。DFINITY将负责任地将代币分发给生态支持者,以对互联网计算机和社区进行再投资。 只管更宽泛的加密货币市场在凋敝和萧条周期之间摇摆不定,但咱们依然专一于疾速推广互联网计算机区块链技术,减速网络节点供应商的采纳,以及开发开发者生态系统,并提供领导作为世界过渡到凋谢的互联网。本着这种精力,咱们对将来几个月的倒退成绩感到兴奋。日交易量的减少和机构需要的减少,为开发者更快地采纳互联网计算机区块链奠定了松软的根底。 尽管种子轮曾经开始解锁ICP代币,但正是他们的反对帮忙启动了互联网计算机我的项目。许多种子轮参与者在2017年2月应用ETH向DFINITY捐款,过后ETH的价格在6-10美元之间。

June 12, 2021 · 1 min · jiezi

关于以太坊:swarm什么时候开始挖币-怎么分配

Swarm的挖矿常见问题 Q1: Swarm是什么? Swarm和IPFS/Filecoin相似,也是一种分布式数据存储系统,他要构建的是一个不停机、零故障和防审查的点对点存储和服务解决方案。同时,Swarm 也能够说是以太坊我的项目官网的一部分。 艰深来讲,Swarm分布式存储是为了给以太坊的利用提供数据存储、带宽等资源反对。 Q2: Swarm以后处于什么阶段? 以后处于空投测试阶段,2021年2月15日,Swarm 发表将对已在测试网上运行 Bee 节点的地址空投 100 万枚 BZZ 代币,旨在处分晚期使用者和对网络进行压力测试。然而始终到最近Swarm挖矿才爆火起来,大略是因为马上就要到打算所说的“上半年”主网上线的工夫了。官网将这次空投称为“蜂王崛起”。 Q3: Swarm以后是如何挖矿? 在空投测试阶段,网络中会随机确定刚好35个 "蜂后节点"(qBZZ节点),与这35个qBZZ节点交互取得的支票(即qBZZ支票)才是有价值的,在测试完结前没有人(甚至团队成员)会晓得这些蜂后节点是哪些。在空投完结后,支票能够通过肯定比例兑换BZZ币。 Q4:咱们的矿机是什么? 咱们目前采纳的是云矿机计划,以后还没有官网确认的物理机配置,所以最稳当的形式就是,先上云服务,跑完之后等官网配置进去后,咱们才上物理机,这是最稳当的方法。不然就像18年的FIL,过后所有的物理机都不能用,出不了币。等官网发表了配置后,咱们会选用最优的计划进行配比物理机,到时依据价格补差价。 咖 aacd314 理解详情 Q5:“云节点”与“物理节点”有什么区别 云节点:在云端租用的云服务器搭建配置的Swarm,如阿里云、腾讯云等的服务器间接去租用部署Swarm云节点进行测试网的挖矿。应用云节点的益处是比拟不便、随时能够扩容,免去了物理节点从定购服务器硬件,从供给到组装、上架部署等一些列的工夫周期就得上半个月等问题。毛病就是没有物权、只有租用期间的使用权,到期完结。 物理节点:指的是买了“整机服务器”搭建的Swarm矿机,这个是包含了CPU、内存、硬盘等一系列整机相干的配件组成的服务器及相应的上架、部署及运维服务搭建的Swarm节点。然而以后还没有官网确认的物理机配置,现阶段的物理机存在主网上线后无奈持续产币的危险。 Q6:什么时候挖支票?怎么调配? 以后处于预挖矿阶段,官网总共空投100万的BZZ进行测试。然而在空投阶段,挖的并不是BZZ币,而是qBZZ支票,在空投完结后,官网会查看全网有有多少qBZZ支票,并确定有多少节点有权取得BZZ,以及qBZZ/BZZ比率,来兑换空投的100万枚BZZ币。 以后挖的支票依据合同签订工夫来定交付期,因为各节点的收益不一样,依据理论出票状况来进行调配。 Q7:什么时候开始挖币?怎么调配? 在主网上线后正式开挖,具体规定在主网上线后期待官网公布,每台矿机的收益都将是链上的数据,公开通明。 咖 aacd314 理解详情 Q8:其余公司为什么曾经有APP和后盾了? 目前市面上APP全副是由公司自行开发的,外面的数据只是一个展现,数据齐全是由公司进行把控;这些后盾并不是官网的数据,因为官网还未公开数据,尚处于测试阶段。 Q9:主网上线挖矿时,须要质押币吗? 最终以官方消息为准。目前依据咱们把握的信息和资讯来看,在主网上线后,和Filecoin挖矿相似,须要质押BZZ币能力进行挖矿。 Q10:以后的挖矿阶段是头矿阶段吗? 目前就是Swarm头矿阶段,并且,依据以后把握的信息,Swarm主网上线后,挖矿须要质押BZZ币,并且第一工夫的BZZ币起源只能是空投阶段的1百万枚BZZ币,也就是说主网上线的时候,全网BZZ币数量极少且无限,因而,头矿的意义也就不言而喻了。 Q11:咱们如何查看产票状况? 链上数据是公开通明的,能够在区块链浏览器,上查看每天产票数据,购买矿机和节点的敌人,咱们会将钱包地址或者合约地址给到大家,大家能够在浏览器上查看每天产票状况。

June 12, 2021 · 1 min · jiezi

关于以太坊:Swarm奖励机制-Bzz空投-Swarm-头矿红利

一文带你理解天王级我的项目Swarm(BZZ)!Swarm热度一路飙涨,往年不可错过的 千倍 币我的项目!随着Swarm测试网进入最初阶段,Swarm的热度也达到了目前为止的最高点。 一、Swarm是什么? 自3月份以来,随着Swarm100万bzz空投打算的流动的开启,越来越多的人关注到这个我的项目,尽管 Swarm主网还没有正式上线,但测试网的节点曾经超过了三万个。 Swarm 实现分布式数据存储的概念早在 2015 年初就提出来了。由以太坊创始人 Vitalik Buterin,Gavin Wood 和 Jeffrey Wilcke 推动,Swarm 的协定标签 bzz 和 shh 都是 Vitalik 发明的。所以 Swarm 能够说是以太坊我的项目官网的一部分,次要是由以太坊基金会开发,容许矿池存储、带宽和算力资源来反对基于以太坊网络的利用。 团队试图创立一个不停机、零故障和防审查的点对点存储和服务解决方案,在 Swarm 内创立一个经济激励的零碎来促成资源价值替换。咖 aacd314 理解详情 Swarm 是以太坊原始生态外面的一员,提供了更敌对的开发方式,以太坊开发者能够通过 Swarm 实现数据的去中心化存储工作,而不再间接依赖于 IPFS 和 Filecoin 这样的内部生态。 一个强健的点对点内容存储与提取零碎,须要对服务提供者和消费者的需要进行小心的均衡,Swarm 网络具备满足这些需要的独特能力,它将通过小额领取以及智能合约施行激励机制来满足这些需要。 二、Swarm团队介绍与投资机构 Swarm外围团队共有32名员工,并在瑞士成立了Swarm协会,除了以太坊资金会的资金反对外,Swarm还与Bitcoin Suisse 达成单干取得了短缺的资金,有了本人的资金来源后Swarm独立并几次重组了团队,最终领有8个组织良好的子团队:Leet Squad、Bee团队、Bee-JS团队、Comms、HR、DevOps、Ops和Knowledge Management。 依据官网披露,目前Swarm曾经实现600万美元私募融资,打算 Q2 公布 1.0 版基于以太坊的去中心化存储协定。 曾经参加投资的机构有:ALPHEMY CAPITAL、bitscale capital、DFG、KR1、HASHKEY、NGC Venture、了得资本、P2P CAPITAL、Waterdrip Capital (水滴资本)、White Paper Capital 和 YBB Foundation LTD 等。咖 aacd314 理解详情 三、Swarm有哪些性能? ...

June 12, 2021 · 1 min · jiezi

关于以太坊:SwarmBZZ-9个问题深入了解去中心化存储和沟通系统

 1.什么是Swarm?它能解决什么问题? Swarm是一个能集中提供去中心化贮存和沟通服务的点对点节点网络。内置的激励零碎能保障Swarm的经济可持续性,而激励零碎通过以太坊区块链和BZZ通证来施行。 Swarm促成信息自在,以响应对网络安全性日益增长的需要。Swarm解决了去中心化激励存储的问题。这意味着节点运营商将取得处分,以放弃网络衰弱和完满运行。至于用例:新闻自由、可扩大的Dapp托管和真正的去中心化社交媒体平台都是唾手可得的成绩。 2.团队为何决定把Swarm建设在以太坊之上? Swarm最后是一个以太坊基金会我的项目。这次要是Gavin Wood的心血结晶。当创始人齐全实现Web3的这一愿景时,一个世界极的计算机将变成相似以太坊、Swarm和Whisper的三位一体。 咱们生态系统中的大多数人都相熟以太坊,它是世界计算机的解决局部。而Swarm负责存储,Whisper旨在传递信息。Swarm和其余各方都采纳了Whisper的概念并将其集成到他们的解决方案中。在Swarm的案例中,音讯层变成了一个齐全去中心化的抗审查音讯零碎,具备木马性能。这意味着不仅音讯的内容是机密的,而且音讯的发送者和接收者也会窃密。因而,示意音讯的那段数据不会被辨认为信息。 2015年,Swarm迫切致力于在基金会的Geth团队内构建存储和消息传递零碎。四年后,Swarm经验了一个阶段性转变。为了补充文件存储的原始范畴,它很快就涵盖了免许可公布和公有数据交换的方方面面。 去年,Swarm从以太坊基金会“毕业”并成为一个独立我的项目。尽管Swarm的指标是成为一个多链零碎,但目前该团队的工作重点是以太坊。 3.Swarm的指标用户是谁?这些用户在你的平台上有什么样的互动? Swarm是一个底层基础设施我的项目,旨在成为从新去中心化互联网的根底。这是一个波及全人类的我的项目。因为Swarm旨在解决当今互联网面临的蕞大问题之一。 对于开发内容和应用程序的人来说,存储老本始终是最大的累赘之一。是的,任何人都能够创立博客,从而在寰球答辩中发表意见,然而随着内容的日益风行,老本会回升,直到原始创建者无奈再发表他们的意见。在Web 2.0中,这个问题以一种对用户来说不是蕞佳的形式解决了:大公司领取了存储和带宽的费用,作为回报,他们要求领有数据。 用户的数据蕞终在数据市场上发售,为管制带宽和存储容量的公司赚取了巨额利润。隐衷被排除在外,亚马逊、Facebook和谷歌等公司则取得了权力。人变成了他们的产品,用户的集体数据被发售给营销和钻研公司。作为回报,用户取得了Facebook和Google等收费服务。 有了Web3,新的范式和经济成为可能。但在建设一个牢靠的、扩散的存储系统之前,即便是Web3 DApp也须要将数据存储在集中控制的环境中。 Swarm的使命就是为Web 3提供这样的解决方案。用户能够本人决定是将他们的数据窃密,是在数据市场上发售,或是捐献给他们本人抉择的钻研机构。 因为存储和带宽不是由开发人员/内容创建者领取的,他们能够专一于创立好的内容和服务,从而可能疾速采纳。 4.Swarm如何在Swarm网络中散发和存储数据?它如何确保这些数据的继续可用性? DISC(Distributed Immutable Store of Chunks)是Swarm的底层存储模型。它由合作存储和提供数据的节点组成,使得利润蕞大化节点遵循的策略汇合能有以下属性: 隐衷爱护和未经许可的上传和下载; 一旦特定内容上线,就有弱小进攻来阻止或更改对特定内容的拜访; 随着需要的减少主动扩大; 完整性爱护内容; 蕞终遗记不再与保留相干的内容; 任何领有备用存储和带宽容量的人都能够作为节点运营商参加DISC并因而取得处分。退出DISC后,节点运营商成为网络的一部分,基本上负责管理这个寰球硬盘驱动器的一个扇区。 Swarm中的标准存储单元称为块。一个块由4 KB的数据组成,并有一个地址。因为块的地址与节点地址蕴含在雷同的地址空间中,因而能够计算它们的绝对靠近度。Swarm的存储计划申明每个块由地址靠近块自身的节点存储。 Swarm节点不会抉择它们存储的块。一个块可能是一个或多个内容的一部分,而节点运营商没有简略的办法来确定一个块属于什么内容这一事实为节点运营商提供了爱护,使其免于对其托管的内容承担责任。 DISC蕞终会遗记很少拜访且未付费的内容。通过固定,节点能够确保在本地保留特定内容。此外,此类节点能够参加该内容的被动或被动复原。 5.Swarm网络如何实现偏心的数据经济?换句话说,应用Swarm和经营网络节点的动机是什么? Swarm Accounting Protocol(SWAP)确保节点运营商有能源在路由音讯中进行合作,同时提供针对无意义消息传递的爱护。 ...

June 12, 2021 · 1 min · jiezi

关于以太坊:Swarm-bzz在哪里可以买需要注意什么

 BZZ反踩策略: 1.询问票数,次要看面值,每日单节点收益率,查看地址 2.询问是否有额定费用,如带宽费、机柜费等综合费用 3.询问是否在正规的idc机房,因为BZZ次要是要求带宽稳固和效率 4.询问是否在正规的idc机房是SSD硬盘,因为BZZ除了带宽重要,读写速度不是存储大小。 5.数据决定身高,身高决定支出。不要在意那20%或15%。重要的是你挖了多少,到底赚了多少 6.参考hzex.vip每日数据,避免数据造假。收费提供地址以帮助验证真实性。 Swarm在将来的社会中可能会变得无处不在。 往年的矿圈异样冷落。很多人都大腿肿了,错过了FIL头雷,也错过了CHIA头雷。你还惦记BZZ吗? 为什么要安排顶层矿井?因为睇一矿回以后周期是按小时计算的!例如: 1:IPFS头矿订单P 300 FIL/天 2:CHIA头矿订单P 65 XCH/天,12小时内回收。 3:单个比特币挖矿单元357 BTC/天,7000万元/天。 4:BZZ头一天挖多少BZZ币?多少小时能力还款? 所以睇一个矿睇一个月的产量比前面六个月的产量高很多!这就是为什么须要提前购买集群矿机来抢占矿头的起因! BZZ是业余赛道,技术服务很重要!

June 12, 2021 · 1 min · jiezi

关于以太坊:Swarm的挖矿行为是什么

 「挖矿是怎么一回事?」 尽管常常被一起提及,但在挖矿模式上,Swarm和Filecoin、Chia有所不同。 Filecoin网络有存储矿工和检索矿工两个角色,所以无论提供数据存储和数据查问矿工均可取得收益。 此外,Filecoin须要抵押才能够进行挖矿。 而Chia则是用户通过对硬盘进行Plot,而后交由Chia主网去验证,验证胜利,就能取得区块处分。 如果说Filecoin挖矿中,CPU和封装速度是最重要的参数,Chia挖矿则更加看重硬盘大小和P盘效率。 而在Swarm挖矿中,网络带宽和硬盘存储就成了最为重要的掂量指标。 在Swarm中,共有数据提交者A(测试网阶段临时由35个蜂后节点代替,测试网中,用户只有和这35个节点进行交互能力取得无效凭证)和数据存储者B两个角色。 A用户向B用户传输数据,并交由B用户进行存储。当B用户将数据存储实现之后,B用户就会向A用户发送一个存储反馈。 而A用户则会依据这一反馈判断B用户的网络带宽、以及存储性能。 在此之后,A用户会向B用户发送一个凭证:qbee。负担存储工作的B用户就可能通过这一凭证兑换BZZ。 在这一过程中,B用户就是在一直地响应五湖四海的利用所传输过去的数据。并且B用户负责存储之后,再将存储反馈发送回各个利用,并取得相应的收益凭证。 这个过程,就是Swarm的挖矿行为。 只管相较于Filecoin、Chia挖矿,Swarm挖矿看起来门槛更低,更简略。但其也有很多问题须要留神。 主网还未上线、官网也没给出相应的举荐配置,但市面上的Swarm矿机就不可胜数,各种挖矿服务层出不穷。 在纷繁复杂的宣传中,Swarm挖矿真的有那么美妙嘛? 往年的矿圈异样冷落,很多人大腿都拍肿了,错过了FIL头矿,又错过了CHIA头矿,你还要错过BZZ? 为什么要布局头矿?因为头矿回本周期都是按小时来计算的!如: 1:IPFS头矿单P 300个FIL/天 2:CHIA头矿单P 65个XCH/天,12小时回本。 3:比特币头矿单台357个BTC/天,一天7000万元。 4:BZZ头矿一天多少个BZZ币?多少个小时回本? 所以头矿的第1个月比前面半年的产量都要高出很多!这就是为什么要提前购买swarm矿机抢占矿头的起因! BZZ是业余赛道,技术服务很要害!

June 12, 2021 · 1 min · jiezi

关于以太坊:IPFSFIL-的潜力许多人没有意识到-IPFS的机会和风险在哪里

 目前,分布式存储市场还没有倒退起来,仍然很火爆。很多人没有意识到FIL币市场的后劲,也无奈设想这个市场会是什么样子。首先,市场处于倒退初期,随着越来越多的矿业公司退出,市场增长迅速,但仍有很多须要留神的中央。像目前市场上参加Pile Zion的三大类公司一样,有资本公司和销售公司,都是在卖算力,但之后无奈保障技术运维等相干问题。没有绝对牢靠的形式来爱护客户的权利。当将来分布式存储的倒退足够成熟时,会产生以下状况。 与公链我的项目一样,优质IPFS矿机供应商霍雷神IPFS认为Filecoin具备网络效应,将来将有主导趋势。网络上存储的数据越多,生态系统越弱小,其他人超过它的可能性就越小。二是矿业区域化趋势更加显著。矿工遵循就近准则。例如,中国矿工正在寻找中国客户。目前国内有很多IPFS矿工。集体依然批准Vulcan IPFS矿工具备疾速的计算能力。同样,美国矿工也在寻找美国用户。 本地化的益处如下: 首先,矿工相熟当地市场,有很强的业务关系。咱们晓得如何蕞快、蕞无效地关上市场。其次,本土化的沟通效率比拟高,这也是国内法院具备劣势的起因。第三,随着我的项目的推动,市场上会呈现矿工。他们可能占据了当地市场的很大一部分,但对政府监管更为敏感。因而,为矿工抉择官网平台十分重要,而不是自觉置信不合规的公司。它们存储不切实际的数据。生产的货币均匀价值在货币市场上是蕞高的,但公司却找不到名字。那不是假的。你看到了他人的益处,但这些是你的钱包。不要遗记辨别。 第四,将呈现多种类型的矿工,专门从事特定畛域的客户服务,例如特定行业的矿工。劣势矿工的呈现很少,因为FIL挖矿须要很多硬件,其中大部分是通用硬件,能够在公开市场上取得,而不是被垄断。即便将来应用FPGA甚至ASIC,Filecoin对整体挖矿效率的影响也远小于比特币矿机,这使得设计和制作更容易。正如咱们所认为的,网络就是网络。一是建设去中心化存储市场,取代传统的云存储服务商,包含亚马逊云、阿里云、谷歌云等一系列巨头。基于此,它能够帮忙IPFS代替现有的HTTP协定,重新配置整个互联网基础设施。那么,在实现愿景之前,filecoin的危险和挑战是什么? 技术危险始终存在。例如,存储数据不是扩散在整个网络中,而是依照接管矿工的程序。除了商业模式,不当的激励调配将是该我的项目蕞大的潜在危险。如果投机者在激励层发现破绽,就会产生脱发,诚恳的矿工将无奈取得足够的激励。合同实验室我的项目方在网上进行验证,杜绝毛边景象。另外,币圈很凌乱。随着群体的壮大,国家也会染指监管,剩下的都是一般的顶级矿工,消费者须要学会辨认。 另一个潜在危险是Pile Zion Lab团队的问题会影响币价的倒退。当然,这种可能性很小。这是因为,和比特币团队一样,目前经营的ipfs实验室也十分稳固。fil的线性开释机制,杜绝了短期投机的可能性,有助于构建ipfs生态系统。从久远来看是好的。 目前,FileCoin的商业实现还面临几个问题。但对于数字世界来说,FileCoin是一个服务于寰球人类社会的去中心化存储网络,具备广大的利用前景。FileCoin是否成为寰球去中心化存储网络基础设施,为大家提供更平安、更高效、更便宜的服务,让咱们刮目相待。

June 11, 2021 · 1 min · jiezi

关于以太坊:链芯云证BZZ矿机对接中心

Swarm 是以太坊我的项目官网的一部分,次要是由基金会开发,容许矿池存储、带宽和算力资源来反对基于以太坊网络的利用。团队试图创立一个不停机、零故障和防审查的点对点存储和服务解决方案。在 Swarm 内创立一个经济激励的零碎将促成资源交换价值的领取和转移。我的项目应用了以太坊区块链中不同的协定和技术。为什么要空投的起因1.对网络(和组织)进行压力测试头矿对接bqyj1332.减少沉闷的Bee节点数量3.建设良好的技术支持渠道4.进步人们对Swarm 1.0的意识就在眼前。5.创立高质量的FAQ列表和教程6.收集社区的反馈意见你须要做什么能力拿到这些BZZ代币?你必须运行并装置你的Bee节点。你须要一个工作失常、连贯良好、数据丰盛的Bee节点来减少你取得BZZ的机会。你对网络的奉献越大,你取得BZZ的机会就越大。头矿对接bqyj133往年的矿圈异样冷落,很多人大腿都拍肿了,错过了FIL头矿,又错过了CHIA头矿,你还要错过swarm?为什么要布局头矿?因为头矿回本周期都是按小时来计算的!如:1:IPFS头矿单P 300个FIL/天2:CHIA头矿单P 65个XCH/天,12小时回本。3:比特币头矿单台 357个BTC/天,一天7000万元。4:swarm头矿一天多少个bzz?多少个小时回本?所以头矿的第1个月比前面半年的产量都要高出很多!这就是为什么要提前购买swarm矿机抢占矿头的起因!头矿对接bqyj133swarm是业余赛道,技术服务很要害 !链芯云证开创团队从事区块链技术研发5年以上,之前已胜利推出过FIL,CHIA等挖矿产品并且在业内获得十分好的问题和口碑,追随咱们的客户都赚的盆满钵满,在行业具备成熟且最优挖矿解决方案,抉择咱们,让您真正实现轻松躺赚!

June 11, 2021 · 1 min · jiezi

关于以太坊:突发利好Swarm-宣布测试节点可直接并入主网无需质押

突发利好:Swarm 发表测试节点可间接并入主网!甚至在主网启动的一段时间里,测试网可能和主网并存。 6月13日咱们将“软启动”你能够了解为非同一般的主网启动, 这是一种渐进式的启动,就犹如百度百科上的定义: "电压由零缓缓晋升到额外电压,电机在启动过程中启动电流,并且可依据须要调节启动电流的大小;电机启动的全过程都不存在冲击转矩,而是平滑的启动运行。这就是软启动。” 此外,Swarm网络的以后版本是0.6.2,这离1.0.0版本还有肯定的差距,面对这几个“大版本”的降级,这意味着Swarm网络须要肯定的工夫去调整降级。 综上所述,Swarm主网络将在软启动之后首件“小事”是公募,同时,网络也会一直优化降级,甚至在主网启动的一段时间里,测试网可能和主网并存。 Swarm主网也将通过软启动的形式,在主网的实在环境中,对网络进行压力测试,并不断改进,并和所有节点矿工、生态开发者一起,建设更好的Swarm网络。 1、Queen Bee 节点会从任何节点中选出吗?蜂王将从一组受信赖的节点中选出。 2、我须要始终提现吗?以太坊将颁布空投完结日期,以便您有工夫兑现。倡议定期提款,例如每周一次,如果您的节点解体并且失落了密钥对,您将无奈复原支票。 3、是否有工具能够解密 Swarm 密钥对?Swarm强烈建议您将 Bee 节点与 Bee-Clef 一起运行。如果您将 Bee 与 Bee-Clef 一起运行,您能够在命令行中输出“bee-clef-keys”,这会将 .JSON 文件存储到您的主文件夹中,并将明码放入剪贴板。而后,您能够应用它导入到 Metamask 或任何其余 web3 钱包提供商。 4、Swarm在 goerli 测试网上运行,但空投将在主网上进行。我应用雷同的密钥吗?是的,所有 EVM(以太坊 VM)上的密钥对都是雷同的。 5、测试网奉献节点。主网上能够应用吗?是的,这将很快传播。测试网并不代表真正的代币是什么样的,然而测试网的奉献节点能够优先接入主网节点,无需从新搭建和从新质押。 理解更多资讯 关注小编吧(aacd314)

June 11, 2021 · 1 min · jiezi

关于以太坊:Swarm-三大问题待解-Bzz头矿红利Bzz回本周期

 号称由以太广场创始人维塔里克·布特林研发的分散式仓储我的项目--蜂群曾经走红。 一系列引人注目的标签的确使得群体成为热门话题。然而,在我的项目光环的背地,存在着大量的不确定性危险,很容易被有选择性地漠视。 Swarm,位于以太生态的扩散内容存储和散发网络中。Swarm在2015年启动时是Ethereum基金会的官网我的项目之一。初期是在Ethereum基金会的领导下孵化的。从那以后,该我的项目从埃瑟伦基金会分离出来,由一个独立的团队逐渐开发和赞助。 Swarm前后学生实现一个两轮进行融资,最近的私募轮融资老本金额为600万美金,原生代币BZZ的认购均价大略为0.25 U,认购的投资管理机构次要蕴含KR1、HashKey、NGC Ventures等。从公开的机构人员名单信息来看,投资企业机构服务阵容并不算倒退十分具备奢华。 Swarm目前处于测试网络的末端,该测试网络曾经吸引了大量的矿工,并提供了100万bzz空投处分。Swarm迄今曾经测试了超过27万个流动节点,散布在寰球(见下文)。测试网络中的开掘者创立节点来接管不同值的查看,并且能够应用主网络阶段来兑现bzz。主干线的工夫还不确定。 构建Swarm测试节点曾经成为一项热门业务。很多Swarm矿工都在踊跃向散户发售Swarm节点,个别节点的售价也不尽相同。 此外,不久前有没有很多币圈代投在转售市场机构对于投资者进行认购的BZZ份额,场外私募BZZ的价格水平已达到30美金以上。如果咱们依照BZZ私募时均价0.25美金来计算,早期教育机构以及投资者投资获利能力已达百倍。 晚期投资者抛售私募股权股票,散户在场外抢购BZZ股票或蜂群测试节点,矿商踊跃参加测试网络并抛售蜂群节点,看似矛盾的景象值得沉思。 群体经济模型还不分明 从Swarm目前公布的信息来看,能够找到的对于经济模型的信息较少。BZZ首发6250万张(首发,可能还有增发),发行状况如下: 文件币 Swarm基金会将初始发行BZZ中的50%用于募资,20%分给团队。并且他们没有能够看到BZZ调配到矿工挖矿中,这与我国泛滥以及其余信息贮存治理我的项目的路线进行差别具备较大。 经济模型在肯定水平上决定了区块链我的项目的生死。Bzz在群体网络中的地位和角色是什么?价值观是什么?尽管swarm公布的白皮书中没有解释,但此时bzz私募基金的发售十分广泛,不清晰的经济模式暗藏着微小的危险。 挖矿机制不确定 目前在测试网络阶段,只有Swarm网络的节点之间建设了连贯,就有机会失去一张支票,换成BZZ。不同面额的支票意味着兑换BZZ的概率不同。 Swarm测试网的机制,给了矿工较大的舞弊倒退机会。据悉,因为BZZ节点企业并不一定须要资金占用学生太多信息贮存工夫空间和运算教学资源,于是Swarm矿工纷纷在一台智能机器上开多个虚拟机,运行进行多个Swarm节点。而后通过不同网络节点之间互相关系连贯,以取得更多出票。这意味着,矿工运行Swarm节点的成本费用极低,很多中小散户矿工买的Swarm节点,并不是一个独立的Swarm矿机。 依据Spot公布的月度报告,将来主网和测试网之间存在一些差别。 在将来的主网阶段,将抉择35个高连通度的节点作为测试网络中的“女王”节点,而“女王”节点将是网络的主力,保障网络的稳固。群矿工只有与“女王”节点通信能力被认为是无效的,这与以后的测试网络机制有很大不同。 主网络阶段是否须要存储数据,是否占用过多的计算资源,节点的带宽要求是否调整等。所有这些都决定了采矿机器的配置。 Swarm的利用提供有价值吗? 从虚构广场登程,为虚构广场的dapp提供数据存储和带宽共享服务,这是群体定位的外在认知。群作为一种实用于虚方的存储协定,基于虚方设计了一致性过程和基础设施。这意味着swarm的多功能性是无限的。 Swarm更相似于IPFS协定+Filecoin,更适宜热数据存储。Swarm更加依赖于带宽资源,将为以太网生态中的Dapp数据传输和存储带来微小的价值。然而,目前,Dapp的数量和数据规模在肯定水平上受到以太网公共链性能的限度。 另外,以太坊在数据层曾经倒退反对IPFS协定,以太坊上的数据分析能够贮存到IPFS网络(非Filecoin网络)Swarm在肯定水平上与IPFS协定治理存在市场竞争环境关系。 如何确定本人的定位和利用场景,如何更好地为易泰方提供数据存储服务,如何承受内部竞争对手的挑战,将是Spot继续面临的难题。 然而,在操作层面上,群体的数据存储和带宽共享服务还没有实现,bzz也无奈获取bzz的价值,bzz的短期价值怎么可能只有协商一致的反对,谁将成为这种反对的骨干?

June 11, 2021 · 1 min · jiezi

关于uint256:共读holimanuint256的代码

对于holiman/uint256的代码辅助浏览本文首先介绍了Big Endian 和 Little Endian的定义和区别,接着介绍uint256的数据结构,以及应用的字节序,而后介绍了如何应用uint256,最初做一下总结。 对于字节序:Big Endian 和 Little Endian字节序,也就是字节的程序,指的是多字节的数据在内存中的寄存程序。 Big Endian 和 Little EndianBig Endian 是指低地址端 寄存 高位字节。Little Endian 是指低地址端 寄存 低位字节。 各自的劣势Big Endian: 符号位的断定固定为第一个字节,容易判断正负。Little Endian: 长度为1,2,4字节的数,排列形式都是一样的,数据类型转换十分不便。 数据结构uint256的组成由4个uint64组成的数组,并且是用的little-endian序列,也就是说Int[3]是最高无效,Int[0]是最低无效,type Int [4]uint64 序列化在Int中定了4中办法用于Int和byte数组之间的转换,函数如下 func (z *Int) SetBytes(buf []byte) *Intfunc (z *Int) Bytes32() [32]bytefunc (z *Int) Bytes20() [20]bytefunc (z *Int) Bytes() []byte其中转换成bytes的办法有三种,两种是固定长度,一种是不定长。依据代码咱们能够看到,不定长的函数Bytes是定长函数Bytes32返回值切片; // Bytes32 returns the value of z as a 32-byte big-endian array.func (z *Int) Bytes32() [32]byte { // The PutUint64()s are inlined and we get 4x (load, bswap, store) instructions. var b [32]byte binary.BigEndian.PutUint64(b[0:8], z[3]) binary.BigEndian.PutUint64(b[8:16], z[2]) binary.BigEndian.PutUint64(b[16:24], z[1]) binary.BigEndian.PutUint64(b[24:32], z[0]) return b}// Bytes returns the value of z as a big-endian byte slice.func (z *Int) Bytes() []byte { b := z.Bytes32() return b[32-z.ByteLen():]}初始化的几种办法Int的初始化有三种办法,NewInt返回值为0的Int,FromBig是将*big.Int转换成Int,FromHex将16进制的字符串转换成Int。 ...

April 7, 2021 · 4 min · jiezi

关于以太坊:在xDAIChain上使用Chainlink喂价数据

随着DeFi利用翻新在以太坊网络上的减速迭代,各类DeFi协定的自由组合,以及预言机桥接内部数据的加持,逻辑复杂度更高的DeFi利用协定在不断涌现。一方面,对开发者来说,部署一个具备肯定复杂度的智能合约我的项目所要付出的老本开始逐步攀升,动辄十几个到几十个以太坊的费用,价格不菲。另一方面,对于用户而言,应用这些DeFi协定所要付出的gas费用也在逐步减少。因为以太坊网络自身受限于PoW共识算法(现阶段支流,非以太坊2.0)带来的低TPS,使得交易的手续费变高,但变高是用的人多所导致的市场博弈的后果。 而从另一个踊跃的角度来看,用的人多正反映着生态的凋敝,以及市场的关注度高,翻新在以太坊生态中层出不穷,所以如何放弃智能合约利用依然留存在以太坊生态的同时还能升高手续费、晋升交易速度等体验,正是Layer 2网络想要探讨的课题。 在本文中咱们将通过实例来演示如何在Layer 2网络xDAIChain上部署智能合约,并通过Chainlink预言机为部署在xDAIChain上的智能合约提供高质量的、防篡改的内部数据,在案例局部咱们会展现Chainlink的喂价机制如何在xDAIChain上应用。 xDAIChain简介xDAIChain是一种以太坊网络的Layer 2实现计划,所采纳的实现形式是基于侧链机制,它采纳了新的共识算法POSDAO,一种基于dPoS的共识算法模型。xDAIChain上的交易确认工夫更快,约为5秒,同时在xDAIChain上的交易手续费更低,500笔交易所要付出的费用约为0.01刀。另外正如它的名称所示意的,在xDAIChain链上的原生代币是XDAI,和主网上的DAI1:1兑换,领取交易费用为稳固币,可能给予用户更好的交易成本预期。 合约调用喂价和链下调用喂价的比拟Matic也是一种侧链实现,在Chainlink社区的之前文章中有专门解说如何在Matic网络上应用Chainlink预言机。Matic网络上曾经实现了Chainlink的整合,因而能够在Matic网络上链上调用Chainlink合约,蕴含喂价,随机数生成等性能。以后在xDAI上,Chainlink的整合还未齐全公开,因而本文中的示例中,实用于曾经部署在主网或者Kovan等测试网上的Chainlink智能合约,并以Kovan测试网作为示例,主网或者其余测试网能够类比迁徙。架构如下: 以Chainlink喂价为例,当初Chainlink官网文档上提供了Matic的喂价合约地址,然而xDAI没有,所以可能在xDAIChain上获取链下价格数据所要采纳的形式略有不同。咱们将通过Node.js脚本取以太坊网络上喂价合约提供的数据,并将其被动更新到xDAIChain上的合约中。 上面咱们将进入到教程的实际环节。 xDAI智能合约的部署筹备工作为了后续步骤的推动,咱们须要先筹备好部署合约的账户,本教程采纳的钱包为MetaMask,对于钱包的网络设定,以及代币的获取会顺次开展。 但在此之前,须要阐明的一个点是,xDAI网络没有测试网络能够应用,所以部署合约也是间接部署到xDAI侧链的主网,所耗费的是具备实在价值的资产。尽管费用不会很高,但基于测试目标,咱们能够抉择在另一个测试网络POA Sokol网络上执行部署、交互测试。等确认无误后,只须要批改一点配置文件,即可无缝迁徙到xDAI测试网络。 另外,xDAIChain上的原生代币为XDAI,POA Sokol上的原生代币为POA。xDAIChain提供的获取原生代币的水龙头地址为:https://xdai-faucet.top/,能够获取0.01XDAI。 然而在行文时,拜访此水龙头发现并不能通过这个网站实现XDAI的获取,通过debug发现,拜访人数过多导致无奈申请,在官网社群中有开发者给出答案说是临时不可用,因为这是有实在价值的代币。在社群中能够申请管理员给0.01XDAI用于开发测试,告知你的钱包地址即可,或者能够通过购买DAI,并通过资产桥:https://docs.tokenbridge.net/xdai-bridge/about 转换为在xDAIChain上的XDAI。 另注:在社群中询问此问题时,会有一些间接私信你的其余用户,经常顶着社群管理员的头像和名字(社群容许名称和头像与实在管理员雷同,且私聊不会显示社群中的tag)会给出一些所谓的通过walletconnect这样的网站,个别会说因为数据库更新导致无奈连贯,而后给出一个钓鱼网站,须要你输出本人的私钥或者助记词来从新连贯,这都是属于骗取公有信息,留神防备。 POA Sokol测试网络信息增加POA Sokol网络是另一种侧链实现,基于POA共识算法,其中POA共识算法能够看作是对dPoS算法的一种改良,它要求参加竞选的节点提供真实世界的信用信息。 在POA Sokol网络上获取测试代币POA则简略许多。步骤开展如下。 步骤一:设置钱包网络信息点击MetaMask菜单栏,选择网络,下拉到Custom RPC,点击进入,配置网络信息如下: 要害信息字段如下: RPC地址:https://sokol.poa.network链ID:77原生代币符号:POA区块浏览器地址:https://blockscout.com/poa/sokol配置实现后,点击保留,此时查看钱包余额: 上面进入测试代币获取步骤。 步骤二:获取测试代币拜访测试代币水龙头地址:https://faucet-sokol.herokuapp.com/,并输出本人的钱包地址: 查看钱包地址余额,有两种形式: 通过浏览器,输出本人的钱包地址查看https://blockscout.com/poa/sokol/address/0x28383b9717ca0468C580dF7b970A4897a0f11202/transactions等交易实现,在Metamask中查看显示余额为:100 POA 总的来说这个步骤和在Kovan测试网上获取代币流程简直统一,须要稍加留神的是设定钱包的RPC信息有所不同。 xDAIChain网络信息补充xDAIChain的钱包中配置网络RPC信息如下: RPC地址:https://dai.poa.network链ID:100原生代币符号:XDAI区块浏览器地址:https://blockscout.com/poa/xdai 钱包准备就绪后,开始执行我的项目创立和部署阶段,咱们将基于truffle框架来演示此过程,此框架对于工程合约我的项目开发来说必不可少。 在xDAI智能合约中应用PriceFeed注:本局部的我的项目工程文件托管在Github仓库,地址为:https://github.com/Bingyy/Use-Chainlink-On-xDAIChain 上面演示的是如何从头开始创立我的项目并部署。 1. 我的项目创立如果机器上没有装置truffle,能够通过命令行执行: npm install -g truffle 新建一个我的项目名:Use-Chainlink-On-xDAIChain mkdir Use-Chainlink-On-xDAIChain cd Use-Chainlink-On-xDAIChain truffle我的项目初始化: truffle init truffle我的项目构造如下: 这里的client目录非truffle我的项目所蕴含,build目录则是编译合约后存储ABI数据的地位。咱们次要编写合约,合约部署脚本以及我的项目配置信息。 2. 编写合约在contracts文件夹中,新建一个合约:GetETHUSDPrice.sol,内容如下: // SPDX-License-Identifier: MIT pragma solidity >=0.4.22 <0.8.0; contract GetETHUSDPrice { uint256 eth_usd_price; // 平安起见倡议用SafeMath function setETHUSDPrice(uint256 _price) external { eth_usd_price = _price; } function getETHUSDPrice() public view returns(uint256) { return eth_usd_price; } }此合约有一个状态变量,eth_usd_price用于保留从Chainlink喂价获取的实在的价格数据。 ...

February 3, 2021 · 7 min · jiezi

关于以太坊:手把手教你发行自己的ERC20代币并空投给社区成员

10分钟 5步 公布以太坊 ERC20 代币昨天在隔壁老王的群里领到了空投代币,不禁心生艳羡,老王一个初中毕业的人居然懂代码?!还发了本人的币?!他晓得什么叫 ERC20?!我不信他有这么大的能耐,拐弯抹脚的问了老王良久到底是怎么发币的,老王却遮遮掩掩不愿分享。 功夫不负有心人,终于让我找到一键发币的办法了,基本不须要懂编程、不须要懂英语、不须要懂电脑技能,这么说吧,基本上只有你能看懂汉字,就能发币!我立马发行了一个本人的币,并且豪掷1亿枚空投给老王,让他乐呵乐呵 ???? 我可不是老王那种遮遮掩掩、一点也不罗唆的人。明天不仅手把手教你一键发币,还教你怎么把币空投给隔壁老王们,独乐乐不如众乐乐,圈子大了才好玩嘛,你说是不是。 一键发币有两种形式可选: 一、网页版——联合小狐狸钱包 (MetaMask插件); 二、手机版——联合任何以太坊手机钱包都能够 (举荐应用 imToken、TokenPocket 等) 上面是这两种形式的操作步骤,包你一学就会: 一、网页版一键发币操作步骤 筹备工作:电脑浏览器提前装置好小狐狸MetaMask钱包插件。如果无奈下载插件,能够查看这里的教程。  metamask装置教程  https://cointool.catxs.com/doc/index?tab=metamaskInstall Dapp网址: https://cointool.app 1.关上一键发币网址:https://cointool.catxs.com/eth/createToken?menu=1 并点击页面上方 “解锁钱包“,受权链接 MetaMask 小狐狸钱包; 2.填写代币根底信息:代币名称、缩写符号、发行数量、并勾选您须要的合约性能(点击相干文字,会显示性能介绍),点击“立刻创立“; 3.在 MetaMask 的弹出框里确认交易,期待交易打包; 4.交易打包胜利即会显示该代币的合约地址,在钱包内增加资产即可显示代币资产。 **二、手机版一键发币操作步骤 **筹备工作:手机装置好钱包APP。上面是以 imToken 钱包为例,其余手机钱包的操作也大同小异,都能够参考这个步骤。 1.关上手机钱包,在浏览页面内输出网址:  https://cointool.catxs.com/eth/createToken?menu=1   并点击确认进行受权。 在关上的页面内填写代币根底信息:代币名称、缩写符号、发行数量、并勾选您须要的合约性能,点击“立刻创立“。 点击下一步,输出钱包明码,期待交易打包胜利即可收到您发行的代币,在钱包内增加资产即可显示代币。 备注:一键发币实现后,代币会主动转至创建者地址 。 只需几个简略步骤,就实现一键发币啦, 是不是超级简略。   微信:x0Panda

January 24, 2021 · 1 min · jiezi

关于以太坊:关于区块链智能合约和货币溢价的思考

随着泛滥能够反对智能合约的公链我的项目逐步上线,市场对其的关注度也慢慢从「神奇」的技术冲破,转向他们倒退生态、为生态发明价值、捕捉生态中价值的能力。这些能力与我的项目的经营程度和经济模型设计相干。 我最近始终在思考可编程价值网络的状态,特地是以太坊。从远处看,仿佛有许多「竞争者」竞相成为「赢者通吃」的智能合约平台畛域领头羊;在二级市场方面,咱们有以太坊、EOS、Tezos、Zilliqa、Cardano 等,更不用说新上线的 Cosmos 了,而在未上线的一级市场方面,有 DFINITY、Coda、Near、Polkadot、Oasis、Kadena、Thunder 等。 这篇文章的目标不是剖析当中每一个区块链网络绝对其余的优劣,并推导某个特定网络「胜出」的可能性——我甚至认为并不会涌现出一个「赢家」。我的这篇文章会更着重关注一点:「货币溢价」。 我置信对于那些想实现大规模利用并取得成功的可编程价值网络,这是一个必要的组件。 什么是「货币溢价」 这里的「货币溢价」,简略说是指资产对信息的不敏感性和能够禁受工夫考验的能力。也就是说,对于要在交易中应用的资产,用户不应该放心它的将来价值,同时也不能介意它的经济史。抗审查、平安、可预测和稳固的货币政策,以及其余正当和可继续的价值主张,也是实现社会可扩展性的要害。 但社会可扩展性到底是如何实现的呢? 咱们晓得,货币资产必须取得大量实物资本的反对,能力使其内生价值具备合理性和可持续性。但无形资本并非凭空出现,它还须要社会资本。 物质资本与社会资本的互作用 社会资本,或者一些人所说的「文化资本」,指的是在特定社会中生存和工作的人们之间的关系网。它包含人际关系、独特的认同感、独特的了解、独特的标准、独特的价值观、信赖、单干和互惠。 那么,物质资本和社会资本之间的关系是怎么的呢? 是物质资本导致社会资本,还是社会资本导致物质资本?抑或两者之间的关系是循环的? 如果货币资产背地没有实质性的实物资本,那么一个由人所组成的社会可能不违心反对它。然而,正如咱们过来所理解到的那样,加密网络能够在起初支持者寥寥无几的状况下作为晚期想法起步,但随着时间推移,它将可能吸引实物资本。这其中最典型的例子就是比特币。这表明社会资本最后会吸引物质资本。 然而,为了持续扩充规模,物质资本须要随着工夫的推移吸引更多的社会资本,而社会资本反过来又须要持续吸引更多的物质资本。这表明社会资本和物质资本之间的关系是循环的,在加密网络中尤其如此。置信这个故事的人越多,违心讲述它的人就越多;讲述的人越多,这种说法流传的频率就越高,这样的循环不断反复。 如何实现正向循环? 回忆一下,区块链发明了财务上的激励机制。在这种机制下,社区取得催化,联结起来提供去中心化的数字产品或服务,而后为该数字产品或服务、或网络上的特定数字产品或服务领取报酬。 一般来说,加密网络波及三个次要角色:开发人员(建设者)、工人(供应方)和投资者(需求方)。加密投资公司 Placeholder 的观点与此相似,只不过说法略不同,工人换成了矿工,开发人员换成了他们口中的用户。其中一类网络参与者未必就比其余参与者更重要。相同,这些角色的正确组合,以及它们朝着独特指标的协调一致的行为,对于创立网络和捕捉价值是必要的,如上面的星型所代表的地位所示。 投资者将实物资本注入到去中心化加密网络中,冀望这些投资资本在将来取得回报。相似地,工人通过以非拜占庭式的形式提供各种模式的供给端服务来疏导去中心化的加密网络,并冀望在投入劳动力后,能够取得网络处分,也就是收益。这样一来,投资者和员工动机统一,都心愿将本人的无形资本和劳动力投入到可能提供迷人的货币化效益的网络中。 那么,开发人员呢? 吸引并留住开发者 开发人员是加密网络的命根子,也是社会资本倒退的须要。没有开发人员,网络将无奈得以保护,其将来的安全性也会受到质疑。 应该廓清的是,开发人员并不间接爱护他们所构建的加密网络;这个工作是由事务验证者,即上文中的「工人」,所实现的。 每个网络都有不同的平安机制,其中一些可能比另一些更平安,但这得另开一个帖子独自剖析。重点是,开发人员须要保护、降级和参加治理他们在社交上反对的加密网络。适当的财政激励作用是弱小的,但社会激励和相互连贯能够说作用同样弱小。 如果开发人员因为某种特定的起因从某个加密网络迁徙,投资者和工人将很难为他们的无形资本和劳动力调配价值。他们的物质资本须要社会资本来发明价值,他们所反对的经济设计促成了价值的获取。因而,网络赚取货币溢价的能力在很大水平上取决于其开发者联盟的实力。 如果开发人员基于更好的用户界面 / 用户体验、更高的计算效率,或者仅仅是更好的社区或归属感,放弃了一个网络,转而构建另一个,倘若这个晚期网络的开发人员没有取得充沛补充,赶上或超过之前的程度,那么,最后的网络货币溢价不可能随着工夫的推移依然放弃其价值。在这种状况下,投资者和工人所投机的货币溢价只不过是一种幻觉。 那么,这与以太坊和其余可编程价值竞争者有什么关系呢? 以太坊仍然当先 围绕着以太坊的 1.x 和 2.0 路线图、执行打算以及工夫安顿,存在着很多争议。DeFi/ 凋谢金融狂热者收回各种埋怨,指出有超过 2% 的 ETH 供给被锁定在 MakerDAO 智能协定中,但 ETH 也被用于其余 DeFi/ 凋谢金融利用(Dharma、Uniswap 等)中,这 表明 ETH 正成为寰球价值储备和数字储备资产,存在看涨趋势。不过,更重要的是要记住: ERC20 代币是可迁徙的,能够转移到其余网络。因而,应该持续关注开发人员的流动。 ...

December 21, 2020 · 1 min · jiezi

关于以太坊:AAVE当前风险与收益是否有偏差如何评估DeFi投资组合

目前传统金融市场投资模式已从被动转向了被动型,截至2020年初,指数基金治理的资产超过10万亿美元。这一转变也十分有可能产生在目前以被动投资为主的数字货币市场。 也就是说ETF等指数基金十分值得关注,除了DeFi Pulse Index外,Index Cooperative,Synthetix和PieDAO也曾经公布了自有的DeFi指数,目前已有超过2400万美元的资金通过DeFi Pulse Index投资到DeFi资产中。将来还可能呈现更多ETF指数,并且还须要呈现相似传统金融基金评级的“晨星评级”这样的评级机制。 那么如何更迷信的评估一个数字资产投资组合的收益和危险呢?本文给出了两个维度,联合着两个维度甚至能够设计出一个适宜区块链资产的自动化的“晨星评级”: 不相干资产:组合中的成分资产之间的相关性越小,组合整体的收益期望值越高;平等危险承当:成分资产带来的危险占组合整体危险的比例,与成分资产占组合份额比例相比,是否存在较大偏差,偏差越大整体危险越高。在过来的十年中,传统金融市场的投资模式已急剧转向被动投资。截至2020年初,指数基金治理的资产超过10万亿美元,这是由低免费、宽泛的市场敞口和多样化等特点驱动的。然而,依据指数的构建办法,可能会呈现集中危险,并缩小多样化,从而减少工具的整体危险。 指数基金与向被动投资的转变 指数基金是一种独特基金或交易所交易产品(ETP),目标是提供对金融市场指数收益的间接敞口。许多投资者之所以会应用指数基金,是因为其打消了被动治理的复杂性(抉择要投资的单个股票的过程),并通过提供宽泛的市场敞口来简化进入给定市场的路径,从而造成多样化的投资组合。此外,指数基金偏向于遵循被动投资策略,与被动治理基金相比,这种策略产生的费用更低。 基于这些起因,投资者的偏好曾经从被动治理转向被动治理。2019年9月,随着越来越多的投资者意识到“跑赢大盘”的艰难,被动型美股基金治理的资产规模超过了主动型美股基金。 鉴于指数基金在传统金融中的实用性和受欢迎水平,看到这种金融原语在加密生态系统中的呈现难能可贵。诸如Index Cooperative,Synthetix和PieDAO之类的协定曾经建设了各自的DeFi指数,从而使加密货币投资者能够轻松接触DeFi,而无需成为该畛域的专家。随着加密生态系统将传统金融中的所有可能的金融产品移植到加密网络上,指数已为快速增长做好了筹备,尤其是在DeFi资产中。 集中危险 只管有这些益处,指数基金仍会无意间带来集中危险。这尤其实用于市值加权指数,因为每个公司的指数集中度由发行在外的股票乘以价格确定。例如,在过来几个月中,标普500指数曾经比互联网泡沫期间更加集中在前五名科技股(苹果,微软,亚马逊,Facebook和Google)中。 自4月以来,规范普尔500指数的集中度只减少了一点,前五大公司的集中度达到了21.95%。尽管这种行为在遵循市值构造框架的指数中是能够预期到的,但理解仓位集中度如何影响产品的危险和多样化,有助于投资者理解在不同的市场环境下能够冀望什么。 投资中惟一收费的午餐 诺贝尔奖获得者Harry Markowitz已经说过:“多元化是惟一的收费午餐”。核心思想是,通过扩散投资,投资者能够通过就义一小部分长期的预期收益来升高投资组合的危险。多元化始终是指数产品的要害卖点,因而必须从不同角度进行思考。尽管有几种办法能够评估投资组合的多元化,但与此相关的最重要的是: 不相干资产模式的多元化以平等承担风险的模式进行多元化“不相干资产”指的是投资组合中根底资产之间的相关性,而“平等危险承当”则是单个资产对投资组合总危险的奉献水平。 多元化:不相干资产 评估资产相关性的最常用工具是相关矩阵。相关性是一种统计,用来掂量一个变量与另一个变量之间的关系,而相关矩阵是一组变量的成对相关性的表格。 古代投资组合实践(MPT)是由Harry Markowitz在20世纪50年代提出的,它将多元化作为一种投资组合配置策略,通过持有不齐全正相干的资产来最小化非凡危险。换句话说,一个投资组合持有的不相干资产越多,多元化收益就越高。 与黄金、原油、股票和债券等其余资产类别相比,比特币和以太坊等加密资产的相关性最低,如下图所示,截至2020年10月28日的3年内数据。 心愿通过调整资产类别危险以进步回报率的投资者,必然须要将BTC和ETH等加密资产蕴含入其投资组合。 多元化:平等危险承当 在建设一类资产的指数或投资组合时,对多样化显然是有限度的。不过,投资者能够在投资组合的多元化中取得边际收益。 评估组合中每个资产的边际危险奉献(MCTR)能够掂量单个资产对投资组合整体危险的奉献。现实状况下,每项资产的危险奉献应均匀散布在一个投资组合中。如果与组合中的其余资产相比,一项资产的危险占比很大,那么缩小对这种资产的调配能够减少投资组合的多样化。 以驰名的60/40投资组合为例—由60%的股票和40%的债券组成的投资组合。这种投资组合调配的最大毛病之一是在大多数市场中,90%以上的危险来自股票。因而,60%的投资组合带来了90%的危险。换句话说,每种资产的危险奉献与投资组合的资产配置不统一。 这为什么很重要?简略来说,股票收益率决定了60/40投资组合的收益率。当股票上涨时,则60/40投资组合也很可能也会上涨(但涨幅稍小)。同样,当股价下降时,60/40也可能会降落。简而言之,股票决定了60/40投资组合的将来。 为了分明起见,本文将危险称为“资产收益的标准差”。能够将标准偏差视为不确定性的范畴。标准差(危险)越高,区间越宽,因而资产短期收益的不确定性也越大。 只管多元化的准则已在传统金融中很好的利用了,但在加密畛域,投资者在构建投资组合时却疏忽了这些准则。 驰名的加密投资者(如Placeholder Ventures的Chris Burniske)已开始提倡初学者通过投资DeFi Pulse Index(DPI)以轻松地取得多种DeFi资产。尽管投资于DeFi指数听起来对初学者来说是一个不错的做法,但DPI可能无奈实现其所宣称的多样化以合乎更成熟的投资者的需要。 多元化和最大的DeFi指数 DeFi Pulse Index(DPI)是市值加权指数,用于跟踪以太坊上的DeFi资产的价格体现。DPI每月更新一次,不包含通证化的衍生产品、合成资产或链接到实物资产的通证。 DPI对于“不相干资产” 当初,让咱们在多元化框架中从“不相干资产”角度和“平等危险承当”角度来测验DPI。 DeFi Pulse Index的相关矩阵显示,除UNI以外,大多数资产之间都高度相干。只管UNI与REN或REP等其余DPI资产的相关性接近于零,但UNI与DPI资产仍放弃正相干。 DeFi协定资产的可组合性、Dai在许多根底市场的利用以及与以太坊潜在的相关性都是潜在的危险集中点。 DPI对于“平等危险承当” 联合上述相关矩阵,咱们能够应用资产协方差和总投资组合方差,来估算每项资产的MCTR(危险边际奉献),以细化的评估指数整体危险。 依据以后DPI调配,总投资组合危险为122.48%。按资产计算MCTR表明,UNI(占指数的16.53%)约占总投资组合危险的26%。 此外,DPI总危险的77%次要由4种代币(UNI、YFI、SNX和AAVE)驱动,DPI指数的收益会因为这4种代币的价格稳定而变得极为敏感。与咱们的60/40投资组合一样,DeFi Pulse Index组合中的大量资产带来了大量危险。 进步DPI的多元化 简略地将更多的DeFi资产增加到DPI投资组合中会事与愿违,因为所有DeFi资产的走势都是雷同的,特地是在强劲的牛市或熊市中。 产生更好的危险调整后回报的一种潜在办法是创立一种能够更均匀地扩散危险的配置。例如,转向等同权重的投资组合并每周或每月从新均衡可能会产生更高的回报,同时也能够升高整体投资组合的危险。但值得注意的是,较短的再均衡工夫周期可能会导致额定的交易gas老本产生。 ...

December 9, 2020 · 1 min · jiezi

Second-State-SOLL-编译器项目获得以太坊基金会的现金奖励

2019年10月20日,台北 Second Satte是领先的面向区块链智能合约的开源基础架构软件的提供者,因为对开源SOLL编译器项目的贡献,获得了以太坊的现金奖励。 (右一为Second State 工程师Hydai,右四为以太坊创始人Vitalik) 2019年10月20日在台北举行的CrossLink活动中,以太坊基金会的Vitalik Buterin向Second State 团队颁发了5000美元的奖金。 SOLL是世界上第一个将Solidity智能合约编译为WebAssembly字节码,并成功部署到以太坊基金会官方Ewasm(以太坊WebAssembly)测试网中的工具链。 本月初,Second State团队在日本大阪的2019年以太坊基金会Devcon5上demo 了SOLL编译器项目的早期版本。 (Second State 工程师正在给以太坊团队demo 如何使用SOLL 在Solidity 中编译ERC20 合约,然后将其部署到官方Ewasm测试网上) 走向ETH 2 的重要路径根据ETH 2 路线图的规划,ETH 2 需要一种新的智能合约执行引擎,称为Ewasm(以太坊WebAssembly)虚拟机。但是,经过多年的开发,针对Ewasm 的开发工具链仍然缺失。在SOLL 之前,没有简单的工具可以将Solidity 智能合约编译并部署到基于Ewasm 的区块链上。 通过对LLVM 的支持,SOLL 不仅完善了Ewasm 缺少的工具链,还把现代编译器基础结构引入了Solidity 编程语言。 有了对LLVM 的支持,SOLL 不仅可以在前端支持多种智能合约编程语言,例如Rust和C ++,而且可以在后端支持各种VM,例如Ewasm和EVM1.x。区块链上的应用程序开发将更加灵活和高效。 Second State首席执行官Michael Yuan 博士解释了SOLL 项目背后的基本原理,“ SOLL 项目在企业开发人员和区块链世界之间架起了一座桥梁。我们欢迎所有开发人员使用为Ewasm 设计的SOLL 工具链。” 超越Ewasm能够在后端支持多个执行引擎,这是基于LLVM的编译器工具链的主要优点。例如,Second State与ETC Labs之间正在进行的合作,正在朝着SOLL的EVM 1.0 后端努力。这使得基于LLVM的工具和优化功能可以在现有的基于EVM的区块链上使用,例如以太经典(Ethereum Classic),CyberMiles等。 以太经典的核心开发Alan Li表示:“ SOLL EVM 项目的前进非常令人兴奋,将有效地塑造以EVM执行环境为基础构建的整个DApp 生态系统。” 此外,Second State将把SOLL 编译器工具链合并到非常易于使用的基于Web 的BUIDL IDE 中。BUIDL IDE 以智能合约作为后端,以web3作为前端,可以在几分钟内构建和部署完整的DApp。 ...

October 22, 2019 · 1 min · jiezi

用三张照片讲述Second-State-与DevCon5-的故事

解决现下以太坊智能合约开发挑战 第一张照片来自Devcon 第一天,我们的发言现场。观众熙熙攘攘,只有站立空间。我们进行了非常技术性的介绍,通过BUIDL IDE进行了所有的现场演示,并取得了巨大的成功。 我们演讲的重点是解决现下以太坊智能合约开发的挑战。我们讨论了针对当今EVM 开发的解决方案以及针对以太坊2.0的未来解决方案。您可以点击此处了解挑战和我们的解决方案。 Second State 在EVM 领域是关键创新者 第二张照片来自ETC Labs的Terry Culver的 Devcon主旨演讲,我们出现在主会场演讲的PPT上。 Second State是EVM的主要创新者。我们与在以太经典,CyberMiles和现在的以太坊的合作伙伴正在共同构建基于LLVM 的下一代EVM 语言工具链和基于WebAssembly WASM的执行引擎。 与以太坊团队共同建立下一代编译器工具链 第三张照片显示了Second State 编译器团队向以太坊基金会Solidity 团队展示了我们的解决方案。 Second StateSOLL是世界上第一个成功将Solidity ERC20 合约编译为WASM 字节码并将其部署在官方Ewasm测试网上的工具。参与这次会议的结果是Second State将与以太坊基金会团队合作,为Solidity 和Vyper 语言构建下一代编译器工具链。 总体而言,Second State 上周非常成功的参与了Devcon5 和ETC 峰会。我们结交了新朋友,并建立了重要的伙伴关系。

October 14, 2019 · 1 min · jiezi

开源免费的EOS-ETHXLM收款插件

无需搭建比特币/以太坊/EOS全节点(每一个都需要几百G空间)无手续费,你的程序你做主所有收到的钱实时自动转移到开发者个人账户,即使被拖库也没钱可盗。GitHub 地址 开发者访问本地 http 接口,向用户展示付款方法,用户付款后程序会访问本地回调URL 步骤: 1. 创建一个Mixin Messenger账户.访问 https://mixin.one/messenger 下载对应手机端App。 中国大陆用户可以访问 https://a.app.qq.com/o/simple... 下载 2. 激活开发者账号登陆 https://developer.mixin.one ,用App扫码登录 这个 教程对于新开发者很有用。 Clone, build, rungit clone https://github.com/myrual/mixin-network-snapshot-golangcd mixin-network-snapshot-golang编辑一部分配置信息const ( userid = "3c5fd587-5ac3-4fb6-b294-423ba3473f7d" sessionid = "42848ded-0ffd-45eb-9b46-094d5542ee01" private_key = `-----BEGIN RSA PRIVATE KEY-----MIICXAIBAAKBgQDACTrT4uaB9el9qe0MUOsFrm8kpaDI9PowauMB1Ha25mpfL+5hMFqISLS5z2P89nAsXBg+KyQ2gAVA6rBwW/ZqOc1PKiJhhLBS80nzo3ayfv7OlzNGIxMyqD5izCCtPixnqpuTePoPWq4CNZlxop0VYklsWEfU0U0qqMBgmtqYfQIDAQABAoGAR8crZed5oTn5fC73m5LjRcxdXqVJ49MtcMuC7jwr41FckRepUkpwjGAgrRMHnJXAd9Q0e4hEkNppHEqciGLXR1dQfZnaM1Gnv7mD3oSgHaH+4qAMnNOCpvwW4Eu3yp9b1UGj9SvM3D2BrpA+MGf0E/yEJzpRcT956W6SPYYSegECQQDm4uTK+teoxr1ZagJZuCta+IhMzpxIWMob+JN/Huf7OnRcIa9JpXngg4tHOUWmZCDQdqeJMpaQc8SQ44hba015AkEA1OyJswNIhdmvVp5P1zgREVVRK6JloYwmAtj+Qo4pWJ117LqH4w+b491r4AeLEGh8VrZ4k6Hp+Cm783S2jTAWJQJARbWdlHdV45xVkQiDuyjy1h2RsXb0EpfUNcvAZLIlImIMvcBh1x+CA7pTs+Zj1BAJJEee37qJYQXDBGfeRJPKKQJAVG+cx42Ew/eoTZwoIzvLoOkJcFlNHjwaksSER9ZiVQ7URdVOr99vvXQAJG45Wn9k12oy9LCfvNan/wqIngK0tQJBAL1Wc02seEbMeWyt5jycJEhn6G8F18s9S1v0GXb4U/7/6Y87P3TmDLcEuCXkrbZQaCX7jVLu0BkDw8To58TWjh0= -----END RSA PRIVATE KEY-----` ADMIN_MessengerID = ""//this is your mixin messenger id, you can find your id in contact page.)编译go build mixin_snap.go运行./mixin_snap数据库同一目录下会生成一个test.db 的sqlite3文件。 如何使用获取数字资产当前价格信息,因此可以计算客户应该付多少数字资产curl -X GET 'http://localhost:8080/assetsprice'价格结果如下,其中Full Name是该币种全名,Symbol是在交易所和钱包的缩写符号,USDPrice是当前资产美元价格,BTCPrice同理。 ...

July 12, 2019 · 3 min · jiezi

以BOX为例介绍在Mixin-Network上发行数字资产ETF-的优势

笑来老师基于 Mixin Network 发行了一个 ETF:BOX。那么 Mixin Network 有什么关键特性非常适合用来构建数字资产的ETF呢? Mixin Network 是一个主网已经上线的公链Mixin Network 主网已经有25个节点,这意味着攻击 Mixin Network 需要控制9个主网节点,因此主网非常安全。Mixin Network 从发布测试网至今没有发生过一起资产丢失事件。 Mixin Network支持海量数字资产目前已经支持BTC, BCH, Bytom, Dash, Doge, EOS, ETH, ETC, Horizen, LTC, MGD, NEM, Tron, Sia, XLM, ZCash。以及所有ERC20, EOS token,TRC10 token。 这对于ETF来说非常方便,只需一个 Mixin Network 钱包,就可以管理很多种资产。下面这张图是当下 Mixin Network 持有的资产的前10名 在 Mixin Network 内点对点转账免费,而且交易进入不可逆状态等待时间小于1秒钟确认快且网内交易免费可以极大的方便ETF交易。 Mixin Network 资产和交易默认保密Mixin Network 内的交易数据使用了cryptonote的技术,交易的双方对全网匿名,只有交易双方知道细节。因此购买ETF的人非常安全,无法被追溯。 Mixin Network 账户持有人可以通过提供授权码让他人查询账户余额ETF发起方可以生成授权码,让份额持有者来实时查询基金持有的数字资产余额。份额持有者甚至可以自行通过软件自行监控余额变化。BOX 就提供了授权码,允许任何人随时查询资产。 用户购买ETF技术门槛很低无需用户操作多种资产私钥,只需一个 Mixin Messenger 手机 App,就可以进行多种资产的管理和 ETF 申购和赎回。 ...

July 9, 2019 · 1 min · jiezi

DOS-Network-六月项目月报

各位亲爱的 DOS 社区的支持者们,欢迎阅读 6 月 1 日至 6 月 30 日的月度项目进度报告!???? ⚙ 产品和开发从 #beta1.1 测试网从 6 月启动以来,我们持续对节点软件进行优化、同时开发网络浏览器和用户仪表盘。 具有一定技术背景或者对命令行操作界面不陌生的节点运行者可以填写申请表并遵从 GitHub 文档来启动一个测试网节点。 测试节点申请表:https://docs.google.com/forms/d/e/1FAIpQLSdiWuVdyxpVozEC0uWZIj9HCBX9COBYFj8Dxp2C2qX4Qv5U9g/viewform  GitHub 节点文档:https://github.com/DOSNetwork/core/blob/master/README.md 节点 / 客户端软件开发:开启 geth 的轻客户端 (light-client) 模式,减小节点运行者长期维护以太坊全节点的压力。修复了节点订阅合约事件时 Web Socket 断线重连和 eth_proxy 的 EOF 错误。重新定义客户端子命令让节点新生成本地的节点钱包。节点地址与持币地址分开,从此质押的代币不再需要转移到节点地址,而是统一锁定在质押合约中 - 这减少了资金暴露在“热”钱包里的风险。修复启动过程和 DKG (分布式密钥生成) 过程 CPU 使用率过高的问题。改进代码格式、注释、更多的测试覆盖和修复其他一些小问题。智能合约开发:系统合约 : 增加了节点注销函数。给 proxy 合约增加了 truffle 单元测试。- 质押 / 委托合约: 正在开发质押和委托合约。质押 / 委托合约允许节点运行者以及普通持币用户得到质押挖矿的收益。持币用户可以不跑节点、而是把代币委托给节点并且赚取一部分利息;节点运行者除了得到自己质押代币的全部利息之外,也能得到用户委托给该节点的代币产生的利息的一部分。开发者和节点运行者的文档:更新开发者文档 到最新的预言机使用样例和最新版部署的 #beta1.1 合约。http://developers.dos.network更新从源代码编译及运行 beta 测试网节点的 GitHub 文档 (文档在持续更新中)。网络浏览器、用户界面:我们正在开发网络浏览器,方便持币用户及节点运行者搜索节点状态和网络中发生的事件。在这里预览现在的前端设计原型图:https://scene.zeplin.io/project/5d0250d2f695e65dec3f8053 其他:在币安链上发行了 BEP2 DOS 代币,并且从所有 validators 那得到了登陆币安去中心化交易所 DEX 的支持。DOS/BNB 交易对将于 7 月 8 日下午 6 点在币安 DEX 开启交易,同时我们会在下周发布一系列活动,敬请期待!为了方便用户进行代币转换,我们开发了从 ERC20 DOS 到 BEP2 DOS 转换桥https://swap.dos.network。后续我们会持续开发转换桥来实现自动的双向代币转换。转换代币的教程请查看这里「DOS 即将登陆 Binance DEX,并提供 ERC20 DOS 到 BEP2 DOS 的转换中继」???? 运营和市场6 月 2 日,DOS Network 运营和业务发展负责人孙孝虎受邀参加了 BitMax在北京举办的线下粉丝见面会。孙孝虎在会议上发表了演讲,介绍了预言机在区块链行业的重要性,必要性以及预言机的应用场景等。 ...

July 5, 2019 · 1 min · jiezi

一-用-JavaScript-写-DApp谈谈-ETHEOSFIBOS

一个普通开发者对 ETH、EOS、FIBOS的看法一直保持着如儿童般的好奇心和技术的热情,挺早就关注区块链和加密货币。当然并没有发财,这可能跟自己知识结构和本身比较穷有关。 在读大学的时候第一次听到了比特币,那时候可能几美元吧记不清了。后来接触到了以太坊,第一次听到了 DApp 这个词。可能当时各种资料比较少,只是看了看文档并没有真正尝试去写一个 DApp。 真正想着去编写一个 DApp 应该是在 2018 年,当时一句话感触至深: 你想真正了解一件事情最好的方法是参与其中。于是乎在 2018 年花了一点点钱买了一点点加密币。大家不用猜也知道,买在了山顶上,哈哈哈。也就是从那时候开始,在 Udemy 买了课程 Ethereum and Solidity: The Complete Developer's Guide 和 参加了 LoomNetWork 的在线互动课程。这两个课程质量非常好,强烈推荐,算是我的 DApp 入门课程。但是但是,我并没有后续自己独立开发出一个 DApp。 再后来,通过一直在微博上关注的西祠胡同响马,了解到了 FIBOS,也把自己为数不多的 EOS 兑换成了 FO。 为什么会关注 FIBOS 呢?经历了 Solidity 写 DApp 的确发现 Solidity 其实也有一定的学习成本,虽然说 Solidity 跟 Javascript 类似,但是还是有自己不同的语法。另外 DApp 编程,跟中心化应用你的大脑回路需要不一样。另外 ETH 一个缺点就是性能比较差,而且跑你的 DApp 非常贵。大家应该也听说过一个云养猫的 DApp 就让 ETH 拥堵不堪了。 当然 ETH 的开发团度肯定也意识到了这些问题,但是有号称区块链 3.0 的 EOS 出来想要解决这些问题。更快的运行速度,更大的通量,更便宜的运行成本,但是似乎并没有解决开发门槛的问题。目前 EOS 仅仅支持 C 和 C ++ 编写合约。EOS 比 ETH 开发门槛更高了。 ...

July 4, 2019 · 2 min · jiezi

如何使用GETH-CLI在以太坊网络进行资金转账交易

完成同步的以太坊区块链节点后,就可以通过使用GETH CLI在以太坊网络上执行交易。 首先我们来链接GETH控制台,查询以太坊帐户的余额: geth attach ipc:/home/enchanter/.gophersland_ethereum_r1/geth.ipc eth.getBalance("0xceee57f2b700c2f37d1476a7974965e149fce2d4")> 7500000000000000000我想,你可能会想为什么7.5ETH在Geth控制台中显示为75000000000000000? Ether与wei以太坊虚拟机不支持小数或浮点数。显然,金融计算在整数中更容易。 因此,为了能够发送1 ETH的一小部分,以太坊基金会决定创建自己的单位系统,其中最小单位为1 Wei,1 Ether为1e18 Wei。 但不用担心,有些工具可以让你的生活更轻松。例如,我强烈推荐Ether to Wei在线转换器: https://etherconverter.online 为了发送价值15美元的以太,其中1 ETH == $200(旧时代......),你将发送0.0740 ETH的交易,这必须在Wei中表示为74000000000000000。 在线Ether to Wei转换器: 以太坊单位系统概述: 实战中来掌握。让我们实际发送74000000000000000 wei(15美元)到另一个帐户。 使用GETH CLI将以太发送到另一个帐户在一个终端中,请记住运行完全同步的区块链节点: geth --rinkeby --datadir=~/.gophersland_ethereum_r1 --port=30304 --cache=2048 --rpc --rpcport=8546 --rpcapi=eth,web3,net,personal --syncmode=fast在另一个终端,我们将创建我们的第二个以太坊帐户。 ls -la ~/.gophersland_ethereum_r1/keystore/> drwx------ 2 enchanter enchanter 4096 sep 24 15:36 .> drwx------ 4 enchanter enchanter 4096 sep 24 15:26 ..> -rw------- 1 enchanter enchanter 491 sep 24 15:36 UTC--2018-09-24T13-36-43.069452577Z--ceee57f2b700c2f37d1476a7974965e149fce2d4geth --datadir=~/.gophersland_ethereum_r1 account new> INFO [09-24|15:36:33.566] Maximum peer count ETH=25 LES=0 total=25> Your new account is locked with a password. Please give a password. Do not forget this password.> Passphrase: > Repeat passphrase: > Address: {7aa4a14286a25e3a275d7a122c23dc3c107a636a}ls -la ~/.gophersland_ethereum_r1/keystore/> drwx------ 2 enchanter enchanter 4096 oct 25 20:14 .> drwx------ 4 enchanter enchanter 4096 oct 25 19:48 ..> -rw------- 1 enchanter enchanter 491 sep 24 15:36 UTC--2018-09-24T13-36-43.069452577Z--ceee57f2b700c2f37d1476a7974965e149fce2d4现在,让我们将Geth控制台链接到当前运行的区块链节点,就像我们在上一篇文章中所做的那样,以便通过执行eth.sendTransaction命令将15美元转账到这个新创建的帐户。 ...

June 18, 2019 · 1 min · jiezi

DOS-Network五月项目月报

各位亲爱的DOS社区的支持者们,欢迎阅读5月1日至5月30日的月度项目进度报告!???? 请关注我们的微信公众号或加入DOS官方社群,了解DOS网络的最新动态!现在就为大家带来最新的项目进展月报! ⚙️ 产品和开发DOS网络已经正式发布了公共测试网络 Beta 1.1版本 ????????????  任何能够使用Linux命令行环境的DOS网络支持者都可以加入DOS公共测试网络并且运行节点。请查看下方README文件并按照说明进行操作。 https://github.com/DOSNetwork... 如果您是开发者,请在下方链接中查看有关如何使用预言机服务的文档和示例。 https://dosnetwork.github.io/... Beta版本1.1目前包括以下功能: 1、可验证的密钥共享 2、分布式密钥生成(Pedersen的DKG方法) 3、Paring Library和阈值BLS签名 4、分布式随机数生成 5、Gossip和DHT协议的实现 6、P2P NAT支持 7、Json / Xml / Html请求解析器 8、容器化和客户端部署脚本 9、以太坊链上系统合约的整合 以下是未来发布版本的更多功能: 1、测试geth命令的lightnode模式并且在Parity客户端上进行试验 2、实现质押&授权合约及用户友好的面板 3、网络状态浏览器 ???? 最新战略合作DOS网络已与DUO Network达成战略合作。 双方将致力于通过抵押智能合约和分布式的数据预言机来降低传统衍生品交易中的风险和障碍,从而加速通证化加密衍生品的开发并促进Dapps的大规模应用。 ????活动DOS Network 联合创始人兼首席运营官王琦受邀参加哔哔News社区关于「以太坊生态」的线上论坛。 哔哔News社区致力于为用户提供有关区块链和数字货币的最新及有趣的信息和社区服务。王琦在此次论坛中表达了他对以太坊生态系统的见解。文章整理请戳:深聊以太坊 DOS网络运营和业务发展经理孙孝虎受邀参加了“解密Staking经济线下聚会”。 DOS网络公布了第一轮全球大使计划的结果。感谢所有参与者积极和支持。我们为 8 个不同的地方挑选了 10 位大使,并分别建立了各地的官方电报社区。我们的全球大使计划仍在进行,欢迎所有其他地区符合条件的DOS网络支持者申请!https://medium.com/dos-networ... DOS Network 正式入驻 Binance Info,并获得 Binance Info 官方“V”标识认证。 DOS网络联合创始人兼首席运营官王琦应邀参加了由巴比特主办的2019全球区块链(杭州)高峰论坛。并参与了主题为:"区块链项目融资新姿势”的大辩论。 DOS网络运营和业务发展经理孙孝虎应邀参与5月20日在北京举办的比特币之夜 - “A Gathering of Believers”。 DOS Network与Rebase社区和链茶馆于5月26日在北京联合举办了主题为”区块链跨链技术”的线下活动。本次活动特邀嘉宾Random Capital合伙人刘毅和Wanchain全球副总裁李尼做了主题分享,并与现场观众针对跨链展开深入讨论。DOS网络建立并开通电报官方公告频道。我们欢迎并鼓励每个DOS网络支持者加入这个频道,只需点击一下即刻了解我们的所有项目进展与更新。????每月统计数据推特粉丝:6344~6614(+ 4.3%)电报社区成员:15362~15798(+ 2.8%)Reddit成员:5034~5059(+ 0.5%)微信社区成员:2104~2779(+ 32.1%) - END - ...

June 10, 2019 · 1 min · jiezi

从经济模型角度看比特币和以太坊存在的问题

公链的竞争是惨烈的,这个战场里的玩家要想生存下来,既要有绝活,还得没短板。在构建加密经济网络上,在技术实现和共识协议部分,我们为大家分享了CKB 的绝活,即: 与时俱进的 Cell 模型用 RISC—V 从头造的 CKB-VM 虚拟机突破中本聪共识的新型 NC-Max 共识协议今天,我们开进构建加密经济网络的最后一个支柱:经济模型。 比特币和以太坊像两座最早出现的虚拟城市。在它们之后,越来越多公链试图建立自己的城邦,吸引游民入住。但这些项目没有意识到的是,经济系统的运作真正决定了一个城市长期的繁荣。对经济模型设计的重视程度,决定了一个城市能否留住自己的居民。橙皮书表示:“Nervos 是我们看到的最令人惊喜的存在,为公链介绍了另一种完备的经济学设计思路。” 秘猿科技区块链小课堂第 31 期 任何一个加密货币项目都可以看作是一个经济体,加密经济机制是经济体的根基和推进体系持续运转的动力。区块链发展到现今这个阶段,人们在共识协议、可扩展性方向都做出了大量的尝试和创新,但是在加密经济模型设计方面的创新相对来说则不那么多见。 区块链的世界,既需要计算机专家也需要经济学家,Nervos 加密经济研究小组做了大量的研究分析并发布了 Nervos CKB 经济学模型提案,希望可以抛砖引玉,引起大家的探讨。本文是社区伙伴 Henry 对 CKB 经济模型提案部分内容的解读,同时也欢迎大家进入 Nervos Talk 论坛,加入我们的讨论当中。两个重要的方向 在现有的区块链系统中,代币的用途大致可以被分为两个方向:一种是 SoV(Store of Value / 资产存储),另一种是 MoE(Medium of Exchange / 交易媒介)。 SoVSoV 属性的代币,通常会在以下三个维度做出努力: 确保足够的稀缺性确保足够的算力和安全性价值的增值保值MoEMoE 属性的代币,通常会倾向于在以下三个维度做出努力: 更低的交易手续费更快的交易速度更优的连网体验(我们不希望一个系统要求交易双方都同时在线,甚至握手三次才能完成交易。)SoV vs MoE一个方向的经济模型最佳化,不太可能是另一个的最佳化,因为 SoV 和 MoE 具有不同的系统资源利用方式:交易花费是一瞬间的,而且计算和带宽是可更新的资源,但是保值却需要长期的占用资源。就像我们买黄金,并不是用它来作为交易媒介,而是用来保值。下面我们先来分析比特币和以太坊这两个最大加密经济体的经济模型,我们经过研究发现它们在可持续性上都存在各自的问题。 比特币加密经济模型比特币 as MoE比特币是一个点对点的电子现金系统, 但是它在走 MoE 这条路时,面临着几个问题: 交易速度慢:TPS 低,交易至少需要经过 6 个区块确认;交易手续费高;现今很少有人会用比特币来频繁交易,大家都把比特币视为数字黄金用来保值。虽然作为 MoE 是比特币最为本质的属性,但是比特币作为一个交易媒介,目前并不那么成功。但是发展到现在,由于先发优势,和经过了十年的验证,比特币慢慢拥有了大范围的矿工来保障系统的安全性和可持续性。如果一个系统的安全性和可持续性越高,那么它的价值就会越高——现在的比特币更像一个储值平台而不是交易的中介。 比特币 as SoV在未来,比特币的出块奖励会持续减半,距离下一次减半还有差不多 400 天,由于稀缺性的增加,比特币的预期价格会持续上涨,这也代表着未来需要投入更多的算力来保证整个网络的安全性。 ...

June 6, 2019 · 1 min · jiezi

区块链无法解决的状态爆炸问题

在设计全新的区块链经济模型之前,我们以 SoV(价值存储) 和 MoE(交易媒介) 两个框架分析了比特币和以太坊经济模型,得出了上一篇中的问题。在本次秘猿科技区块链小课堂中,我们带大家来了解一个全新的状态爆炸问题。这类问题将会在未来解决扩展性问题后,显著爆发出来,我们称之为 post-scalability problem!秘猿科技区块链小课堂第 32 期 如果 Layer 1 的关注点应该是状态而不是计算,在设计 Layer 1 区块链时,我们就需要先理解什么是区块链的状态。理解了状态是什么,我们才能理解状态爆炸是什么。 状态区块链网络中的每一个全节点,在网络中运行一段时间之后都会在本地存储上留下一些数据,我们可以按照历史和现在把它们分为两类: 历史——区块数据和交易数据都是历史,历史是从 Genesis 到达当前状态的路径。状态(即现在)——节点在处理完从 Genesis 到当前高度的所有区块和交易后形成的最终结果。状态随着区块的增加一直处于变化之中,交易是造成变化的原因。共识协议的作用是通过一系列的消息交换,保证每一个节点看到的当前状态是相同的,而实现这个目标的方式是保证每一个节点看到的历史是相同的。只要历史相同(即所有交易的排序相同),处理交易的方式相同(把交易放在相同的确定性虚拟机里面执行),最后看到的当前状态就是相同的。当我们说「区块链具有不可篡改性」时,是指区块链历史不可篡改,相反,状态是一直在变化的。 有趣的是,不同的区块链保存历史和状态的方式不同,其中的差异使得不同的区块链形成了各自的特点。由于这篇文章讨论的话题是状态,而影响状态的历史数据主要是交易(而不是区块头),接下来的讨论历史的时候会侧重交易,忽略区块头。 举个例子:Bitcoin 的历史和状态Bitcoin 的状态,指的是 Bitcoin 账本当前的样子。Bitcoin 的状态是由一个个 UTXO(尚未花费的交易输出)构成的,每个 UTXO 代表了一定数量的 Bitcoin,每个 UTXO 上面写了一个名字(scriptPubkey),记录这个 UTXO 的所有者是谁。如果要做一个比喻的话,Bitcoin 的当前状态是一个装满了金币的袋子,每个金币上刻着所有者的名字。 Bitcoin 的历史由一连串的交易构成,交易内部的主要结构是输入和输出。交易更改状态的方法是,把当前状态中包含的一些UTXO(交易输入引用的那些)标记为已花费,从 UTXO 集合中移出,然后把一些新的 UTXO(这个交易的输出)添加到 UTXO 集合里面去。 可以看出,Bitcoin 交易的输出(TXO,Transaction Output)正是上面说的 UTXO,UTXO 只不过是一种处于特殊阶段(尚未花费)的 TXO。因为构成 Bitcoin 状态的组件(UTXO),同时也是构成交易的组件(TXO)。由此 Bitcoin 有一个奇妙的性质:任意时刻的状态都是历史的一个子集,历史和状态包含的数据类型是同一维度的。交易的历史(所有被打包的交易的集合,即所有产生过的 TXO 的集合)即状态的历史(每个区块对应的 UTXO 集合的集合,也是所有产生过的 TXO 的集合),Bitcoin 的历史只包含交易。 在 Bitcoin 网络中,每一个区块,每一个 UTXO 都要持续占用节点的存储空间。目前 Bitcoin 整个历史的大小(所有区块加起来的大小)大约是200G,而状态的大小只有大约 3G(由约 5000万个UTXO组成)。Bitcoin 通过对区块大小的限制很好的管理了历史的增长速度,由于其历史和状态之间的子集关系,状态数据大小必然远小于历史数据大小,因此状态增长也间接的受到区块大小的管理。 ...

June 6, 2019 · 2 min · jiezi

深入研究-PoW-和-PoS-优劣和取舍

在秘猿科技区块链小课堂第 26 期开始,我们开始讨论「构建加密经济背后的三大支柱之一」的共识部分,浅谈了 PoW 和 PoS 共识差异。今天我们分享前 Blockstream 共识协议、安全、隐私的研究员 Ren Zhang 来为大家深入分析 PoW 和 PoS 优劣取舍。本文节选自《What PoS Cannot Achieve (But PoW Can) And What PoW Cannot Achieve, Either》的主题演讲 秘猿科技区块链小课堂第 27 期 安全性假设和安全属性在分享的一开始,张韧就给出了安全性假设和安全属性关系的基本公式: 系统的脆弱性 =(理想中的安全属性 - 实际的安全属性)+ 安全性假设从这个公式中我们可以看到,当想要建设一个更好的区块链时,我们的关键目标应该是降低系统整体的脆弱性。而要达到这个目标,我们应该做到:与之前的设计相比,新增加的安全性假设少于新增加的安全属性 或者减少的安全性假设多于减少的安全属性 本质上这就是在构建一个更健壮的架构。 然而现状是,有太多项目宣称自己是具备强安全属性的区块链 X.0,但实际上在这些安全性上的改进都包含一些前提假设,所以这也让它们各自的网络存在脆弱性。 PoW vs. PoS熟悉 Nervos 的伙伴都知道,我们推崇比特币的 Nakamoto 共识机制。在比特币之前,(在分布式系统中)一个共识网络中的所有参与者都彼此知道其它的每个参与者。它们之间的信息会通过安全链接或者采用数字签名的方式进行传递,并且,消息对于定时的假设是异步的。 比特币引入了带有延迟的无需许可网络的概念。在比特币网络中,新的节点可以随时加入,并且可以获得可信的网络历史记录。网络的参与者不再需要知道其他参与者,信息也不再需要被可信的主体签名,而是通过广播的方式传递。 那么,如果不采用工作量证明机制,或者在一段时间内不采用工作量证明机制,这样的网络还能够正常运转吗?对于一个无需许可区块链来说,答案是否定的。 为了保证后来加入的节点能够看到可信的区块链历史,工作量证明机制必须永远持续下去。并且,节点需要随时知道网络的延迟信息,因此网络中无法采用异步协议。另外,这个网络还要求大部分节点都是诚实的。 那么,权益证明机制可以达成网络中的这些属性吗?和工作量证明机制类似,权益证明机制的运行需要一种稀缺资源作为基础。然而和工作量证明机制不同的是,如果没有可信的主体,那么采用权益证明机制的网络无法容忍较高的延迟。这意味着在某些情况中,权益证明机制系统会面临几种能够让新参与者无法分辨真实网络历史的攻击。 为了解决这个问题,采用权益证明机制的系统必定会采用由一些拥有公共身份的可信主体进行签名的检查点机制,这实际上又违背了去中心化和无需许可的这个核心信条。 在某些情况中,采用权益证明机制比采用工作量证明机制的系统有更强的安全属性。因为整个系统的价值是已知的(全网有多少 Token,Token 的价格都是公开可知的),如果大部分「价值」达成一致,那么参与者的数量就不那么相关,这样一来,网络可以绕过由于不知道所有参与者数量带来的问题。 但为了确保它们是否达成一致,所有人都必须保持在线,而这是一个很强的安全假设,并且每一个区块都必须被几千个节点签名,这会对性能产生很大的负面影响。因此,虽然参与者数量是已知的,但这并不能弥补权益证明机制相对于工作量证明机制的缺陷。

June 6, 2019 · 1 min · jiezi

UTXO-和-Account-模型对比

Nervos 加密经济网络中的底层公链 CKB 是比比特币更像比特币的价值存储平台。(这一点将会在经济模型设计中讲到,敬请期待~)在技术实现上,我们也充分对比了比特币 UTXO 模型和以太坊 Account 模型的优劣,从中继承了比特币协议对状态为核心的优秀架构。我们称 CKB 是一个通用验证网络,Cell 是对 UTXO 的一般化版本。并且,发展出了 CKB 模型的优势,在 CKB 当前状态中存储的是任意的共同知识,而不再仅仅是某一种单一数字货币。在深入了解 CKB 公链中的 Cell 模型前,我们来谈一谈前置概念:UTXO 和 Account 模型!秘猿科技区块链小课堂 17 期 在当前区块链世界中,主要有两种记录保存方式,UTXO 模式(Unspent Transaction Output) 和 Account 模式。Bitcoin 采用的是 UTXO 模型,Ethereum 采用的 Account 模型,同样 CITA 也采用了 Account 模型。 Bitcoin 的设计初衷是点对点的电子现金系统,在比特币中,每个交易消耗之前交易生成的 UTXO 然后生成新的 UTXO,账户的余额即所有属于该地址的未花费 UTXO 集合,Bitcoin 的全局状态即当前所有未花费的 UTXO 集合。Ethereum 意图创建一个更为通用的协议,该协议支持图灵完备的编程语言,在此协议上用户可以编写智能合约,创建各种去中心化的应用。由于 UTXO 模型在状态保存以及可编程性方面的缺陷,Ethereum 引入了 Account 模型。下面我们对两种模型的优缺点做进一步展开。 UTXO 模型UTXO 模型中,交易只是代表了 UTXO 集合的变更。而账户和余额的概念是在 UTXO 集合上更高的抽象,账号和余额的概念只存在于钱包中。 ...

June 5, 2019 · 2 min · jiezi

区块链实现信任自动化

在前两期秘猿科技区块链小课堂中,我们理解了什么是区块链,以及区块链的发展史。那么,区块链能够为我们带来什么呢?秘猿科技 CEO 谢晗剑分享了对区块链技术带来现实意义的理解,请注意文章中公有许可链的想法在 2017 年第一次被秘猿科技提出。秘猿科技区块链小课堂第 3 期 我们用区块链解决数字世界信任难题人类是一种群居动物,人类学家通过对不同动物群落的分析发现,对于人类而言,最自然的群落人数上限是 150,这代表了我们在日常生活中可以维护的比较亲密的关系数量。从古至今,人类一直在尝试各种发明创造,以期通过不同的工具、制度来突破这个限制。 因此,我们有了公司这个非常伟大的发明。 用机器管理流程在公司内部,我们会制定各种各样的制度来激励人,用于维持一个团体向同一个目标迈进;在公司与公司之间,我们会制定公司法等一系列法规,用于保证公司与公司之间商务合作的顺利进行。公司制度下充斥着各种各样的商业流程,诸如下单、采购、制造、发货、开票、收款等等,它们把各环节上所有的人串起来,保证他们在既定流程中可以有效协同地完成一个任务。 但当计算机出现后,计算机的能力在不断增强,而人类的能力却相对没有变化,这个时候我们开始思考,是否应该把计算机运用到这些流程之中,用它们来管理流程。 这和我们把机器用于工厂是相反的。在工厂里,机器人是工人,管理者是人,但是在流程管理里,我们尝试的是用机器去管理人,这就是我们所描述的“流程自动化”。所以在今天,我们看到了各种各样基于网络和计算机技术的信息系统,比如说ERP、商业智能。 基于这样的信息系统,我们能够组建起越来越多的大公司,那些跨国公司也早已司空见惯。但如果我们想要把这个自动化的流程再向外扩张,延伸到公司边界之外时,我们就会发现各种各样的问题。公司及组织本身是一个信任边界,内部能有很好的协作,但一旦脱离组织边界,我们就没法去相信流程上的其他人也会忠于他该做的事情。 这是我常常思考的一个问题: 能不能通过技术的手段,使得企业与企业之间,而并非仅限于企业内部,也能做到流程自动化呢?在互联网的技术环境下,我一直没有找到答案,直到以太坊的出现。 以太坊给的答案以太坊通过去中心化的技术为我们构造了一个共享的数据库,在这个共享数据库之上又为我们构造了一个共享的计算机,我们可以把代码部署到以太坊这个分布式系统上,让机器来帮我们执行代码。我们可以把在商业世界中用自然语言写成的合约改为用代码写,把由人来执行的合约改为由机器来执行。另外,我们还在以太坊上创建了两种不同的账户,这和诸如比特币等任何其他的区块链都有很大不同。在其他的区块链上,只有一种人类控制的账户,你可以通过你的资料去管理你账户里的余额。 但在以太坊上,只有一种叫做合约账户的东西,它由机器控制,合约账户里储存了用代码写成的逻辑,这个世界上没有任何人可以控制它,只有这段代码可以控制它。 这是一个破天荒的发明。它代表机器在历史上第一次实现了经济独立。在以太坊系统里面,机器和人的地位是一样的。在以太坊上,我们不区分人或者机器,机器也可以在以太坊上面开户,因此机器有了经济自主权。也正是因为这一点,机器能够在这个世界里成为一个可靠的中间人。在我们现在的商业世界里,所有的中间人都由人来担任,你可能没办法相信他能够妥善保管你的财产;但是当机器有了经济自主权之后,你可以相信机器能够安全保管你的财产。 你可以把财产托付给智能合约,即托付给机器,因为机器没有办法从区块链上跑路。到了这个时候,我觉得当初我们想要达到的企业与企业之间的流程自动化就有可能实现了。那么是不是就 OK 了?很遗憾还有很多事情要做。 如果我现在问大家,区块链里最靠谱的应用是什么?你会想到地下市场还是 1CO?我们能够看到的是,这些应用都离我们商业世界里的应用很远。我们需要去中心化的 Uber、去中心化的阿里巴巴,但我们不需要去中心化的地下市场,那与我们普通人没有关系。在我看来,造成这种现象的原因是,现有的公有链是一个无需许可链,任何人都可以匿名的身份在这个环境里做一些事情。但是对于每一个正常人来说,我们需要的不是匿名而是隐私,这是不同的东西。 数字世界的信任在现有的公有链里,我们也很难看到稳定货币的存在。如果我们真的要把现在的商业世界搬到数字世界里,我们就需要稳定货币的支持,那样我们才能对卖出的商品、提供的服务给出一个稳定的定价,才能很好地核算成本和收益。但你又会发现,汇率稳定在公有链里很难,它难以用一种去中心化的方式去实现。商业世界必然需要监督,但是在数字世界里,怎么做到这一点呢? 作为前以太坊的成员,我也经历过去年发生的区块链历史上最最最有名的黑客事件。 在很短的时间内,价值五千万美元的以太币被偷走,这些以太币是由一个智能合约、一个机器保管的。 当时整个社区发生了剧烈的争论,讨论我们是应该尊重《代码及法律》(认为黑客是合理合法的利用了代码漏洞)不去管它,还是立即采取措施把这笔钱找回来? 当时我们联合了几个团队做了一个投票的网站,尝试去收集社区的投票,最后的共识是应该采取措施把损失降到最低,所以最后以太坊也确实采取了这样的行动。我们在代码里硬编入了更改数据状态的代码,把这笔钱找了回来。 但当时这个行为也引起了非常大的争议。有人说这违反了区块链上数据不可篡改的性质, 这样做区块链还有什么意义?但是我想说,区块链的不可篡改究竟指的是什么?它指的是交易的历史不可篡改,这和我们的现实世界非常相似。 因为你在不停的转账,比特币上的账本每时每刻都在更改,每个人账户里的余额都在变化,但是一个交易一旦发送到区块链上,它就不能再被撤销。在以太坊上,从来没发生过交易撤销的事情,只有这个世界的状态改变过,这是我们应该保证的一个原则。但是我常常会想,也许我们可以做得更好,也许我们可以通过某种方式,而非硬性的更改代码来完成这个事情。 身份认证是许可链的基础怎么做?近年来出现了一种新型的区块链,我们把它叫做许可链。它跟公有链有很大的不同,许可链很好的回答了这些问题。 在许可链里,无论是节点还是用户,可能都需要先通过身份认证才能获得一定的许可,才能够加入这个链及使用这个链提供的服务。身份是许可链的基础,有了这个基础,我们才能够去更好地构建一个数字商业。 在许可链里,由于有了身份,我们可以很容易地把现实世界中有信用的机构引入,由这些有信用的机构承担我们称之为法币网关的决策,由这些法币网关去发行对于稳定货币1:1汇率的代币。 在许可链里使用这种基于信任的稳定货币机制可能是最容易的,而且在未来数字货币真正推出的时候,法币网关的机制也更能够让许可链接入真正的数字货币。 有身份的许可链上,我们也能够构造不一样的治理机制,我们可以形成一个链外的治理委员会,在有紧急状况发生时,可以由治理委员会在链外形成人的共识,达成决议来决定我们是否要去做一些操作。 这样一种做法的好处是说,我们不仅没有修改历史,还将当时发生了什么以及我们做出了何种决议,都以交易的形式保存到了历史中。在这样的情况下,区块链可以成为一个非常好的信息记录工具。 但是,这样就够了吗?很可惜还差一点点。我们现在看到世界各地有许多大大小小的许可链正在建设当中,但它们都是分割的网络,而区块链是一个具有网络效应的技术,即:网络越大,网络中资产的价值就越大。我们需要有一个大大的所有人一起用的许可链。 公有许可链是未来许可链现在存在的第二个问题是经济激励机制。区块链里的节点是通过使用自己的计算能力提供存储空间,为区块链上的所有用户提供服务。但是在许可链里,这个服务是免费的,我们缺乏经济激励的机制来激励这些节点提供服务。 如果没有这样的经济激励,我们很难想像许可链可以长久稳定的运行下去。在可遇见的未来,如果没有经济激励,许可链还是不是区块链呢?或者说只是区块链的一个分布式数据库。所以我们该怎么办呢? 现在有一种叫公有链的技术,和许可链比较两者各有好处。首先你会发现,公有和许可的定义并不矛盾,公有说的是希望有尽可能多的用户来使用它,许可说的是希望用户在进入这个链使用服务之前先获得一定的许可,或者说通过一定的身份认证。 这两个定义并不矛盾,我们为什么不可以把它们弄在一起?这是我们觉得未来可能会出现的一种新的区块链,我们把它叫做公有许可链。它既是一个公有链,有很多人一起使用;又是一个许可链,这上面的用户还有节点都是有身份的,这在技术上是可行的。 它的形态可能是说在共有的无许可链上再增加一个许可层或身份认证层,也有可能是完全构造一个独立的共有许可链,和共有无许可链平行。我们相信在未来,这两种类型的区块链会是非常好的互补。 在这样一个分布式的、支持智能合约的、有身份的平台上面,我们可以把今天的商业世界整个的搬到这个数字世界当中,我们可以实现企业与企业之间的商业流程自动化。 换句话说它其实是信任的自动化。 什么是信任呢? 信任就是说,我认识你,什么都别说了,把我的钱拿走,这就是信任。

June 4, 2019 · 1 min · jiezi

用Ruby在去中心化交易所OceanOne上挂单买卖任意ERC20-token

在上一课中,我们介绍了如何在OceanOne交易比特币。OceanOne支持交易任何Mixin Network上的token,包括所有的ERC20和EOS token,不需要任何手续和费用,直接挂单即可。下面介绍如何将将一个ERC20 token挂上OceanOne交易!在掌握了ERC20 token之后,就可以把任何token在Ocean上买卖。 此处我们用一个叫做Benz的ERC20 token为例。这个token已经被充值进Mixin Network,你可以在区块链浏览器看到这个token在Mixin Network内部的总数和交易 预备知识:先将Benz币存入你的钱包,然后使用getAssets API读取它的UUID. 取得该币的UUID调用 getAssets API 会返回json数据, 如: asset_id 币的UUID.public_key 该币的当前钱包的地址.symbol 币的名称. 如: Benz.if cmd == "aw" assetsInfo = walletAccount.read_assets() p "--------The Wallet Assets List-----------------" assetsInfo["data"].each { |x| puts x["symbol"] + " " + x["balance"] + " " + x["public_key"] + x["account_name"] + " " + x["account_tag"]} p "----------End of Wallet Assets --------------"end调用 read_assets API的完整输出如下: "--------The Wallet Assets List-----------------"Benz 10.03 0x822664c2EFb27E2Eb4c4286f421B4BF6FB943fC6ETH 0 0x822664c2EFb27E2Eb4c4286f421B4BF6FB943fC6EOS 0 eoswithmixin b0adfae2f8828d15e11cb1fbe23d6096USDT 1 1KB4RbV5W4MNybpjcJjULKNVXubfR5MJqACNB 0.99999995 0x822664c2EFb27E2Eb4c4286f421B4BF6FB943fC6BTC 0 1KB4RbV5W4MNybpjcJjULKNVXubfR5MJqA"----------End of Wallet Assets --------------"-------------------------------------------------------------------------限价挂单挂限价买单 低于或者等于市场价的单.挂限价卖单 高于或者是等于市场价的单.OceanOne支持三种基类价格: USDT, XIN, BTC, 即: Benz/USDT, Benz/XIN, Benz/BTC, 这儿示范Benz/USDT. ...

May 29, 2019 · 2 min · jiezi

以太坊中文文档翻译交易

本文原文链接点击这里获取Etherscan API 中文文档(完整版)完整内容排版更好,推荐读者前往阅读。 交易(Transaction)交易相关的 API,接口的参数说明请参考Etherscan API 约定, 文档中不单独说明。 [BETA] 检查合约执行状态(if there was an error during contract execution) Note: isError":"0" = Pass , isError":"1" = Error during Contract Execution https://api.etherscan.io/api?module=transaction&action=getstatus&txhash=0x15f8e5ea1079d9a0bb04a4c58ae5fe7654b5b2b4463375ff7ffb490aa0032f3a&apikey=YourApiKeyToken[BETA] 检查交易收据状态(Only applicable for Post Byzantium fork transactions) Note: status: 0 = Fail, 1 = Pass. Will return null/empty value for pre-byzantium fork https://api.etherscan.io/api?module=transaction&action=gettxreceiptstatus&txhash=0x513c1ba0bebf66436b5fed86ab668452b7805593c05073eb2d51d3a52f480a76&apikey=YourApiKeyToken点击获取Etherscan API 中文文档(完整版)示意图: 相关文档推荐:Solidity 中文文档(完整版)ethers.js 中文文档(完整版)Web3.js 中文文档(完整版)Truffle 中文文档(完整版)

May 26, 2019 · 1 min · jiezi

以太坊中文文档翻译区块

本文原文链接点击这里获取Etherscan API 中文文档(完整版)完整内容排版更好,推荐读者前往阅读。 区块(Blocks)区块相关的 API,接口的参数说明请参考Etherscan API 约定, 文档中不单独说明。 通过区块号获取块及叔块奖励https://api.etherscan.io/api?module=block&action=getblockreward&blockno=2165403&apikey=YourApiKeyToken示意图: 相关文档推荐:Solidity 中文文档(完整版)ethers.js 中文文档(完整版)Web3.js 中文文档(完整版)Truffle 中文文档(完整版)

May 26, 2019 · 1 min · jiezi

以太坊中文文档翻译智能合约

本文原文链接点击这里获取Etherscan API 中文文档(完整版)完整内容排版更好,推荐读者前往阅读。 智能合约(Contracts)智能合约相关的 API,接口的参数说明请参考Etherscan API 约定, 文档中不单独说明。 Newly verified Contracts are synced to the API servers within 5 minutes or less 获取已经验证代码合约的ABIVerified Contract Source Codes https://api.etherscan.io/api?module=contract&action=getabi&address=0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413&apikey=YourApiKeyTokenA simple sample for retrieving the contractABI using Web3.js and Jquery to interact with a contract var Web3 = require('web3'); var web3 = new Web3(new Web3.providers.HttpProvider()); var version = web3.version.api; $.getJSON('http://api.etherscan.io/api?module=contract&action=getabi&address=0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359', function (data) { var contractABI = ""; contractABI = JSON.parse(data.result); if (contractABI != ''){ var MyContract = web3.eth.contract(contractABI); var myContractInstance = MyContract.at("0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359"); var result = myContractInstance.memberId("0xfe8ad7dd2f564a877cc23feea6c0a9cc2e783715"); console.log("result1 : " + result); var result = myContractInstance.members(1); console.log("result2 : " + result); } else { console.log("Error" ); } });获取已经验证代码合约的源码https://api.etherscan.io/api?module=contract&action=getsourcecode&address=0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413&apikey=YourApiKeyToken点击获取Etherscan API 中文文档(完整版)示意图: ...

May 26, 2019 · 1 min · jiezi

以太坊中文文档翻译账号

本文原文链接点击这里获取Etherscan API 中文文档(完整版)完整内容排版更好,推荐读者前往阅读。 账号(Account)账号及地址相关的 API,接口的参数说明请参考Etherscan API 约定, 文档中不单独说明。 获取单个账号余额 译者注: 英文 `balance` 有人翻译为`金额`,译者习惯称为`余额`。 账号和地址大部分也是指一个意思。接口: /api?module=account&action=balance&address=0x&tag=latest&apikey=YourApiKeyToken返回: { status: "1", message: "OK", result: "40807178566070000000000"}说明: 余额的单位都是最小单位wei, 更多单位换算可阅读:以太单位换算 请求样例URL,点击可在浏览器查看效果。 获取多个账号余额接口: /api?module=account&action=balancemulti&address=0xabc,0x63..,0x198..&tag=latest&apikey=YourApiKeyToken使用,来分割地址,一次请求最多20个账号。 返回: {status: "1",message: "OK",result: [{account: "0xddbd2b932c763ba5b1b7ae3b362eac3e8d40121a",balance: "40807178566070000000000"},{account: "0x63a9975ba31b0b9626b34300f7f627147df1f526",balance: "332567136222827062478"}]}请求样例URL 获取地址(普通)交易列表接口: /api?module=account&action=txlist&address=&apikey=YourApiKeyToken可选参数:startblock 、endblock、sort 返回: { "status": "1", "message": "OK", "result": [{ "blockNumber": "47884", "timeStamp": "1438947953", "hash": "0xad1c27dd8d0329dbc400021d7477b34ac41e84365bd54b45a4019a15deb10c0d", "nonce": "0", "blockHash": "0xf2988b9870e092f2898662ccdbc06e0e320a08139e9c6be98d0ce372f8611f22", "transactionIndex": "0", "from": "0xddbd2b932c763ba5b1b7ae3b362eac3e8d40121a", "to": "0x2910543af39aba0cd09dbb2d50200b3e800a63d2", "value": "5000000000000000000", "gas": "23000", "gasPrice": "400000000000", "isError": "0", "txreceipt_status": "", "input": "0x454e34354139455138", "contractAddress": "", "cumulativeGasUsed": "21612", "gasUsed": "21612", "confirmations": "7525550" }]}说明: ...

May 26, 2019 · 1 min · jiezi

Awesome-Blockchain-区块链技术导航

区块链技术导航:收集整理最全面最优质的区块链(BlockChain)技术开发相关资源。以后找不到文档资料的时候去导航站看看。 先亮个像,我长这样: 导航站内容区块链开发所涉及的资源: 如 项目白皮书、黄皮书、SDK 文档及翻译、GitHub地址库、开发工具链、开发案例、音视频课程等。 涉及的技术有: 区块链主流技术如比特币、以太坊、超级账本、EOS等提供区块链前沿技术如跨链、侧链、Layer2、存储协议、DAG 、匿名技术等导航索引区块链技术导航区块链入门/比特币 区块链入门/比特币比特币闪电网络比特币术语区块链英文术语-中文对照以太坊 以太坊资源汇总开发文档以太坊扩容技术1以太坊扩容技术2以太坊术语柚子EOS超级账本IPFS/FileCoinDAG/树图跨链 波卡 Polkadot隐私/匿名技术Defi 去中心化金融技术动向课程学习区块链社区参与贡献本站有由一群区块链技术爱好者共同维护,欢迎大家提交内容,我们会第一时间处理,大家可以提交Issues,也可以提交Pull Request,这里还有一个份如何贡献操作指南 部分贡献者以下排名不分先后: Tiny熊虞是乎Bob尊重汗水,转载请注明来自 深入浅出区块链社区 - 技术导航站。

May 22, 2019 · 1 min · jiezi

使用-Nodejs-在开放交易所OceanOne上挂单买卖奔驰币

在上一课中,我们介绍了如何在OceanOne交易比特币。OceanOne支持交易任何Mixin Network上的token,包括所有的ERC20和EOS token,不需要任何手续和费用,直接挂单即可。下面介绍如何将将一个ERC20 token挂上OceanOne交易。掌握了ERC20代币的交易方法,就可以交易任何其他Mixin Network代币了。 此处我们用一个叫做Benz的ERC20 token为例。这个token已经被充值进Mixin Network,你可以在区块链浏览器看到这个token在Mixin Network内部的总数和交易 预备知识:先将Ben币存入你的钱包,然后使用getAssets API读取它的UUID. 取得该币的UUID调用 getAssets API 会返回json数据, 如: asset_id 币的UUID.public_key 该币的当前钱包的地址.symbol 币的名称. 如: Benz.if ( args.type === TYPE_WALLET_ASSETS_INFO ) { const assetsInfo = await newUserClient.getUserAssets(); console.log("-AssetID--Asset--Balance--public_key--"); assetsInfo.forEach(function(element) { console.log(element.asset_id + " " + element.symbol + " " + element.balance + " " + element.public_key + " " + element.account_name + " " + element.account_tag ); }); // console.log(assetsInfo);}调用 getUserAssets API的完整输出如下: ...

May 16, 2019 · 3 min · jiezi

以太坊智能合约之如何执行智能合约

区块链技术在顶级技术中占据主导地位的主要原因在于其去中心化。虽然区块链的主要目的是在没有中心的情况下维护交易记录,但为了实现自动化,智能合约被引入。那么在写完智能合约之后呢?在本文的这个以太坊智能合约教程中,我们将了解如何使用Truffle Ethereum和以太坊专用网络来执行智能合约。 我们将在以太坊智能合约教程中查看以下主题: 使用案例:保险流程中的智能合约智能合约的好处安装先决条件配置Genesis Block运行以太坊专用网络创建以太坊帐户创建以太坊智能合约执行以太坊智能合约使用案例:保险流程中的智能合约区块链遵循的是“没有中央权力机构”,这就是智能合约引入的原因。但你有没有想过如何使用智能合约?那么,在以太坊智能合约的这一部分中,我将解释保险流程中智能合约的使用案例。 让我们考虑一个航班延误保险的例子。假设你想要从出发地A到目的地C进行飞行,但你没有直接飞行。那么,你决定通过B来转机。现在,你的路线将从A到B,然后从B到C,其中B是机场,你将更改航班。不幸的是,从A到B以及从B到C的航班之间没有太大的时间差距。所以,如果有任何问题,一旦从A到B的航班延误,那么你将错过从B到C的航班。意识到这一点后,为了避免重大损失,你可能需要一个航班延误保险。 现在,如果你从A到B的航班延误(这将使你错过从B到C的航班),你将获得保险金额。这是正常的情况,如果你的航班延误,你可以申请保险。然后,有人会核实并批准保险,最后,你将获得你的保险金额。但这是一个漫长的过程。 你如何使用智能合约来改善保险流程?谈到金融交易,特别是当你拿钱时,“越快越好”,不是吗?那么,让我们看看智能合约如何加强保险流程。智能合约是数字合约,在满足特定条件时自动执行。如果航班延误,可以编写智能合约以向选择航班延误保险的人支付保险金额。因此,当航班延误并且系统记录此延迟时,保险将立即支付。 OK!保险金额在几秒钟内支付。这就是智能合约如何简单快速地实现流程。 智能合约的好处你已在上面的示例中看到智能合约如何加强财务流程。除快速交易外,智能合约还有更多好处。在这里,我列出了使用智能合约的其他一些好处: 自动化:智能合约自动执行所有步骤。没有中介:当你使用智能合约时,你不需要中介来完成工作,因为一切都将由智能合约处理。成本效益:使用智能合约可以节省银行收取的交易费用和中介(如果有的话)的服务费用。现在,我们知道如何使用智能合约来让世界变得更快,让我们亲身体验这个以太坊智能合约教程。 安装先决条件对于以太坊智能合约教程,我们需要5个重要的应用程序: NodeJSNPMEthereumTruffleSolidity Compiler安装NodeJSNodeJS是一个用于构建服务器应用程序的JavaScript框架。由于我们使用的是专用网络,因此NodeJS可以轻松构建网络应用程序。 要安装Nodejs,请在终端中运行以下命令: $ sudo apt-get install nodejs安装NPMNPM代表Node Package Manager,用于运行Nodejs应用程序。 要安装NPM,请在终端中运行以下命令: $ sudo apt-get install npm安装以太坊以太坊是一个基于开源和公共区块链的分布式计算平台,用于构建去中心化应用程序。 要安装以太坊,请在终端中运行以下命令: $ sudo apt-get install software-properties-common$ sudo add-apt-repository -y ppa:ethereum/ethereum$ sudo apt-get update$ sudo apt-get install ethereum安装TruffleTruffle是以太坊Blokchains的开发环境,测试框架和资产管道。 要安装Truffle,请在终端中运行以下命令: $ npm install -g truffle安装Solidity CompilerSolidity是一种用于编写智能合约的编程语言。要在我们的系统上运行智能合约,我们必须安装Solidity Compiler。 要安装Solidity Compiler,请在终端中运行以下命令: $ sudo npm install -g solc配置Genesis BlockGenesis Block是Blockchain的起点,我们需要一个genesis文件来启动Blockchain。在以太坊智能合约的这一部分中,我们将编写一个Genesis文件并对其进行配置以允许我们运行智能合约。 让我们首先创建一个新目录,然后在该目录中创建genesis文件: $ mkdir ethereum-network$ cd ethereum-network$ nano genesis.json现在,在genesis.json文件中输入以下行: ...

May 14, 2019 · 1 min · jiezi

用C在去中心化交易所OceanOne上挂单买卖任意ERC20-token

用C#在去中心化交易所OceanOne上挂单买卖任意ERC20 token 在上一课中,我们介绍了如何在OceanOne交易比特币。OceanOne支持交易任何Mixin Network上的token,包括所有的ERC20和EOS token,不需要任何手续和费用,直接挂单即可。下面介绍如何将将一个ERC20 token挂上OceanOne交易。掌握了ERC20的代币买卖之后,你就可以用同样的方法买卖任何EOS以及其他Mixin Network上的token 此处我们用一个叫做Benz的ERC20 token为例。这个token已经被充值进Mixin Network,你可以在区块链浏览器看到这个token在Mixin Network内部的总数和交易 预备知识:先将Ben币存入你的钱包,然后使用getAssets API读取它的UUID. 取得该币的UUID调用 getAssets API 会返回json数据, 如: asset_id 币的UUID.public_key 该币的当前钱包的地址.symbol 币的名称. 如: Benz.if (cmd == "aw" ) { // Console.WriteLine(mixinApi.VerifyPIN(USRCONFIG.PinCode.ToString()).ToString()); MixinApi mixinApiNewUser = GetWalletSDK(); var assets = mixinApiNewUser.ReadAssets(); string wuuid = GetWalletUUID(); Console.WriteLine("Current wallet uuid is " + wuuid); foreach (Asset asset in assets) { if (asset.symbol == "EOS") { Console.WriteLine(asset.symbol + " Public Address is: " + asset.account_name + " " + asset.account_tag + " Balance is: " + asset.balance); } else Console.WriteLine(asset.symbol + " Public Address is: " + asset.public_key + " Balance is: " + asset.balance); Console.WriteLine(); }}调用 getAssets API的完整输出如下: ...

May 9, 2019 · 3 min · jiezi

用PHP在去中心化交易所OceanOne上挂单买卖任意ERC20-token

在上一课中,我们介绍了如何在OceanOne交易比特币。OceanOne支持交易任何Mixin Network上的token,包括所有的ERC20和EOS token,不需要任何手续和费用,直接挂单即可。下面介绍如何将将一个ERC20 token挂上OceanOne交易! 此处我们用一个叫做Benz的ERC20 token为例。这个token已经被充值进Mixin Network,你可以在区块链浏览器看到这个token在Mixin Network内部的总数和交易 预备知识:先将Benz币存入你的钱包,然后使用getAssets API读取它的UUID. 取得该币的UUID调用 getAssets API 会返回json数据, 如: asset_id 币的UUID.public_key 该币的当前钱包的地址.symbol 币的名称. 如: Benz.if ($line == 'aw') { $mixinSdk_eachAccountInstance = GenerateWalletSDKFromCSV(); $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAssets(); foreach ($asset_info as $key => $asset) { echo $asset["symbol"] . " " . $asset["asset_id"] ." ". $asset["balance"] . " ". $asset["public_key"].PHP_EOL; }}调用 getAssets API的完整输出如下: Make your choose:awrun...client id is:26b20aa5-40c0-3e00-9de0-666cfb6f2daaBenz 2b9c216c-ef60-398d-a42a-eba1b298581d 799 0x9A4F6c67444cd6558905ef5B04a4c429b9538A9dEOS 6cfe566e-4aad-470b-8c9a-2fd35b49c68d 0CNB 965e5c6e-434c-3fa9-b780-c50f43cd955c 4.72599997 0x9A4F6c67444cd6558905ef5B04a4c429b9538A9dBTC c6d0c728-2624-429b-8e0d-d9d19b6592fa 0 17z1Rq3VsyvvXvGWiHT8YErjBoFgnhErB8XIN c94ac88f-4671-3976-b60a-09064f1811e8 0.01 0x9A4F6c67444cd6558905ef5B04a4c429b9538A9d限价挂单挂限价买单 低于或者等于市场价的单.挂限价卖单 高于或者是等于市场价的单.OceanOne支持三种基类价格: USDT, XIN, BTC, 即: Benz/USDT, Benz/XIN, Benz/BTC, 这儿示范Benz/USDT. ...

May 2, 2019 · 2 min · jiezi

Solidity-057简明教程

以太坊不仅是一种加密数字货币,它更是功能完备的智能合约平台,solidity就是用来开发以太坊上的智能合约的原生开发语言。solidity最早发布于2015年,它是第一种图灵完备的智能合约专用开发语言。目前除了以太坊之外,在其他区块链中也逐渐开始支持solidity,例如hyperledger fabric、tendermint等。在这个solidity快速教程中,我们将使用最新0.5.7版的solidity,以一个具体的案例来介绍solidity智能合约的开发、部署与交互,希望对你快速掌握solidity智能合约的开发有所帮助。 如果要高效系统地掌握以太坊智能合约与DApp的开发,推荐访问汇智网的在线互动课程:以太坊开发入门 | java以太坊 | python以太坊 | php以太坊 | C#以太坊 | 电商DApp实战 | ERC721通证实战 0、问题的背景有一个老爷爷,在生命的最后岁月别无他求,只是希望自己的财产能够通过遗嘱顺利地传给其他家庭成员。 在传统的遗嘱中,遗产分配方案是落实在法律文件上的,然后当真正开始分配时,法官需要重审文件并做出相应的决定。常见的问题发生在家庭成员之间对分配比例的争执上,甚至因此而导致家庭成员关系的破裂。在法庭听证阶段,这些都会影响法官最终的裁决,并因此可能导致不公平的结果,甚至对家庭关系造成进一步的伤害。 那么,如果我们可以让遗产分配自动进行,是否可以避免上述情况的发生? 如果遗产是一个智能合约,那么就不需要法官了。老爷爷可以自主地利用合约管理资产,然后在他去世后由程序来分配遗产给家庭成员。合约里的代码就决定了最终的分配结果,因此无需法官的介入。例如萨拉分$10000,本得到$5000,朱丽叶得到$2000。代码执行后,资产以代币或加密货币的形式自动分配给这些家庭成员,而无需人工介入。虽然不能保证每个成员都对遗产的分配结果满意,但是没有人会和代码争执。这听起来还比较可行,对吗? 记住这个案例,在这个快速教程中,我们将使用solidity,为老爷爷开发一个简单的遗嘱合约,来满足他最后的愿望。 1、搭建solidity开发环境开发solidity智能合约最简单的方法,就是使用官方提供的在线集成开发环境REMIX,你可以点击这里打开remix,在网页里就完成solidity智能合约的编写、编译与部署: 在你打开remix页面后,注意在右侧的run选项页,environment下拉框中,要选中JavaScript VM。这个选项的意思是使用一个内存仿真以太坊节点作为你的solidity智能合约的运行平台,这样就不用考虑与实际的以太坊主网交互所需要的账号、资金、计算费用等问题,而可以先把精力聚焦在学习如何使用solidity表达你的业务逻辑上。 点击remix页面左上方的+图标,就可以创建一个新的代码文件,我们将其命名为will.sol。在remix页面中间的编辑区域可以同时显示多个文件,当前正在编辑的文件,则以活动选项页的形式显示文件名称。 2、声明solidity编译器版本solidity还是很早期阶段的语言,从语法到编译器都在不断地演化,所以在solidity代码的第一行,一定要用pragma关键字声明这个文件中的solidity代码需要哪个版本的编译器。例如: 注意在solidity中,末尾的分号不可省略。 3、编写第一个solidity合约接下来就可以定义我们的第一个合约: 使用contract关键字来定义一个合约,solidity的合约类似于我们熟悉的OOP中的类,因此通常合约的名称首字母也会大写,例如Will。一对大括号用来定义合约的实现逻辑,单行注释也使用//,这和很多开发语言都类似。 4、solidity中的全局变量和构造函数在我们开始写代码之前,应当首先明确遗嘱的条款。假设老爷爷的遗产是50个以太币,其中20个留给他的儿子康莱德,剩下的30个留给他的妻子丽莎。在真实的环境中,当老爷爷去世后,应当有一个外部的程序将调用合约中定义的方法来分配遗产,但是我们为了便于学习将自己完成这个调用。 现在,让我们先完成如下代码: 表征合约所有者的变量表征遗产数量的变量表征老爷爷是否还健在的变量设置上述变量初始值的构造函数 第5行代码定义了合约的所有者。当我们在solidity中定义变量时,必须先声明其类型。address是solidity中一种特殊的类型,它表示一个以太坊地址。address类型的变量有一些特殊的方法,我们在后面会进一步了解。 第6行代码定义的fortune变量用来保存老爷爷的遗产数量,它的类型是uint或unsigned int,意思是这个变量是0或正整数。solidity中有很多数据类型,但我们不会在这里一一介绍,你可以在官方文档中深入了解solidity的数据类型。 第7行代码定义的isDeceased变量用来标识老爷爷是否已经去世,这是一个开关量,因此其类型为boolean,可能的值只有两个:true或false,默认值为false。 第9~13行代码是合约的构造函数,这个特殊的函数将在合约部署的时候自动执行。 public关键字被称为可见性修饰符,它的作用是声明被修饰的方法是否允许外部调用。public意味着在合约内部或外部(由其他合约或其他人)都可以调用该方法。 payable关键字是solidity的特色之一,它使得被修饰的方法可以发送或接收以太币。为构造函数声明payable关键字意味着当我们部署合约的时候,可以直接向合约存入以太币,例如,作为遗产的50个以太币。当合约接收到以太币后,这些币就保存在合约地址上了。 在构造函数内部,我们将owner变量的值设置为msg.sender,这是一个以太坊平台预置的全局变量,表示调用合约方法的账号地址,在我们的案例中,这的地址是老爷爷的。 同时我们将fortune变量的值设置为msg.value,这是另一个全局变量,它表示被调用的方法接收到的以太币的数量。 虽然变量isDeceased被自动初始化为默认值false,但为了清晰起见,我们将其显式地设置为false。 5、使用solidity修饰符在solidity中,修饰符(Modifier)可以为函数附加额外的条件逻辑。例如,假设我有一个用来关灯的方法,同时有一个修饰符要求灯开关必须处于on状态,那么我们就可以在方法上附加声明这个修饰符,以便确保只有在灯开关处于on状态时,才可以调用这个方法,否则就抛出异常。 第15行代码定义了onlyOwner修饰符。如果一个方法附加声明了这个修饰符,那么就要求调用方法的账号(msg.sender)必须与owner变量的值一致(别忘了我们在构造函数中设置了owner的值)。这个调用条件有助于遗产的分配,我们将在后面看到这一点。 require关键字的意思是,括号里的表达式的值必须为真(true),否则就会抛出异常,不再继续执行代码。 _;起到占位符的作用,在执行过程中,以太坊虚拟机会用被修饰的方法代码来替换它。 第20行代码定义了mustBeDeceased修饰符。如果一个方法附加声明了这个修饰符,那么就只有在isDeceased变量值为true时,才可以调用该方法,否则就抛出异常。 在上面的代码中,我们使用修饰符来限定方法的执行条件,当然也可以不使用修饰符,而直接在方法实现代码中使用require,不过修饰符看起来更高级一些,也更容易实现代码的复用。 6、设定遗产分配方案现在我们要继续完成遗产在家庭成员之间的分配任务,这需要他们的钱包地址和分配数量。 正如我们之前所述,康莱德将收到20个以太币而丽莎将继承30个。让我们创建一个数组来保存他们的钱包地址,然后写一个方法来分配遗产。 第25行代码定义了一个空数组familyWallets,用来保存所有家庭成员的钱包地址。和其他语言一样,在solidity中数组是顺序存放并且可以使用序号来存取。注意方括号之前的关键字paybale,只有address payable类型的变量,才可以接收以太币,这是0.5版本的solidity与之前版本的区别之一。 第27行代码创建了一个从address类型到uint类型的映射表变量inheritance,用来保存每个钱包地址的遗产数量。这是一个键/值对数据结构,类似于其他语言中的字典或哈希表,可以用键来存取值。 第29行代码定义了一个方法,它的功能是将一个钱包地址添加到familyWallets数组,然后设置该地址在inheritance映射表中的遗产数量。注意附加的onlyOwner修饰符,猜一下为什么我们要在这里声明这个修饰符? 第30行代码将传入方法的钱包地址追加到familyWallets数组的末尾。 第31行代码将传入方法的遗产继承数量设置为映射表inheritance的指定地址(传入方法的另一个参数)的值。 7、实现遗产自动分配让我们总结一下。到目前为止,我们已经学习了全局变量、数据类型、构造函数、特殊的关键字例如payable和public、内置的全局变量例如msg.sender和msg.value、修饰符和require、数组、映射表和方法。我们已经搭好了合约的框架,现在让我们把各部分整合起来最终完成合约。 作为这个教程最后一部分的代码,我们将实现家庭成员遗产的自动分配。 第34行定义了payout()方法,注意private关键字,这个可视性修饰符是public的反义词,它只允许被修饰的方法在合约内部调用,就像在第42行的代码那样。之所以在这里使用private,主要是考虑到安全性,因为我们不希望任何来自合约外部的调用。注意最后的mustBeDeceased修饰符,目前我们依然不能满足这个修饰符要求的条件来执行payout()方法。 第35行代码是一个for循环,用来遍历familyWallets数组。语法如下: 定义一个计数器变量i,声明循环的执行条件每个周期计数器变量i加1第36行代码是整个合约的核心,我们调用address类型的地址对象的transfer()方法,向该地址转账预定的遗产继承数量,inheritance[familyWallets[i]]表示在inheritance映射表中,键familyWallets[i]的值,也就是第i个家庭成员的遗产继承数量。 ...

April 29, 2019 · 1 min · jiezi

在OceanOne上挂单买卖任意ERC20-token

在上一课中,我们介绍了如何在OceanOne交易比特币。OceanOne支持交易任何Mixin Network上的token,包括所有的ERC20和EOS token,不需要任何手续和费用,直接挂单即可。下面介绍如何将将一个ERC20 token挂上OceanOne交易! 此处我们用一个叫做Benz的ERC20 token为例。这个token已经被充值进Mixin Network,你可以在区块链浏览器看到这个token在Mixin Network内部的总数和交易 预备知识:先将Ben币存入你的钱包,然后使用getAssets API读取它的UUID. 取得该币的UUID调用 getAssets API 会返回json数据, 如: asset_id 币的UUID.public_key 该币的当前钱包的地址.symbol 币的名称. 如: Benz.if ( input.equals("aw") ) { MixinAPI mixinApiUser = generateAPI_FromCSV(); JsonArray assets = mixinApiUser.getAssets(); System.out.println("------------------------All Assets Information---------------------------"); System.out.println(assets); assets.forEach((element) -> { JsonObject jsonObj = element.getAsJsonObject(); System.out.println(jsonObj.get("asset_id").getAsString() + " " + jsonObj.get("symbol").getAsString() + " " + jsonObj.get("public_key").getAsString() + " " + jsonObj.get("balance").getAsString() ); }); System.out.println("-----------------------------------------------------------------------");}调用 getAssets API的完整输出如下: ...

April 28, 2019 · 3 min · jiezi

以太坊创世区块与链配置载入分析

原文链接请大家前往深入浅出区块链主站, 获取最新内容。 创世区块作为第零个区块,其他区块直接或间接引用到创世区块。因此节点启动之初必须载入正确的创世区块信息,且不得任意修改。 以太坊允许通过创世配置文件来初始化创世区块,也可使用选择使用内置的多个网络环境的创世配置。默认使用以太坊主网创世配置。 创世配置文件如果你需要搭建以太坊私有链,那么了解创世配置是必须的,否则你大可不关心创世配置。下面是一份 JSON 格式的创世配置示例: { "config": { "chainId": 1, "homesteadBlock": 1150000, "daoForkBlock": 1920000, "daoForkSupport": true, "eip150Block": 2463000, "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", "eip155Block": 2675000, "eip158Block": 2675000, "byzantiumBlock": 4370000, "constantinopleBlock": 7280000, "petersburgBlock": 7280000, "ethash": {} }, "nonce": "0x42", "timestamp": "0x0", "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa", "gasLimit": "0x1388", "difficulty": "0x400000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "coinbase": "0x0000000000000000000000000000000000000000", "number": "0x0", "gasUsed": "0x0", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "alloc": { "000d836201318ec6899a67540690382780743280": { "balance": "0xad78ebc5ac6200000" }, "001762430ea9c3a26e5749afdb70da5f78ddbb8c": { "balance": "0xad78ebc5ac6200000" } }}根据配置用途可分为三大类: ...

April 25, 2019 · 3 min · jiezi

如何开发一款以太坊安卓钱包系列3 - 资产信息展示

这是如何开发以太坊(安卓)钱包系列第3篇, 钱包账号资产信息展示,展示信息主要包括账号地址、eth余额及该账号所拥有的Token及余额。预备知识 MVVM本文会涉及和UI界面的交互,提前理解下界面和数据如何交互是非常有必要的,如果你已经很熟悉MVVM,可跳过这一小节。最早写Android的时候,数据和界面经常耦合在一起,一个Activity文件总是特别大,每当产品界面改版就非常痛苦,吐槽下,很多产品经理都喜欢对界面改来改去。后来Google 推荐多个架构模式: MPV、 MVVM模式来解决数据和UI耦合的问题,登链钱包代码,使用的就是MVVM模式,所以对它做一个简单介绍,下面是MVVM的视图和数据的交互图:View 通常对应于Activity/Fragment/自定义ViewModel:则是和数据相关的模块。View 与 Model 不直接发生联系, 而是通过ViewModel负责接收View层的事件以及获取并处理数据,ViewModel层的数据变化也会通知给View层进行相应的UI的更新,从而实现业务逻辑和Ui的隔离。使用MVVM模式最大的优点就是解耦, 因为数据处理逻辑是独立于View, 在UI更改时,ViewModel 不用做太多改动。我们使用了Google在I/O大会推出的一套遵循MVVM开发模式的LiveData和ViewModel组件架构。ViewModel 和 LiveDataViewModel 会关注UI生命周期来存储和管理数据,在Activity发生变化(锁屏开屏、旋转)时,ViewModel 会自动保留之前的数据并给新的Activity或Fragment使用,当界面被系统销毁时,ViewModel也会进行资源清理,避免内存泄漏。ViewModel 还可以用于不同界面间数据共享。LiveData是一个可观察的数据持有者类。观察者可以方便我们以异步的方式获取数据,同时LiveData也是有生命周期感知的。如果其生命周期处于STARTED或RESUMED状态。LiveData会将观察者视为活动状态,并通知其数据的变化。LiveData未注册的观察对象以及非活动观察者是不会收到有关更新的通知。了解更多,可自行以关键字: Lifecycle、ViewModel、LiveData 进行搜索。账号信息展示展示信息主要包括账号地址、eth余额及该账号所拥有的Token及余额, 其界面效果如下:这个界面应的是登链钱包的PropertyFragment,上图的UPT 是我自己发行的Token,所以没有显示价格现在我们来思考一下, 怎么来展现上面的数据, 别着急往下看, 可以先想想。先对问题做一个拆分,把数据拆分为4个部分:显示当前选中的账号显示当前账号 ETH 余额显示当前账号下 Token 数量显示对应的法币金额。为了避免 UI 与上面4个数据的耦合,代码使用了一个TokensViewModel, 获取到的数据用 LiveData做了一个Wrap,以便UI可以订阅数据,TokensViewModel类像下面,代码有删减:public class TokensViewModel extends ViewModel { private final MutableLiveData<ETHWallet> defaultWallet; private final MutableLiveData<NetworkInfo> defaultNetwork; private final MutableLiveData<Token[]> tokens; private final MutableLiveData<Ticker> prices;}MutableLiveData 是前面提到的 LiveData的子类,在UI界面中就可以对数据进行订阅,下面我们逐一拆解下每个数据。显示当前账号可以分为两个步骤:从数据库中读取账号;界面显示账号TokensViewModel中定义了一个MutableLiveData<ETHWallet> defaultWallet ,从数据库中读取账号会保存在defaultWallet中,然后UI对 defaultWallet 进行观察显示。注解: 登链钱包 里大量使用的这个方式,通过一个LiveData 做数据桥接。在上一篇导入账号及账号管理,所有的账号使用greenDao 存储起来, 因此我们只需要把所有账号从加载出来,挑选出当前选中的那一个。 结合代码看一看:// WalletDaoUtils.java public static ETHWallet getCurrent() { List<ETHWallet> ethWallets = ethWalletDao.loadAll(); for (ETHWallet ethwallet : ethWallets) { if (ethwallet.isCurrent()) { ethwallet.setCurrent(true); return ethwallet; } } return null; }上面代码先用 ETHWalletDao.loadAll 加载出所有的账号,返回当前选中的,上面的代码会被FetchWalletInteract 类的 findDefault方法调用,在ViewModle里,很多时候以数据进行交互的类,我们会命名为 xxxInteract,这也是一个习惯用法。其代码如下: // FetchWalletInteract.java // 返回一个可订阅的Single<ETHWallet> 对象 public Single<ETHWallet> findDefault() { return Single.fromCallable(() -> { return WalletDaoUtils.getCurrent(); }).subscribe(this::onDefaultWallet); } // 获取到默认钱包账号 设置到 defaultWallet 这个LiveData private void onDefaultWallet(ETHWallet wallet) { defaultWallet.setValue(wallet); }findDefault()返回一个可订阅的Single<ETHWallet> 对象,如果不熟悉可参考后面的文档。之后,在UI界面 PropertyFragment.java 中, 就可以对 defaultWallet 进行订阅:tokensViewModel.defaultWallet().observe(this, this::showWallet);当获取到默认账号时,就会回调showWallet:// UI 显示 public void showWallet(ETHWallet wallet) { tvWalletName.setText(wallet.getName()); tvWalletAddress.setText(wallet.getAddress()); }这样, 界面的显示就完成了,下一篇继续介绍获取余额。参考文档lifecycle官方文档地址RxAndroid 了解更多响应式编程我创建了一个专门讨论钱包开发的微信群,加微信:xlbxiong 备注:钱包。加入知识星球,和一群优秀的区块链从业者一起学习。深入浅出区块链 - 系统学习区块链,学区块链的都在这里,打造最好的区块链技术博客。本文原文链接 ...

April 4, 2019 · 1 min · jiezi

mac下编译go-ethereum

macos: 10.14.4下载go-ethereum源码,按照文档执行命令编译:$ make all 报错:fatal error: ‘stdlib.h’ file not found/usr/include查看xcode是否安装:$ xcode-select –install xcode-select: error: command line tools are already installed, use “Software Update” to install updates$ xcode-select -p /Applications/Xcode.app/Contents/Developer$ brew configClang: 10.0 build 1001Git: 2.20.1 => /usr/local/bin/gitmacOS: 10.14.4-x86_64CLT: 10.2.0.0.1.1552586384Xcode: 10.2CLT headers: 10.2.0.0.1.1552586384发现xcode已经安装。使用命令查看 clang++的 include 搜索路径(#include <…> search starts here: 后面)。$ clang++ -E -x c++ - -v < /dev/nullignoring nonexistent directory “/usr/include/c++/v1"ignoring nonexistent directory “/usr/include"发现忽略了不存在的/usr/include。 说明macOS SDK 的头文件不存在。安装llvm:$ brew install llvm问题仍然存在。安装头文件:$ cd /Library/Developer/CommandLineTools/Packages/$ open macOS_SDK_headers_for_macOS_10.14.pkg再次编译go-ethereum, 通过。 问题解决。参考资料:1、https://stackoverflow.com/que…2、https://www.cnblogs.com/flipp…3、https://apple.stackexchange.c… ...

March 29, 2019 · 1 min · jiezi

跨链技术的分析和思考

当前的区块链底层技术平台百花齐放,不同的业务、不同的技术底层的区块链之间缺乏统一的互联互通的机制,这极大限制了区块链技术和应用生态的健康发展。跨链的需求由此而来,本文通过分析几种主流的跨链方案探讨跨链技术的本质及相应的解决思路。<!– more –>跨链的类型跨链交互根据所跨越的区块链底层技术平台的不同可以分为同构链跨链和异构链跨链:同构链之间安全机制、共识算法、网络拓扑、区块生成验证逻辑都一致,它们之间的跨链交互相对简单。而异构链的跨链交互相对复杂,比如比特币采用PoW算法而联盟链Fabric采用传统确定性共识算法,其区块的组成形式和确定性保证机制均有很大不同,直接跨链交互机制不易设计。异构链之间的跨链交互一般需要第三方辅助服务辅助跨链交互。主流跨链机制概述截至目前,主流的区块链跨链技术方案按照其具体的实现方式主要分为三大类,分别是公证人机制、侧链/中继和哈希锁定:公证人机制(Notary schemes): 公证人也称见证人机制,公证人机制本质上是一种中介的方式。具体而言,假设区块链A和B本身是不能直接进行互操作的,那么他们可以引入一个共同信任的第三方作为中介,由这个共同信任的中介进行跨链消息的验证和转发。公证人机制的优点在于能够灵活地支持各种不同结构的区块链(前提是公证人能够访问相关方的链上信息),缺点在于存在中心化风险。哈希锁定(Hash-locking): 哈希锁定技术主要是支持跨链中的原子资产交换,最早起源自比特币的闪电网络。其典型实现是哈希时间锁定合约HTLC(Hashed TimeLock Contract)。哈希锁定的原理是通过时间差和影藏哈希值来达到资产的原子交换。哈希锁定只能做到交换而不能做到资产或者信息的转移,因此其使用场景有限。侧链/中继链(Sidechains / Relays): 侧链是指完全拥有某链的功能的另一条区块链,侧链可以读取和验证主链上的信息。主链不知道侧链的存在,由侧链主动感知主链信息并进行相应的动作。而中继链则是侧链和公证人机制的结合体,中继链具有访问需要和验证进行互操作的链的关键信息并对两条链的跨链消息进行转移。从这个角度看中继链也是一种去中心的公证人机制。下面就这几种跨链方式的典型实现方式进行详细分析:典型跨链机制实现分析公证人机制最传统的公证人机制是基于中心化交易所得跨链资产交换,这种跨链的方式比较单一,只支持资产的交换,如下图演示了Alice通过交易所,用比特币和Bob交换ETH的过程。 Alice 通过交易所钱包将自己的比特币打入交易所地址;Alice 在交易所上挂上卖单1个BTC卖出20ETH价格;Bob需要将自己的ETH打入交易所的以太坊地址;Bob通过交易所挂出购买比特币的单子 20ETH买一个比特币;交易所将Alice的卖单和Bob的卖单进行撮合;交易所将Alice在交易所存储的1BTC 转移给Bob的比特币地址;交易所将Bob在交易所存储的20ETH 转移给Alice的以太坊地址;至此完成了Alice和Bob的BTC和ETH的交换(案例中省去了交易所的服务费)。通过该例子可以看出交易所的方式目前仅能够支持资产的交换,且资产交换的原子性、安全性完全由中心化的交易所保障存在较大的中心化风险。除此之外还有一种著名的分布式账本技术Ripple,也是采用类似公证人的机制来解决全球金融机构之间的资产交换。Ripple的系统架构如上图所示,Ripple系统中交易通过网络中的验证者进行交易的验证,验证者验证的交易通过加密算法保护交易内容不能被验证着窥探从而保证交易的隐私性。公证人机制的跨链技术实现简单,且能够比较灵活地支持不同类型的底层区块链体系。公证人机制的主要问题在于公证人机制的安全性保障完全由公证人系统保障。参与跨链的相关方需要对中间人给予较大的信任。哈希锁定哈希时间锁定(HTLC)最早出现在比特币的闪电网络,跨链资产交换支持一定数量的A链资产和一定数量的B链资产进行原子交换。哈希时间锁定巧妙地采用了哈希锁和时间锁,迫使资产的接收方在deadline内确定收款并产生一种收款证明给打款人,否则资产会归还给打款人。收款证明能够被付款人用来获取接收人区块链上的等量价值的数量资产或触发其他事件。如下图所示,我们用一个例子来阐述如何使用哈希时间锁定进行跨链的原子资产交换,假设Alice和Bob有资产交换的需求,Alice想用1个BTC和Bob换20个ETH. 那么首先需要在两条链上设置哈希时间锁定合约,然后执行如下步骤:Alice 随机构建一个字符串s,并计算出其哈希 h = hash(s);Alice 将h发送给Bob的合约;Alice锁定自己的1个BTC资产,并设置一个较长的锁定时间t1, 并设置了获取该BTC的一个条件:谁能够提供h的原始值s就可以得到该BTC;Bob观察到Alice 合约中锁定了一个BTC, 然后Bob锁定自己的20个ETH资产,并设置一个相对较短的锁定时间t2, t2 < t1, Bob也设置了同样获取条件(谁提供h的原始值s就可以获取20个ETH);Alice将自己最初生成的字符串s 发送到Bob的合约里取得了20个ETH;Bob观察到步骤5中Alice的s值,将其发送给Alice的合约成功获取1个BTC; 至此Alice和Bob完成了资产的交换。从上述的过程我们可以看出哈希时间锁定合约有一些约束条件:进行跨链资产交换的双方必须能够解析双方的合约内部数据,例如s,例如锁定资产的证明等;哈希锁定的超时时间设置时需要保证存在时间差,这样在单方面作弊时另一方可以及时撤回自己的资产。哈希锁定的思想运用在支付领域较多,例如闪电网络、雷电网络以及跨链资产转移协议Interledger等。但是哈希锁定目前看只适合偏资产或者关键数据的交换,甚至不支持转移因此其试用场景受限。侧链/中继链侧链侧链是相对于主链而言的,最初的侧链提出是针对比特币做新特性的测试和研发。侧链相对主链而言能够验证和解析主链中的区块数据和账本数据。侧链实现的基础技术是双向锚定(Two-way Peg),通过双向锚定技术可以将数字资产在主链上进行锁定,同时将等价的资产在侧链中释放。相反当侧链中相关资产进行锁定时,主链上锚定的等价资产也可以被释放。BTC-Relay是号称的史上第一个侧链,BTC-Relay是通过以太坊构建了一个比特币的侧面,运用以太坊的智能合约允许用户验证比特币的交易。这里我们仍然以Alice 1BTC和Bob的20ETH数字资产交换为例阐述相应原理:Bob将20ETH发送到BTCSwap的合约进行冻结;(该合约只要能够确认BTC网络上Bob接收到来自Alice 1BTC就自动将20ETH转给Alice)Alice 确认Bob冻结信息后,将1 BTC转给Bob比特币账户;BTC Relayer将比特币区块头推送到BTCSwap合约;Alice 接下来就可以调用relay tx;BTCSwap合约结合tx和BTC链的区块链进行SPV验证,验证通过则将20ETH转给Alice以太坊地址。这种跨链的实现方式简单,但是BTC Relay需要额外的信任和维护成本,且智能合约内部的数据存储会有体积膨胀的问题。但是侧链的机制相对哈希锁定而言能够提供更多的跨链交互场景,侧链以及类SPV验证的思想适合所有跨链的场景。中继链中继链本质上算是公证人机制和侧链机制的融合和扩展,目前社区内最活跃的两个跨链项目Cosmos 和 Polkadot 采用的都是基于中继链的多链多层架构,其中Cosmos目前支持的是跨链资产交互而Polkadot则宣称提供任意类型的跨链交互,具体实现还有待观察。CosmosCosmos网络是一个多链混合的区块链网格结构,如下图所示,该网络中主要包括两种角色:Hub: 用于处理跨链交互的中继链;Zone: Cosmos中的平行链, Cosmos中平行链需要具备两个前提条件: 1. 快速确定性(fast finality), 这个特性由共识算法保障,也就是说Cosmos的跨链不直接支持PoW等概率确定模型的区块链; 2. 强监管性(Sovereignty):每个平行链都具有一组验证者能够决定其出块。 为了支持平行链之间的跨链互操作,Cosmos提出了一种跨链交互协议IBC(Inter-Blockchain Communication protocol), 并利用tendermint共识算法的即时确定性实现多个异构链之间的价值和数据传输。首先我们以Chain A 到Chain B 转账10 token为例说明使用IBC的跨链交互: 1. 互相跟踪,也就是说如果A要和B进行跨链交易,那么A和B链需要分别运行相当于对方区块链的轻节点服务,这样互相可以实时接收到对方的区块头信息(方便后续执行类SPV验证); 2. A链上初始化IBC协议,冻结相关资产10 token, 并生成相应的证明发送给B区块链; 3. B链接收到相应的IBC消息,通过A链的区块头信息确定A确实进行相应的资产冻结,然后B链会生成等价值10 token的资产。以上是使用IBC协议的两个平行链直接进行跨链的基本过程,如果区块链很多,那么这种方式的两两跨链复杂度会呈现组合级别增加。因此Cosmos网络又引入了一种Hub的中继链,所有的平行链都通过IBC连接到Hub,让Hub辅助跨链交易的验证和转移,目前Cosmos实现了一个官方的Hub称为Cosmos Hub(如前图所示)。如下图所示是Cosmos 网络的详细架构图,Cosmos为方便平行链开发提供了基本服务CosmosSDK包括:共识、网络以及IBC协议等,这样基于Cosmos SDK开发的子链之间都能够方便地互相交互。此外对于非Cosmos SDK 开发的区块链需要使用Peg Zone进行桥接,如图中的Ethereum。笔者认为Cosmos为跨链带来的最大贡献在于IBC协议的设计,IBC协议提供了一种通用的跨链协议标准。IBC的设计使得跨链交易可以在多个Hub之间进行安全路由和转发,类似目前互联网的TCP/IP 协议。但是遗憾的是目前的Cosmos设计也只能够支持资产的跨链,而且由于不同区块链的业务不同其共识速率的不一致也会影响跨链交易有效性的证明。PolkadotPolkadot也是一种集成平行链和中继链的多层多链架构,Polkadot区块链的整体架构图如下图所示,主要包含三种角色链和四种参与方:三种链角色:中继链(Relay chain): 中继链位于Polkadot的体系的核心地位,主要是为整个系统提供统一的共识和安全性保障;平行链(Parachain): 在Polkadot中平行链负责具体的业务场景,平行链自身不具备区块的共识,它们将共识的职责渡让给了中继链,所有平行链共享来自中继链的安全保障,中继链是Polkadot组成的一部分;桥接链:桥接链指的是非Polkadot体系之外的区块链,如Bitcoin, Ethereum, 这些区块链有自身的共识算法,它们通过不同的Bridge与Polkadot连接在一起进行跨链交互。四种参与方:验证者(Validator): 验证者负责Polkadot的网络出块,会运行一个中继链的客户端,在每一轮区块产生中会对其提名的平行链出的块进行核验。当平行链的跨都被他们的子验证者集合确定好之后,验证者们会将所有平行链区块头组装到中继链的区块并进行共识。核验人(Collator): 帮助验证者收集、验证和提交备选平行链区块,维护了一个平行链的全节点。钓鱼人(Fisherman):钓鱼人主要靠检举非法交易或者区块以获取收益;提名人(Nominator): 拥有stake的相关方,维护和负责验证者的安全性。Polkadot的特性包括两个,一个是共享安全性,一个是不需信任的跨链交互。这里的不需信任的跨链交互其实是和第一个特点共享安全性密切相关的,而且Polkadot的不需信任的跨链交互也主要是只其内部的平行链之间。在Polkadot中如果parachain A 需要发送一笔交易到parachain B的过程如下:A链将跨链交易放到自己的engress(每个平行链有一个消息输出队列engress 和一个消息输入队列ingress);A链的Collator收集A链的普通交易以及跨链交易并提交给A链的验证者集合;A链的验证者集合验证成功,将本次A链的区块头信息以及A链的engress内信息提交到中继链上;中继链运行共识算法进行区块确认以及跨链交易路由,中继链上的验证者会将A链的相应交易从A链的engress queue中移动到B链的ingress queue中。B链执行区块,将ingress queue中相应交易执行并修改自身账本。以上便是Polkadot跨链交易的主要步骤,由于所有平行链的共识同步发生(中继链区块示意图如下),因此跨链交易不会有诸如双花等安全性问题。Polkadot 的平行链之间的跨链交换的安全性保障主要来自共享安全性这个特点,共享安全性使得跨链交易和普通交易同步发生也就不存在其他跨链场景中的双花等跨链数据不一致问题。其次Polkadot中的引入的特殊状态验证方法方便中继链进行跨链等消息的有效性验证。值得一提的是Polkadot项目目前还处在项目初期,对于parachain的设计、Collator的协作以及Validator的共识、工作效率等都未完善。这种共享安全性的方式是否也限制了平行链自身的性能都还有待考证。关于跨链技术的几点思考综合以上的一些主流跨链场景和方案的分析,从跨链的概念以及需求上看跨链的本质其实就是 如何将A链上的消息M安全可信地转移到B链并在B链上产生预期效果。那么一个成功的跨链交互到底需要解决哪些问题呢?笔者认为主要有以下四个问题:消息M的真实性证明,也就是说M是否确实是存在A链上的,也确实是A链发给B链的;消息M的路由,如何让跨链消息安全跨系统路由;消息M的有效性证明,这里的有效性是指来自A链的消息M如何让B链认可其抵达B链时状态仍然有效,比如转移的资产是否是冻结的,没有双花的,如果是状态那么是否在此期间未发生改变等;消息M的执行结果证明,这个是指A链需要确认跨链操作是否成功,以及成功操作的相应回执。那么针对这些关键本质问题,如何去处理呢?笔者设想未来的区块链应该在底层平台的设计之初就需要遵循统一的跨链协议标准,就像现在的操作系统对TCP/IP协议的支持一样。需要进行通用跨链的区块链至少要支持一下功能:提供跨链消息的输入和输出口径,例如Cosmos和Polkadot的跨链队列;提供跨链消息的真实性证明,区块链需要提供类似SPV的证明手段;消息的有效路由需要构建跨链消息的统一格式,定义好消息的来源和去处以及消息内容,如Cosmos的IBC协议;消息的有效性证明,区块链可能需要设计新的类似UTXO的可验证存储结构,方便做类SPV类验证,否则目前的基于KV的数据存储方式做有效性证明几乎不可能;跨链执行结果证明,和有效性证明类似,需要全新的数据结构和运行算法支持。除此之外,跨链系统的设计还需要考虑系统稳定性、可扩展性以及易升级性、容错等等,总而言之,真正的可信互联网建设艰辛蛮长,诸君共勉!本文经作者授权转自BITKING深入浅出区块链 - 系统学习区块链,打造最好的区块链技术博客。????本文原文链接 ...

March 26, 2019 · 1 min · jiezi

如何开发一款以太坊(安卓)钱包系列1 - 通过助记词创建账号

上周我开源了一款钱包,反映很好,一周时间不到已经快到100 Star。接下来我会几篇系列文章把开发以太坊钱包的核心要点写出来,也算是对代码的一个解读。写在前面钱包是使用Android安卓平台编写,使用的是原生代码Java 语言编写, 是基于Java 1.8 版本,也使用了Java 1.8 中一些较新的语言特性,如 Lambda表达式等;另外还较多使用了ReactiveX/RxAndroid响应式编程用法。在本系列文章中,重点是介绍以太坊钱包账号、交易等逻辑,有时可能会假定读者已经了解Android开发等相关知识,因为这些内容不是文章的重点,因此不会过多介绍,请海涵。钱包包含的功能通常一个钱包会包含以下功能:[x] 支持通过生成助记词、Keystore文件、私钥 创建钱包账号。[x] 支持导出钱包账号助记词、私钥、Keystore文件。[x] 支持多个钱包账号管理[x] 账户余额查询及转账功能(二维码扫描支持)。[x] 支持ERC20 代币(余额显示、转账、代币币价显示)[x] 支持用法币(美元和人民币)实时显示币价。[x] 历史交易列表显示创建账号预备知识我们先来介绍第一个功能:通过生成助记词、Keystore文件、私钥创建钱包账号。本系列中,钱包都是指分层确定性钱包,(HD钱包 Hierarchical Deterministic Wallets), 之前博客有一篇文章分层钱包进行了详细的介绍,还不熟悉的可以读一下。为了保持本文的完整,这里做一个总结性回顾:以太坊及比特币的地址是由随机生成的私钥经过椭圆曲线等算法单向推倒而来 ,BIP32及BIP44是为方便管理私钥提出的分层推倒方案,BIP39 定义助记词让分层种子的备份更方便。而KeyStore文件是用来解密以太坊保存私钥的一种方式,大家可以阅读下这篇文章: 账号Keystore文件导入导出了解更多。实现完成的,界面如下图:这是一张导入钱包账号的截图(导入和创建,其实原理一样),界面仿照ImToken,不过本文将不会介绍UI部分的编写。Web3j & bitcoinj为了完成创建账号功能,我们需要使用到两个库:Web3j 和 bitcoinjWeb3是一套和以太坊通信的封装库,Web3j是Java版本的实现,例如发起交易和智能合约进行交互,下图很好的表达了其作用。不过本文中的功能,主要是使用了web3j中椭圆曲线加密及KeyStore文件的生成与解密。bitcoinj 的功能和web3类似,它是比特币协议的Java实现,他实现了 BIP32、BIP44及BIP39 相关协议。Android使用Gradle来构建,直接在app/build.gradle文件中加入:implementation ‘org.web3j:core:4.1.0-android’implementation ‘org.bitcoinj:bitcoinj-core:0.14.7’提示: 实践中遇到的一个问题,由于bitcoinj 中引入了 com.lambdaworks:scrypt加密库, 它包含的lib/x86_64/darwin/libscrypt.dylib文件,会导致在进行Android App Bundle 编译时会出现错误(好像也会导致某些机型没法安装),解决办法是在 build.gradle 加入一下语句,把这个文件在打包时排除掉。packagingOptions {exclude ’lib/x86_64/darwin/libscrypt.dylib’}创建账号实现通过助记词常见钱包账号这是目前钱包客户端,最常见的一种为用户常见账号的方式,这里会包含一下几个核心步骤:生成一个随机数种子;通过随机数种子得到助记词;通过 种子 + 路径 派生生成私钥;使用KeyStore保存私钥;私钥推倒出账号地址。大家可以在再次阅读分层钱包,理解为何这么做的原因。理解了上面几点,那么代码就容易明白了,代码在代码库中的app/src/pro/upchain/wallet/utils/ETHWalletUtils.java中,关键代码逻辑如下: // 创建钱包对象入口函数 public static ETHWallet generateMnemonic(String walletName, String pwd) { String[] pathArray = “m/44’/60’/0’/0/0”.split("/"); long creationTimeSeconds = System.currentTimeMillis() / 1000; SecureRandom secureRandom = SecureRandomUtils.secureRandom(); DeterministicSeed ds = new DeterministicSeed(secureRandom, 128, “”, creationTimeSeconds); return generateWalletByMnemonic(walletName, ds, pathArray, pwd); } /** * @param walletName 钱包名称 * @param ds 助记词加密种子 * @param pathArray 助记词标准 * @param pwd 密码 * @return */ @Nullable public static ETHWallet generateWalletByMnemonic(String walletName, DeterministicSeed ds, String[] pathArray, String pwd) { //种子 byte[] seedBytes = ds.getSeedBytes(); //助记词 List<String> mnemonic = ds.getMnemonicCode(); if (seedBytes == null) return null; // 衍生推倒key DeterministicKey dkKey = HDKeyDerivation.createMasterPrivateKey(seedBytes); for (int i = 1; i < pathArray.length; i++) { ChildNumber childNumber; if (pathArray[i].endsWith("’")) { int number = Integer.parseInt(pathArray[i].substring(0, pathArray[i].length() - 1)); childNumber = new ChildNumber(number, true); } else { int number = Integer.parseInt(pathArray[i]); childNumber = new ChildNumber(number, false); } dkKey = HDKeyDerivation.deriveChildKey(dkKey, childNumber); } ECKeyPair keyPair = ECKeyPair.create(dkKey.getPrivKeyBytes()); ETHWallet ethWallet = generateWallet(walletName, pwd, keyPair); if (ethWallet != null) { ethWallet.setMnemonic(convertMnemonicList(mnemonic)); } return ethWallet; } @Nullable private static ETHWallet generateWallet(String walletName, String pwd, ECKeyPair ecKeyPair) { WalletFile keyStoreFile; try { keyStoreFile = Wallet.create(pwd, ecKeyPair, 1024, 1); // WalletUtils. .generateNewWalletFile(); } catch (Exception e) { e.printStackTrace(); return null; } BigInteger publicKey = ecKeyPair.getPublicKey(); String s = publicKey.toString(); String wallet_dir = AppFilePath.Wallet_DIR; String keystorePath = “keystore_” + walletName + “.json”; File destination = new File(wallet_dir, “keystore_” + walletName + “.json”); //目录不存在则创建目录,创建不了则报错 if (!createParentDir(destination)) { return null; } try { objectMapper.writeValue(destination, keyStoreFile); } catch (IOException e) { e.printStackTrace(); return null; } ETHWallet ethWallet = new ETHWallet(); ethWallet.setName(walletName); ethWallet.setAddress(Keys.toChecksumAddress(keyStoreFile.getAddress())); ethWallet.setKeystorePath(destination.getAbsolutePath()); ethWallet.setPassword(Md5Utils.md5(pwd)); return ethWallet; }上述代码中,generateMnemonic()是入口函数,最终返回的是一个ETHWallet 自定义的钱包实体类,一个实例就对应一个钱包,ETHWallet保存了钱包相关的属性,后面会详细介绍,如果对它序列化保存钱包账号及多个钱包账号管理。几个注意事项关于助记词及私钥的保存,有几点要特别注意,否则有可能和其他钱包无法兼容或导致私钥泄漏。这部分作为订阅者福利,发表在我的小专栏,趁还未涨价,赶紧订阅吧,超值的!参考文档web3j API 文档bitcoinj 介绍及文档 加入知识星球,和一群优秀的区块链从业者一起学习。深入浅出区块链 - 系统学习区块链,打造最好的区块链技术博客。<!–几个注意事项创建钱包输入的密码,并不是用于生成种子,而是用来做keystore 加密的密码,这是业内的一个常规做法,尽管这个做法会降低一些安全性,但是不遵循行规,会导致和其他的钱包不兼容,及在其他钱包的助记词不能导入到我们钱包,或反之。keystore 文件应该存储在内部存储沙盒类,即应用程序自身目录内,保证其他程序无法读取内容,万万不可存取在外部存储中,如SD卡。商业产品,应该检查手机时候root,如果root,则第2点的安全性无法保证。–> ...

March 17, 2019 · 2 min · jiezi

Json-RPC操作Ethereum 节点

准备工作本地搭建以太坊私链,使用POA共识。节点开启IPC。功能描述试过一些rpc包和go-ethereum 的rpc包,都不是很好用。有些命令好使,有些就报错。没有去深究这些rpc包生成的json有什么异常。直接自己实现。实现其实很简单,而且用起来也更靠谱。上码package ethimport ( “bytes” “io/ioutil” “net/http”)type ethRequest struct { general Method string json:"method" Params []interface{} json:"params"}type general struct { JsonRPC string json:"jsonrpc" ID int json:"id"}//生成ethRequest,Marshal 成[]byte ,传入do函数即可操作ethereum 节点func do(jsonParam []byte)([]byte,error){ reader := bytes.NewReader(jsonParam) url := “http://127.0.0.1:8545” request, err := http.NewRequest(“POST”, url, reader) if err != nil { return []byte(""),err } request.Header.Set(“Content-Type”, “application/json;charset=UTF-8”) client := http.Client{} resp, err := client.Do(request) if err != nil { return []byte(""),err } respBytes, err := ioutil.ReadAll(resp.Body) if err != nil { return []byte(""),err } return respBytes,nil}其他说明了解更多以太坊管理命令所需要的参数。Here: https://github.com/ethereum/g… ...

March 11, 2019 · 1 min · jiezi

登链钱包(一款功能强大的以太坊钱包)完全开源

你是否和我前段时间一样,苦苦的寻找一款好用的开源以太坊钱包,你会发现可用都很少,因为很多钱包说开源,仅仅是开源部分代码,现在不需要再找了,登链钱包完全开源,登链钱包完全开源,登链钱包完全开源,重要的事情说三遍。再也不用傻乎乎找人开发以太坊钱包了, 直接拿去用吧;再也不用担心私钥会被上传到别人的服务器上。<!– more –>写在前面区块链是开放的,很难想象一个封闭的项目如何产生信任,开源一直是区块链社区所倡导的行为准则。我们也希望开源能够降低行业的开发门槛,吸引更多的开发者和公司能够利用我们的代码,找到更多落地的应用场景,一起来推动行业的发展。同时我们也相信开源可以是产品更加的安全,我们也邀请专业的区块链安全团队零时科技来为钱包做安全审计。效果演示先来看看钱包长什么样吧,我制作了一个gif图片:<p align=“center”> <img src=“https://wiki.learnblockchain….; width=“450”></p>Gif 图片比较简陋,见谅见谅,可以看的出来界面参考了现在的主流钱包,感谢imToken及ETHWallet,大家可以戳链接下载APK体验,Google play 也已经上架,正在审核中。功能介绍目前版本支持一下功能:[x] 支持通过生成助记词、Keystore文件、私钥 创建钱包账号;[x] 支持导出钱包账号助记词、私钥、Keystore文件;[x] 账户余额查询及转账功能;[x] 支持多个钱包账号管理;[x] 支持ERC20 代币(余额显示、转账、代币币价显示);[x] 历史交易列表显示;[x] 二维码扫描,兼容imToken格式;[x] 支持用法币(美元和人民币)实时显示币价;[x] 支持以太坊官方测试网络(Infura Koven及Ropsten)及本地测试网络。功能够全面吧,尤其是最后一个功能支持以太坊官方测试网络(Infura Koven及Ropsten)及本地测试网络,估计是开发者的最爱,做为开发者的我,懂你们的痛(可以获取到免费的以太币用于测试)。代码的讲解和相应的课程,我们后面会陆续放出,在还没有放出之前,先提醒大家几个注意的点:使用本地网络测试的时候注意Geth 或 Ganache 设置下可接收RPC连接的地址,因为默认情况下只支持本地连接,这样手机上就无法连接。显示交易记录功能需要自己搭建一个服务器提供API接口,这个接口来自TrustWallet,为了和本应用保持版本一致,我Fork了一份,地址为trust-ray,这个库会解析区块,并把交易信息存到MongoDb数据库里,然后用API提供给客户端使用。实时币价的显示其实也是使用trust-ray提供的接口,trust-ray 使用的是CoinMarketCap的数据,目前使用的是CoinMarketCap免费提供的数据,CoinMarketCap现在有一套新的付费接口,免费的数据可能在将来会停用,到时需要使用CoinMarketCap 的apikey来访问。代码中ERC20_Contract目录提供了一个ERC20合约给大家部署测试Token功能。其他的代码介绍及环境搭建大家就只有等我的文章了,大家也可以学习网页钱包开发课程,课程详细介绍了开发钱包必备的理论知识。有什么需要的功能,可以提issue或加我微信留言。对了本项目的GitHub地址为:Upchain-wallet, 点 Star 的同学都会发大财,哈哈哈~~~参考的开源项目本钱包在开发是站在巨人的肩膀上完成,特别感谢以下项目:web3jbitcoinjTrust-walletETHWalletBGAQRCodeTrust-ray## 再啰嗦几句本次开源也是受到区块链社区的影响,尤其是HiBlock区块链社区一些朋友坚持布道和开源的精神影响。HiBlock区块链社区 是国内最大的区块链开发者社区,社区已经聚集了数千名区块链开发者。登链钱包是由登链学院出品,希望大家知道登链学院不单出品优质课程,我们也为行业发展贡献一份力量,感谢大家转发。PS: 我们提供专业的钱包定制开发,欢迎咨询微信:xlbxiong深入浅出区块链 - 系统学习区块链,打造最好的区块链技术博客。

March 10, 2019 · 1 min · jiezi

案例-以太坊短地址攻击

这种攻击方式的结果就是:让你瞬间由n个token变为n*256个token,穷屌丝变高富帅只需几分钟攻击原理:在ERC20代币标准中,有一个标准化的transfer函数function transfer(address _to, uint256 _value) returns (bool success)当我们真正调用transfer的时候,在EVM里实际上是在解析一堆ABI字符,ABI相关定义在这。比如我们这样调用transfertransfer(0xef181375f0d6d0b161134b6a0429f5f5016a41fa,200)那实际EVM看到的东西就是这样的0xa9059cbb000000000000000000000000ef181375f0d6d0b161134b6a0429f5f5016a41fa000000000000000000000000000000000000000000000000000001d1a94a2000排一下版的话就是这样前面4字节是方法名的hash中间32字节是address _to(转账的目标地址),高位补0末尾32字节是uint256 _value(转账金额),高位补0,低位16进制存储可以通过etherscan查看这笔交易,我临时截下来的。短地址攻击你也看到了,在transfer的ABI里,金额在目标地址的后面,并且是紧贴着的。机遇就在这里!假如我们有一个如下地址0x1234567890123456789012345678901234567800如果我们把末尾的两个零去掉会发生什么??EVM依然会认为address _to是32位的,所以它会从_value的高位取0来补充。这意味着_value就少了一位!傻傻的EVM则会补上一个零来处理_value。所以你转账金额就翻了256倍那如果目标地址的末尾有多个零呢??!!攻击流程(1)生成一个末尾有零的地址,末尾的零越多越好(零太多的话小心交易所资金不足)(2)找到一个大交易所,确定其打币地址上有足够的资金,用虚假身份注册账号(3)向交易所充erc20币1个(4)从交易所提币到末尾有零的地址,填写地址的时候故意把末尾的零去掉(5)数钱(6)等待交易所工作人员打你电话,如果你用虚假身份注册,请忽略这点(7)等待交易所请你喝茶,喝茶时你悠闲的回复防御手段(1)交易所层面:检测用户输入地址位数是否合规(2)以太坊层面:节点发送交易前,校验函数参数位数是否合规(3)token合约层面:对transfer函数,检查len(msg.data) == 68,对其他函数同理欢迎订阅「K叔区块链」 - 专注于区块链技术学习 博客地址:http://www.jouypub.com简书主页:https://www.jianshu.com/u/756c9c8ae984segmentfault主页:https://segmentfault.com/blog/jouypub腾讯云主页:https://cloud.tencent.com/developer/column/72548

March 4, 2019 · 1 min · jiezi

Ethereum地址是如何生成的

来自简书btc address: 1FmWXNJT3jVKaHBQs2gAs6PLGVWx1zPPHfeth address: 0xd91c747b4a76B8013Aa336Cbc52FD95a7a9BD3D9以太坊生成地址的方式跟比特币比较类似,也是 私钥 -> 公钥 -> 地址,以太坊只是在公钥 -> 地址做了简化。以太坊使用Secp256k1椭圆曲线得到私钥、公钥,比特币使用的也是相同的椭圆曲线算法。得到公钥后,对公钥做Keccak-256哈希运算,然后取最后的40位16进制字符,得到的就是以太坊地址。生成以太坊地址跟比特币地址都是不需要连接网络的python code 生成以太坊地址python首先安装类库pip install ecdsapip install pysha3import binasciiimport sha3from ecdsa import SigningKey, SECP256k1priv = SigningKey.generate(curve=SECP256k1) #生成私钥pub = priv.get_verifying_key() #生成公钥keccak = sha3.keccak_256()keccak.update( pub.to_string()) #keccak_256哈希运算address = “0x” + keccak.hexdigest()[24:]priv_key = binascii.hexlify( priv.to_string())pub_key = binascii.hexlify( pub.to_string())print(“Private key: " + priv_key.decode() )print(“Public key: " + pub_key.decode() )print(“Address: " + address)# Address: 0xd38d3c226d0a86ce9932608edac39163fcbc550e来个骚操作,用同一份私钥来管理比特币与以太坊既然以太坊使用Secp256k1椭圆曲线得到私钥、公钥,比特币使用的也是相同的椭圆曲线算法。那我们就用 Bitcoin地址是如何生成的得到的公钥04d061e9c5891f579fd548cfd22ff29f5c642714cc7e7a9215f0071ef5a5723f691757b28e31be71f09f24673eed52348e58d53bcfd26f4d96ec6bf1489eab429d,生成一个以太坊地址。这个公钥是通过openSSL得到的未压缩公钥,以太坊不需要使用这种类型的公钥,只要把首位的04去掉即可。import sha3import binascii_openssl_pub_key= “04d061e9c5891f579fd548cfd22ff29f5c642714cc7e7a9215f0071ef5a5723f691757b28e31be71f09f24673eed52348e58d53bcfd26f4d96ec6bf1489eab429d”_pub_key = _openssl_pub_key[2:]_pub_hex = binascii.unhexlify(_pub_key)keccak = sha3.keccak_256()keccak.update(_pub_hex)address = “0x” + keccak.hexdigest()[24:]print address #0x9156a7cdab767ffe161ed21a0cb0b688b545b01f这说明啥?我用完全相同的私钥,分别生成了比特币地址与以太坊地址,这两个完全不一样的地址用的是同一个私钥。以太坊地址 0x9156a7cdab767ffe161ed21a0cb0b688b545b01f与比特币地址 14xfJr1DArtYR156XBs28FoYk6sQqirT2s的私钥竟然是相同的。这给资产管理带来了很大方便,但如果一份私钥泄露了,2份资产都有可能被盗。 管理一时爽,泄露全都火葬场。参考:http://blog.luoyuanhang.com/2…https://www.jianshu.com/p/efc...https://www.bilibili.com/vide...https://zhuanlan.zhihu.com/p/...https://www.myetherwallet.com/ ...

March 1, 2019 · 1 min · jiezi

以太坊开发者工具的最新清单

以太坊开发者工具的最新终极清单,用于在以太坊上开发应用程序的可用工具,组件,框架和平台的指南。对于任何开发者,无论你是一个睁大眼睛的Web3新手还是一个头发灰白的OG加密无政府主义技术霸主,Github都是你的朋友。特别是ConsenSys Github可能是你在整个互联网上找到的最明确的Ethereum开发工具库。无论是基础知识,编码语言,IDE,API,ABI,框架,最佳实践,智能合约标准,测试工具还是faucets,ConsenSys Github都能满足你现在开始在以太坊区块链上构建去中心化应用所需的一切。ConsenSys的产品经理推动了这个清单的创建,他们认为需要在新的和经验丰富的区块链开发人员之间更好地共享工具,开发模式和组件。新开发者从这里开始!Solidity:最流行的智能合约语言。Truffle:最流行的智能合约开发,测试和部署框架。通过NPM安装CLI,然后从这里开始编写你的第一份智能合约。Metamask:与Dapps交互的Chrome扩展钱包。Truffle boxes:以太坊生态系统的包装组件。EthHub.io:以太坊的全面概述,包括其历史,治理,未来计划和开发资源。Infura:可扩展,安全,可靠地访问以太坊网络。开发工具/tool智能合约开发工具/tool智能合约语言/languageSolidity:以太坊智能合约语言。Bamboo:一种变形的智能合约语言。Vyper:新的实验性pythonic编程语言。LLL:低级Lisp语言。Flint:正在开发的新语言,具有安全功能,包括资产类型,状态转换和安全整数。框架/FrameworksTruffle:最受欢迎的智能合约开发,测试和部署框架。Truffle套件包括Truffle, Ganache, and Drizzle. 深入了解TruffleEmbark:DApp开发框架。Waffle:高级智能合约开发和测试框架,小巧,灵活,快速(基于ethers.js)。Dapp:DApp开发框架,DApple的继任者。Populus:以太坊开发框架中最可爱的动物图片。Etherlime:基于ethers.js的Dapp部署框架。Parasol:敏捷智能合约开发环境,包括测试,INFURA部署,自动合约文档等。它具有灵活和不受欢迎的设计,可无限制地定制。0xcert:用于构建去中心化应用程序的JavaScript框架。IDEsRemix:内置静态分析的Web IDE,测试区块链VM。Superblocks Lab:内置浏览器blochain VM,Metamask集成(一键部署到Testnet/Mainnet),交易记录器和实时代码WebApp以及许多其他功能。Atom:使用Atom编辑器Atom Solidity Linter,Etheratom,autocomplete-solidity,和language-solidity包。Pragma:非常简单的Web IDE,用于实现solidity,以及自动生成的智能合约接口。Vim solidity:Vim solidity 语法文件。Visual Studio Code:Visual Studio Code扩展,增加了对Solidity的支持。Intellij Solidity Plugin:开源插件JetBrains IntelliJ Idea IDE (free/commercial)语法高亮,格式化,代码完成等。YAKINDU Solidity Tools:基于Eclipse的IDE。具有上下文敏感的代码完成和帮助,代码导航,语法着色,内置编译器,快速修复和模板。Eth Fiddle:由The Loom Network开发的IDE,允许你编写,编译和调试智能合约。易于共享和查找代码段。测试区块链网络/TestGanache:用于测试以太坊区块链的应用程序,带有可视UI和日志。Kaleido:使用Kaleido打造财团区块链网络。非常适合PoC和测试。Pantheon Private Network:在Docker容器中运行Pantheon节点的专用网络。Orion:PegaSys执行私人交易的组件。Artemis:PegaSys的以太坊2.0信标链的Java实现。Cliquebait:使用非常类似于实际区块链网络的docker实例简化集成并接受智能合约应用程序的测试。Local Raiden:在Docker容器中运行本地Raiden网络,以进行演示和测试。Private networks deployment scripts:私有PoA网络的即插即用部署脚本。Local Ethereum Network:私有PoW网络的即插即用部署脚本。Ethereum on Azure:联盟链的部署和治理以太网PoA网络。getho:DApp开发平台,包括PoA私有区块链和智能合约测试工具。Ethereum on Google Cloud:基于PoW构建以太坊网络。Test Ether faucetsRinkeby faucetKovan faucetRopsten faucetUniversal faucetNethereum.Faucet:一个 C#/.NET faucet。以太坊的交互/Communicating以太坊前端APIs/FrontendWeb3.js:Javascript Web3Eth.js:Javascript Web3替代方案。Ethers.js:Javascript Web3替代,有用的实用程序和钱包功能。Web3Wrapper:Typescript Web3替代方案。Ethereumjs:以太坊的实用函数集合如ethereumjs-util和ethereumjs-tx。flex-contract和flex-ether现代零配置的用于与智能合约交互和进行交易的高级别库。ez-ens简单的零配置以太坊名称服务地址解析器。web3x:web3.js的TypeScript端口。优势包括包括与合约交互时微服务构建和完整类型安全。Nethereum:跨平台的以太坊开发框架。Drizzle:使用Redux库将前端连接到区块链。Tasit SDK:一个JavaScript SDK,用于使用React Native制作原生移动端的以太坊dapps。Subproviders:与Web3-provider-engine 结合使用的几个有用的子提供程序,包括用于为你的dApp添加Ledger硬件钱包支持的LedgerSubprovider。web3-react:用于构建单页以太坊dApp的React框架。Vortex:一个Dapp-ready Redux Store。借助WebSockets,智能和动态后台数据刷新。Truffle和Embark。其他Javascript替代品elm-ethereumpurescript-web3以太坊后端APIs/BackendWeb3.py:Python Web3Web3.php:PHP Web3Ethereum-php:PHP Web3Web3j:Java Web3Nethereum:.Net Web3Ethereum.rb:Ruby Web3Web3.hs:Haskell Web3KEthereum:Kotlin Web3Pyethereum:以太坊项目的Python核心库。Eventeum:以太坊智能合约事件和后端微服务之间的桥梁,由Kauri用Java编写。Ethereumex:Ethereum区块链的Elixir JSON-RPC客户端。EthContract:帮助查询Elixir中的ETH智能合约的一组帮助方法。Bootstrap/out of box toolsTruffle boxes:以太坊生态系统的打包组件。Pantheon Private Network:在Docker容器中运行Pantheon节点的专用网络。Testchains:预配置的.NET devchains,用于快速响应(PoA)。Blazor/Blockchain Explorer:Wasm区块链资源管理器(功能样本)。Local Raiden:在Docker容器中运行本地Raiden网络,以进行演示和测试。Private networks deployment scripts:私有PoA网络的即插即用部署脚本。Parity Demo-PoA Tutorial:构建具有2个节点的PoA测试链的分步教程,具有奇偶校验授权共识。Local Ethereum Network:私有PoW网络的即插即用部署脚本。Kaleido:使用Kaleido打造财团区块链网络。非常适合PoC和测试。Cheshire:CryptoKitties API和智能合约的本地沙箱实现,可作为Truffle Box使用。Aragon CLI:Aragon CLI用于创建和开发Aragon应用程序。ColonyJS:JavaScript客户端,提供用于与Colony Network智能合约交互的API。ArcJS:便于javascript应用程序访问DAOstack Arc以太坊智能合约的库。Ethereum ABI (Application Binary Interface) toolsABI decoder:用于解码以太坊交易中的数据参数和事件的库。ABI-gen:从合约ABI生成Typescript合约包装。Ethereum ABI UI:从以太坊合约ABI自动生成UI表单字段定义和相关验证器。headlong:Java中的类型安全合约ABI和递归长度前缀库。One Click dApp:使用ABI在唯一的URL上即时创建dApp。Truffle Pig:一种开发工具,提供简单的HTTP API,用于查找和读取Truffle生成的合约文件,以便在本地开发期间使用。通过http提供新合约ABI。模式和最佳实践/Patterns & Best Practices智能合约开发的模式/Patterns for Smart Contract DevelopmentDappsys: 安全,简单,灵活的以太坊合约构建模块有解决以太坊/ Solidity常见问题的方法,例如, eg.白名单/Whitelisting可升级/Upgradable ERC20-TokenERC20-Token-Vault认证/Authentication (RBAC)…several more…为MakerDAO或The TAO提供构建模块。在创建自己未经测试的解决方案之前,应该咨询。 - 使用情况见Dapp-a-day 1-10和Dapp-a-day 11-25OpenZeppelin: Solidity语言中可重用且安全的智能合约的开放框架。可能是最广泛使用的库和智能合约。与Dappsys类似,更多地集成到Truffle框架中。关于安全审计的最佳实践的博客Advanced Workshop with AssemblySimpler Ethereum Multisig:特别是Benefits。CryptoFin Solidity Auditing Checklist:常见审查结果清单,以及审核主网启动合约时需要注意的问题。aragonOS: 构建DAO,Dapps和协议的智能合约框架易读性:智能合约可以升级到更新版本。权限控制:通过使用auth和authP修饰符,你可以保护功能,只有其他应用程序或实体才能访问它。转发器:aragonOS应用程序可以将其意图发送给其他应用程序,以便在满足一系列要求时转发意图。可升级性/UpgradebilityBlog von Elena Dimitrova, Dev at colony.iohttps://blog.colony.io/writin…https://blog.colony.io/writin...Researchblog von Aragon驱动库开发高级solidity开发OpenZeppelin代理库基础设施/Infrastructure客户端/Ethereum ClientsPantheon:PegaSys的Java客户端。Geth:Go客户端。Parity:Rust客户端。Aleth:C++客户端。Pyethapp:使用pyethereum的Python客户端。Trinity:使用py-evm的Python客户端。Ethereumjs:使用ethereumjs-vm的JS客户端。Ethereumj:以太坊基金会的Java客户端。Harmony:EtherCamp的Java客户端。Seth:Seth是一个以太坊客户端工具,就像命令行的MetaMask。Mustekala:Metamask的以太坊轻客户端项目。Exthereum:Elixir客户端。EWF Parity:Tobalaba测试网络的Energy Web Foundation客户端。Quorum:JP Morgan支持的允许实施以太坊支持数据隐私。Mana:用Elixir编写的以太坊全节点实现。存储/StorageIPFS:去中心化存储和文件引用。IPFS-Store:具有附加搜索功能的IPFS存储服务。OrbitDB:IPFS之上的去中心化数据库。JS IPFS API:IPFS HTTP API的客户端库,用JavaScript实现。TEMPORAL:易于使用的API到IPFS和其他分布式/去中心化存储协议。Swarm:分布式存储平台和内容分发服务,以太坊web3堆栈的本机基础层服务。消息传递/MessagingWhisper:DApps相互通信的通信协议,是以太坊web3堆栈的本机基础层服务。DEVp2p Wire Protocol:运行以太坊/Whisper的节点之间的对等通信。Pydevp2p:RLPx网络层的Python实现。测试工具/Testing ToolsSolidity code coverage:Solidity代码覆盖率工具。Solidity coverage:Solidity智能合约的替代代码覆盖范围。Solidity function profiler:Solidity智能合约分析器。Sol-profiler:备选和更新的Solidity智能合约分析器。Espresso:快速,并行化,热重载solidity测试框架。Eth tester:用于测试以太坊应用程序的工具套件。Cliquebait:使用非常类似于实际区块链网络的docker实例简化集成并接受智能合约应用程序的测试。Hevm:hevm项目是以太坊虚拟机(EVM)的一个实现,专门用于单元测试和调试智能合约。Ethereum graph debugger:Solidity图形调试器。Tenderly CLI:利用人类可读的堆栈跟踪加速你的开发。Solhint:为智能合约验证提供安全性,样式指南和最佳实践规则。Ethlint:用于识别和修复Solidity(以前称Solium)中的样式和安全问题的Linter。Decode:npm包解析提交给本地testrpc节点的tx,使其更易读,更易理解。truffle-assertions:一个带有额外断言和实用程序的npm包,用于测试与松露的Solidity智能合约。最重要的是,它增加了断言特定事件是否已经发出的能力。Psol:具有mustache.js样式语法,宏,条件编译和自动远程依赖包含的Solidity词法预处理器。solpp:Solidity预处理器和flattener,具有全面的指令和表达式语言,高精度数学和许多有用的辅助函数。Decode and Publish:解码并发布原始以太坊tx,https://live.blockcypher.com/…Doppelgänger:用于在单元测试期间模拟智能合约依赖关系的库。rocketh:一个简单的lib来测试以太坊智能合约,允许使用你选择的任何web3 lib和测试运行器。安全工具/Security ToolsMythX:以太坊开发人员的安全验证平台和工具生态系统。Mythril Classic:开源EVM字节码安全分析工具。Oyente:替代静态智能合约安全性分析。Securify:以太坊智能合约的安全扫描程序。SmartCheck:静态智能合约安全分析器。Porosity:基于区块链的以太坊智能合约的反编译器和安全分析工具。Ethersplay:EVM反汇编程序。Evmdis:替代EVM反汇编程序。Hydra:加密经济合约安全框架,去中心化安全奖励。Solgraph:可视化智能合约安全性分析的Solidity控制流程。Manticore:智能合约和二进制文件的符号执行工具。Slither:一个Solidity静态分析框架。Adelaide:Solidity编译器的SECBIT静态分析扩展。Solidity security blog:已知攻击向量和常见反模式的综合列表。Awesome Buggy ERC20 Tokens:ERC20与Token智能合约中的漏洞集合。Free Smart Contract Security Audit:来自Callisto Network的免费智能合约安全审计。监控/MonitoringNeufund - Smart Contract Watch:一种监控大量智能合约和交易的工具。Scout:以太坊上智能合约的活动和事件日志的实时数据Feed。Chainlyt:使用已解码的交易数据探索智能合约,查看合约的使用方式以及使用特定函数调用搜索交易。其他工具/Other Miscellaneous ToolsTruffle boxes:用于快速构建DApps的打包组件。Cheshire:CryptoKitties API和智能合约的本地沙箱实现,可作为Truffle Box使用。Solc:Solidity编译器。Sol-compiler:项目级Solidity编译器。Solidity cli:更快,更简单,更可靠地编译solidity代码。Solidity flattener:将solidity项目与平面文件实用程序相结合。用于可视化导入的合约或验证你在Etherscan上的合约。Sol-merger:替代方案,将所有导入合并为单个文件以获得可靠性合约。RLP:JavaScript中的递归长度前缀编码。eth-cli:一系列用于帮助以太坊学习和开发的CLI工具。Ethereal:Ethereal是一个命令行工具,用于管理以太坊中的常见任务。Eth crypto:用于以太坊的加密javascript函数以及将它们与web3js和solidity一起使用的教程。Parity Signer:移动应用程序允许签署交易。py-eth:为以太坊生态系统收集Python工具。truffle-flattener:在Truffle下开发的Concats solidity文件及其所有依赖项。Decode:npm包解析提交给本地testrpc节点的tx,使其更易读,更易理解。TypeChain:以太坊智能合约的Typescript绑定。EthSum:一个简单的以太坊地址校验和工具。PHP based Blockchain indexer:允许索引块或在PHP中监听事件。Purser:基于以太坊的钱包的JavaScript通用钱包工具。支持软件,硬件和Metamask,将所有钱包都集成到dApp开发的一致且可预测的界面中。Node-Metamask:从node.js连接到MetaMask。Solidity-docgen:Solidity项目的文档生成器。Ethereum ETL:将以太坊区块链数据导出为CSV或JSON文件。prettier-plugin-solidity:用于格式化Solness代码的更漂亮的插件。EthToolbox:一款为以太坊开发人员提供离线工具的网络应用程序。 EC恢复,地址格式化程序,单位转换器,哈希函数,密钥生成器等。Unity3dSimpleSample:以太坊和Unity集成演示。Flappy:以太坊和Unity集成演示/示例。Wonka:Nethereum业务规则引擎演示/示例。智能合约标准库/Smart Contract Standards & LibrariesERCs:Ethereum Request for Comment资料库TokensERC-20:可互换资产的原始通证合约。ERC-721:非可替换资产的通证标准。ERC-918:可采用通证标准。ERC-165:创建一个标准方法来发布和检测智能合约实现的接口。ERC-725:密钥管理和执行的代理合约,用于建立区块链标识。ERC-173:合约所有权的标准接口。热门智能合约库/Popular Smart Contract LibrariesZeppelin:包含经过测试的可重用智能合约SafeMath和ZeppelinOS library可升级智能合约。cryptofin-solidity:一系列Solidity库,用于在以太坊上构建安全,高效的智能合约。Modular Libraries:一组使用以太坊虚拟机在区块链上使用的软件包。DateTime Library:一个节气的Solidity日期和时间库。Aragon:DAO协议。包含aragonOS smart contract framework重点关注可升级性和治理。ARC:DAO的操作系统和DAO堆栈的基础层。0x:DEX protocolToken Libraries with Proofs:包含通证合约的正确性证明。给定规格和高级属性。第二层基础架构的开发人员指南/Developer Guides for 2nd Layer Infrastructure可伸缩性/Scalability支付和状态 / Payment/State ChannelsEthereum Payment Channel:以太网支付通道50行代码。µRaiden Documentation:µRaiden发送者/接收者用例的指南和样本。PlasmaLearn Plasma:网站作为节点应用程序,开始于康奈尔大学2018年IC3-Ethereum Crypto训练营,涵盖所有Plasma variants (MVP/Cash/Debit)。Plasma MVP:OmiseGO对最小可行Plasma的研究实施。Plasma MVP Golang:Golang实现和最小可行Plasma规范的扩展。Plasma Cash:简单的Plasma现金实施。侧链/Side-ChainsPOA NetworkPOA BridgePOA Bridge UIPOA Bridge ContractsLoom Network隐私Privacy / 保密ConfidentialityzkSNARKsZoKrates:以太坊上的zkSNARKS工具箱。The AZTEC Protocol:以太坊网络上的机密交易,在以太坊主网上实施。预编译UI组件/Prebuilt UI Componentsui.aragon.org:包含Dapp组件的React库。components.bounties.network:包含Dapp组件的React库。lorikeet.design:包含Dapp组件的React库。ui.decentraland.org:包含Dapp组件的React库。dapparatus:可重复使用的React Dapp组件。Metamask ui:Metamask React组件。DappHybrid:基于Web的去中心化应用程序的跨平台混合托管机制。Nethereum.UI.Desktop:跨平台桌面钱包示例。======================================================================分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。ERC721以太坊通证实战,课程以一个数字艺术品创作与分享DApp的实战开发为主线,深入讲解以太坊非同质化通证的概念、标准与开发方案。内容包含ERC-721标准的自主实现,讲解OpenZeppelin合约代码库二次开发,实战项目采用Truffle,IPFS,实现了通证以及去中心化的通证交易所。C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。汇智网原创翻译,转载请标明出处。这里是以太坊开发者工具的最新清单 ...

February 25, 2019 · 2 min · jiezi

ERC721以太坊通证实战教程

本课程以一个数字艺术品创作与分享DApp的实战开发为主线,深入讲解以太坊非同质化通证的概念、标准与开发方案。课程内容即包含ERC-721标准的自主实现,也讲解如何基于经过良好安全审计的OpenZeppelin合约代码库进行二次开发,实战项目采用Truffle开发框架,使用IPFS保存通证元数据,同时实现了通证以及去中心化的通证交易所。课程内容深入浅出,是开发者学习以太坊ERC721通证应用开发的最佳选择。这里是学习地址:《ERC721以太坊通证实战》简介在这个课程里,我们将通过深入一个类似于加密猫(CryptoKitties)的 去中心化数字艺术品创作与分享应用的开发过程,学习非同质化通证(NFT:Non-Fungible Token)的基本概念、应用场景与开发实施方案:和加密猫一样,我们的课程应用中的每个数字资产都是独一无二的,事实上, 它们就是使用不同参数生成的形状各异的随机图(Random Graphp),可以认为每个随机图的唯一性赋予它收藏的价值,因此我们可以将其视为一种艺术品。在这个课程中,我们将学习如何生成随机图艺术品并将这一数字资产通证化。每个人都可以有自己的方法将数字资产通证化,不过以太坊已经有了针对非同质化通证的标准:ERC-721。在课程中,我们将完整地讲解ERC-721标准的方方面面,不仅从头实现一个ERC-721兼容的通证合约,同时也会讲解如何利用经过安全审计的OpenZeppelin合约代码库进行二次开发。一旦将资产通证化以后,就可以进行交换。在课程中我们还将实现一个简单的通证交易所,每个人都可以在交易所购买其他人的NFT通证,也可以挂单出售自己的通证:项目技术栈由于这是一个中级课程,因此需要你对区块链/以太坊以及下面的技术 有一些基本的了解和认识,这样会更有利于课程以及课程项目的完成:项目应用的开发主要包含两部分:智能合约的开发以及前端UI的开发。课程项目使用solidity(版本0.5)来开发以太坊智能合约,并对涉及到的solidity新特性进行说明。前端用户界面的开发则使用标准的前端五件套:HTML、CSS、JavaScript、jQuery、Bootstrap,当然,也需要 使用web3.js(版本1)来访问区块链。为了便于DApp项目的开发和管理,课程使用truffle(版本2)框架进行开发,truffle2预置的solidity编译器支持solidity0.5。除了可以继续采用ganache-cli作为开发节点以外,truffle 2还包含了一个嵌入 的以太坊开发节点,这使得开发流程更加顺畅。truffle框架提供了许多模板用于项目的快速开发,这些项目模板被称为box。为了充分利用ES2015的新特性来使课程代码更加容易阅读,我们使用webpack模板。在truffle 2中的webpack模板是基于webpack 4实现。最后,课程项目使用去中心化文件系统IPFS来保存通证的元信息。课程内容安排本课程是一个中级课程,适合具备一定以太坊开发基础的区块链工程师,课程内容安排如下:第一章、课程简介介绍课程要完成的项目,以及项目实现所使用的技术栈。第二章、通证简明指南学习通证的基本概念、分类、应用场景与生成机制。第三章、项目需求分析与设计理解课程项目的总体需求,学习项目应用的设计思路,包括模块划分、 界面原型与合约接口设计等。第四章、生成随机图艺术品了解随机图的基本概念与常用算法,掌握生成随机图的实现方法。第五章、使用IPFS保存随机图艺术品学习IPFS的基本概念、部署与使用方法,掌握将随机图上传到IPFS网络的实现方法。第六章、理解ERC721规范学习ERC721规范中涉及的各种接口,例如ERC721接口、ERC165接口等, 掌握各接口的关系与实现方法。第七章、随机图通证合约实现学习并掌握如何使用OpenZepplin合约开发库实现随机图通证合约。第八章、应用前端实现学习如何在前端页面中调用合约方法,实现随机图通证生成页面和浏览页面。第九章、实现简单的通证交易所学习交易所的基本概念,实现通证交易所合约,前端页面增加对交易所功能 的支持。有关兴趣的同学欢迎到这里是学习:《ERC721以太坊通证实战》

February 22, 2019 · 1 min · jiezi

第12期 DApp 榜单 : “吸睛”+“吸金”的小游戏

作者:DD君欢迎添加作者微信 btcbtc555 与他进行交流!未经授权禁止转载!截止到今天为止,以太坊上DApp数量合计为1,336,EOS上DApp数量合计为349,波场上DApp数量合计为173,三大公链中竞猜类DAPP均居龙头位置。目前宏观经济形势不稳定已成为绝大多数人的共识,春节期间年年爆火的返乡置业潮相较于往年都有所降温,DApp在节期间的表现不尽人意也可以理解。一方面来自用户群体注意力的转移,另一方面则是由于用户现金流的缺失。整个虚拟货币市场是个联动的生态系统,春节期间一直处在盘整阶段的各个主流币种,今天以太坊率先领跑,比特币柚子等也有小幅上涨,不知道此波行情能否也为DAPP带来一些关注度。以下进入今天的榜单。ETH榜单相较于EOS在春节期间的用户数流失,ETH的交易人数却有所增加。但我们发现1812个以太坊DApps中只有180个与ERC-20交易相关联,通过简单的算数得知,这大约相当于10%,大量的以太DAPP已经处于死亡状态。加拿大加密货币研究者和行业评论员Kevin Rooke的言论也巩固了以太坊应用程序缺乏活动的事实。这样来看春节期间以太坊交易人数的激增,可能又是某些项目方自导自演的戏码。EOS榜单可以注意到EOS榜单在春节期间有很大的波动变化,除了雷打不动的PRA CandyBox、EOS Knights依旧霸榜之外,其余名次皆有较大变化,且竞猜类DAPP占据主要名额。游戏BIG.GAME早在去年九月份就已经推出,表现一直不温不火,但近日的用户数增长堪称飞速。相较而言每日成交量的增速远远低于用户数,我们有理由怀疑该团队通过刷用户量的方式提升自己的Dapp排名,以获得更高的曝光度。TRON榜单本周波场前三名依旧为节前前三,而后半部分的变动较大。波场的DApp的爆发时间远晚于EOS,从去年12月份才进入爆发期,1月步入红利期,目前每天仍有新的波场DAPP推出。由于波场主要用户都集中在海外,所以整个春节期间,其交易量并没有太大的下滑幅度。观点分析春节假期明显可以感觉到Dapp圈内迅速冷却,不知道的人还以为是Dapp要凉了。原因篇首已提,此处便不再赘述,目前三大公链的数据已经基本回暖。缺乏新用户入场是目前所有DAPP遭遇的普遍难题。我们DAPPDiscover团队已经不止一次提到过,只有出现一些新的好玩的游戏,才有吸引新用户的可能性。春节期间一款名为Celex的五子棋游戏就引起了我们团队的关注,大家可以感受一下游戏界面。界面简洁,使用流畅,没有繁杂的注册钱包步骤,是DD君体验该游戏的直观感受。也许有读者疑问:“这个游戏这么常见,有必要放在单独拎出来讲吗?”有!!!原因有两点:其一,从游戏层面上,该五子棋属于小游戏,能有效吸引更多的用户群体。我们可以对比微信的小游戏“跳一跳”。2017年12月28日下午,微信小游戏“跳一跳”正式上线,一经推出,微信指数几乎直线上升超过2亿,2018年春节期间同时在线人数最高2800万/小时。抛开微信的熟人生态和满足用户相互攀比分数高低的原因外,小游戏耗时少难度低,用户的碎片化时间可以得到更有效占用,从而能获得更多的用户群体。其二,结合DAPP的通性,包括上面我们提到的Celex,本质依旧是“游戏即挖矿”。以该游戏为例,这款游戏主要通过与人实时PK五子棋来确定输赢,筹码就是GT(该游戏代币)。该游戏还含有邀请好友奖励等等,由于该游戏还处于测试阶段,后续有可能会上线更多的玩法,但本质估计仍差不多。小游戏带来更多用户,区块链又给该小游戏赋予了金融属性,“吸睛”+“吸金”,你不心动吗?你有哪些感兴趣的DApp?欢迎留言回复下一次讨论的,也许就是它。

February 19, 2019 · 1 min · jiezi

DAppDiscover | 盘点2018年度十大DAPP

作者:DD君欢迎添加作者微信 btcbtc555 与他进行交流!未经授权禁止转载!2018年可以说是DApp爆发的元年,这一年出现了好几款现象级DApp。有曾经让以太坊严重拥堵的CryptoKitties(加密猫),有史上最大的资金盘游戏Fomo 3D,还有区块链房地产EOS Pixel Master(像素大师)——一个像素最高价达到了4483.87EOS(折合人民币17万多)!当然,除了资金盘游戏之外,也出现了像EOS Knights、加密英雄这样,制作精良、质量上成、高可玩性的区块链游戏。DAppDiscover团队从2000多个DApp中筛选出了2018年度十大DApp,综合考虑了它们的影响力、可玩性和游戏设计三个方面,一起来看一看吧!10. 波场虾农影响力:3.5分可玩性:3.5分游戏设计:3.0分平台 :TRON发布时间 :2018-12-14网址:https://tronshrimp.farm/波场虾农属于养殖类游戏。逻辑就是买蛋,孵蛋,生蛋,卖蛋。“蛋"可以无限孵化,但相应价格会越来越低。这是波场第一款爆款游戏,上线后一举创下波场 DAPP 日活记录,达到 3 万 DAU。但此款游戏严重抄袭游戏以太虾农,二者连UI都相差无几。9.PoWH 3D影响力:3.5分可玩性:3.5分游戏设计:3.5分平台 :ETH发布时间 :2018-02-26网址 :https://powh.io/PoWH 3D同样属于资金盘类游戏。玩这个游戏须先购买虚拟代币,购买代币需要交10%手续费。持有虚拟代币后,会收到分红,这个分红比例则根据游戏每日产生的收益,按照你持有代币的量分配。该游戏利用新玩家的钱来向老玩家支付利息和短期回报,以制造赚钱的假象,进而骗取更多的玩家入场,属于典型的庞氏骗局游戏。8. CryptoCountries影响力:3.5分可玩性:4.5分游戏设计:3.5分平台 :ETH发布时间 :2018-02-01网址 :https://cryptocountries.io/《CryptoCountries》是一款基于以太坊的卡牌类游戏。游戏主要玩法就是将每个国家在区块链上做成类似虚拟代币一样的token,玩家通过购买这些token来“征服”这个国家。“征服”后,你的名字将写在国家的token上。这款游戏的本质就是击鼓传花。该游戏中玩家拥有一个国家的所有权后,如若其他玩家要想获得,需支付更高的价格。由于宣传噱头到位,2018年春节前后的一周时间里,它创造了4.5万ETH的交易流水。7. BetDice影响力:4.0分可玩性:4.5分游戏设计:3.5分平台 :EOS发布时间 :2018-09-21网址:https://betdice.one/BetDice是一款掷骰子游戏,玩法简单,只要玩家投出小于其设定的数字就获胜。前期的代币空投活动,以及后续的抽奖活动,使BetDice吸引了大量的用户,上线三周后累积成交量就超过3400万EOS。6. 以太水浒影响力:4.0分可玩性:4.5分游戏设计:4.0分平台 :ETH发布时间 :2018-02-17网址 :http://cryptohero.pro/《以太水浒》也是一款由区链块技术打造的水浒题材的策略卡牌类手机游戏,游戏中,每张卡牌都代表一位英雄,玩家可以进行自由的买卖,获得以太币的奖励。《以太水浒》是中国第一个国产DApp。该款游戏发行时刚好卡在击鼓传花类游戏高峰期,外加上打着中国第一旗号,它着实火了一把。尽管现在看这款游戏的方方面面做的都很差,但火爆时卡牌人物宋江曾被炒到50ETH+。5. EOS Pixel Master影响力:4.0分可玩性:4.5分游戏设计:4.5分平台 :EOS发布时间 :2018-09-23网址:https://pixelmaster.io/EOS Pixel Master是EOS ASIA制作的一款EOS链上画板。主要就是在一块1000x1000像素的画布上作画,再使用 EOS 去购买相应位置上的像素。此款游戏同属于现象级DApp,上线9天之内吸金80万美元,并获BM点赞。4. 加密英雄影响力:4.5分可玩性:4.5分游戏设计:4.5分平台 :ETH发布时间 :2018-09-21网址 :https://www.mycryptoheroes.ne…加密英雄是由日本游戏公司double jump制作的,它是一款RPG游戏。此游戏使用了历史或者传说中的英雄人物作为原型。该游戏正式推出后,几天内就冲入ETH游戏榜单的第一名。游戏整体呈像素风格,UI设计和用户体验都还可以,在游戏DAPPs中的表现也可圈可点。3.CryptoKitties影响力:5分可玩性:4.5分游戏设计:4.5分平台 : ETH发布时间 :2017-11-23网址 :https://www.cryptokitties.co/《CryptoKitties》是一款由Axiom Zen开发的区块链宠物养成游戏。在游戏中,玩家使用以太币进行电子猫的购买、喂食、照料与交配等,但其最为核心是玩法是将以太坊区块链中的电子猫进行出售。该款游戏是以太坊上第一个现象级的区块链游戏,也是至今为止生命周期最长的游戏类DApp,创造了单日14000+日活跃地址记录(2017年12月09日),一度造成以太坊交易堵塞。2.Fomo 3D影响力:5分可玩性:4.5分游戏设计:5分平台 :ETH发布时间 :2018-07-05网址 :https://exitscam.meFomo 3D是一款典型的资金盘游戏。游戏玩法简单:只要你是最后一个出价的人,并且这个价格维持 24 小时,那么奖池里的所有以太坊都给你。它包括了:闪拍系统、分红系统、战队系统、排行榜系统和邀请系统,加强了游戏的可玩性。此游戏由于有最终Key购买者独占奖池的诱惑,玩家会主动向奖池持续注入ETH。第一轮游戏结束时,奖池金额高达10469.66ETH,轰动整个DApp圈。同时也是由于此款游戏的成功,后续引出了近百个仿品。1.EOS Knight影响力:5分可玩性:5分游戏设计:5分平台 :EOS发布时间 :2018-07-08网址 :http://eosknights.io/EOS Knights是一款由韩国BADA工作室开发的RPG游戏。玩家首先需要用EOS在游戏中购买英雄,然后通过打怪让英雄升级。玩家在打怪的过程中,获得系统奖励的宝物。玩家可以通过出售宝物,赚取EOS。该游戏从去年7月份上线到现在,日活交易量等都保持良性发展态势,是EOS游戏中的一股清流。小结复盘2018,我们不难发现去年火爆的DApp基本都属于博彩类,从狂热到崩塌,“戏里戏外"间人性的贪婪演绎的淋漓尽致。但狂热过后,伴随着的确是理性的回归。目前已有越来越多的正规游戏厂商开始关注DApp,准备着手进军这一领域。DappDiscover团队也由衷希望2019DApp领域呈现新气象。所有的游戏种类,该佩奇的都“佩奇”,而非仅仅是菠菜类的天下。你有哪些感兴趣的DApp?欢迎留言回复下一次讨论的,也许就是它。

February 12, 2019 · 1 min · jiezi

以太坊合约的安全性弱点,你都绕开了吗 III

新年前,我们最后来谈一谈以太坊安全性的特点。不可能修改的bug当合约公开在区块链上之后,它就不能去修改了。相应的,合约中出现的任何 bug 也没有机会改正。如果希望能够修改bug,合约编写者就需要在编写合约的时候预留一些用来修改或终止合约的代码。但预留修改后门这一方式具有争议,因为在以太坊的愿景中,智能合约一旦部署,其设定就应当是不可更改的。正式因为 bug 不可修改,可能会导致一些很严重的攻击事件没有弥补的方法。DAO 攻击是唯一的例外。以太坊使用了一个硬分叉解决了这一问题。但这种做法没有得到整个社区的赞同,因为它违背了“代码即法则”这一准则。调用栈大小限制每次合约调用另一个合约的时候,调用栈就会增加一个 frame. 上限是 1024 个。当这一上限达到的时候,下一次调用会触发一个异常。如果攻击者先将自己的调用栈离填满只差一个 frame,然后去调用受害者合约的函数,那么受害者函数执行中任何调用将会导致执行失败。如果受害者函数没有正确的处理执行成功与否,将可能导致意料之外的结果。在文章后续部分,我们将以一个例子说明这一点。为了解决这一问题,在一次以太坊升级中,规定了每次通过 call 或 delegatecall 调用合约函数时,只能为被调用函数分配最多 63/64 的剩余 gas. 而以太坊中每个区块最多只能包含约 470 万的 gas。也就是说,如果调用者最初投入了数量为 a 的 gas, 在 10 层递归调用后,最内层的函数最多只有 (63/64)^10*a 的 gas. 因此,调用深度不可能超过 1024. 后面的攻击案例中,假设还没有这一修补方案。时间约束大量的应用使用时间约束来决定某些行为什么时候被允许。比如在一个 ERC 20 合约中,从某个时刻开始,允许用户使用 ether 购买一个 token.在智能合约的执行过程中,当前时间取自给定交易所在区块的区块时间戳。所以,一个区块中的所有交易在执行时使用的是相同的时间戳。这一设定保证了智能合约在每个矿工那里的执行结果是一致的。但这个设定也可能导致一些攻击,因为矿工在选择时间戳的时候有一定的自主权,这可能为一些攻击埋下了后门。GovernMental 合约的攻击GovernMental 是一个“庞氏骗局游戏”型合约。严格来说,其实不能叫骗啦,因为庞氏骗局的规则被公开地写在合约里。在这个合约中,每个人通过向合约中转一笔钱来加入这个庞氏骗局游戏。合约通过两个数组记录参与者的地址和每个参与者转入的钱的数量。如果最后一个人加入后 12 小时后都没有下一个人加入,那么最后一个人就可以获得全部的收益。(这个设定是不是有点像著名的 Fomo3D,值得注意的是,Fomo3D 的出现晚于这篇论文呦。)下面是一个简化版的 GovernMental 合约在这个合约中,参与者可以通过 invest() 函数来投入 ether 并加入这个游戏。合约维护一个名为 jackpot的变量,表示如果后续没有人加入,赢家将拿走多少 ether. 新来的参与者必须投入多于 jackpot 一半的 ether, 同时,新来的参与者投入的 ether 中,会有一半被加入 jackpot. 如果连续一分钟没有人新来的参与者,最后一个人获得 jackpot 中的 ether,同时合约拥有者拿走剩下的钱(留下 1 个 ether 作为下一轮的启动资金)。需要注意的是,这里并没有检查最后分钱的时候,通过 send() 函数进行的转账是否成功。这个简化版的合约有几个点可供被攻击。攻击一这个攻击来自合约拥有者自身,目的是让本来的游戏赢家无法拿到钱。合约拥有者利用 send() 函数的异常处理和调用栈大小限制进行攻击。攻击的方式是,通过预先进行大量的递归调用,导致执行 resetInvestment() 时,调用栈达到了大小上限,无法再执行给游戏赢家和合约拥有者的 send() 函数。合约拥有者和游戏赢家都拿不到钱,钱依然留在合约中,但之后重置合约状态的代码会照常执行。只要再进行一轮正常的游戏,合约拥有者就可以将本该属于上一轮游戏赢家的钱收入囊中。攻击二这一攻击方式来自矿工。矿工可以通过拒绝打包其他人与 GovernMental 合约的交易,来使自己希望的人成为合约游戏的赢家。更多地,进行攻击的矿工在打包区块时可以任意决定交易顺序,来影响这个区块过后谁是 lastInvestor.之前也提到过,每一个新参与者需要投入的 ether 数量不能低于合约中 jackpot 中 ether 数量的一半。而一个人在发起交易的时候看到的 jackpot 数值,与它的交易被执行时 jackpot 的数值可能是不一样的。这就导致这个人可能发起交易时以为自己投入的 ether 数量是符合要求的。但是执行时,由于 jackpot 数值的改变,变成了一笔无效交易。这就是上篇文章中提过的不可预测状态问题。另外,矿工拥有决定区块时间戳的权利。而合约在执行时,判定 resetInvestment 是否可以执行,就是读取矿工决定的区块时间戳。通过影响区块时间戳,也可以影响游戏结果。结语通过这几期对参考文献 [1] 的学习,我们看到了一些以太坊 Solidity 合约中设计的弱点。虽然这些弱点称不上是漏洞,但是如果在编写合约时,对这些点不了解,没有充分考虑,就可能写出有安全问题的合约出来。参考文献:[1] Atzei, Nicola, Massimo Bartoletti, and Tiziana Cimoli. “A survey of attacks on ethereum smart contracts (sok).” Principles of Security and Trust. Springer, Berlin, Heidelberg, 2017. 164-186.–Conflux 是致力于打造下一代高性能的 DAPP 公链平台欢迎关注我们的微信公众号:Conflux中文社区(Conflux-Chain)添加微信群管理员 Confluxgroup 回复“加群”加入 Conflux官方交流群 ...

January 31, 2019 · 1 min · jiezi

盘他!以太坊合约的安全性弱点II

今天,我们继续介绍文献中提到的以太坊合约的安全性弱点与案例。数据保密Solidity 智能合约中的变量分 public 和 private 两种。Private 变量表示这个数值不能被其他合约直接读取。但是,将一个变量标记为 private 不意味着里面的信息就是保密的。因为以太坊是公开的,每次合约函数执行的字节码,参数都是公开的,任何人都可以推断出每次函数执行后是否修改了变量,修改后的数值是多少。Private 只是能够保证其他合约执行的时候,无法读取其中的变量罢了。然而,一些本应该隐藏玩家数据的游戏,却错误地使用了这一点。以下是一个示例:两个玩家在玩一个赌博游戏,每个玩家选一个正整数,两个正整数加起来的奇偶性,决定了获胜者。存储玩家选择的变量是 players, 这个变量具有 private 属性。玩家通过调用智能合约函数选数的时候,决策并不是保密的。为了实现保密性,更好的方式是使用一个称为“委托”的密码学原语。当玩家需要秘密地做出一个决定时,可以将 sha3(决策内容,随机数) 得到的哈希值存到合约里。当玩家需要公开自己选择的时候,将 决策内容 与 随机数 公开,并由智能合约验证哈希值与先前存储的是否一致。可以实现类似于“先在纸上秘密写下选择,到后面一个环节再亮出来”的功能。随机数生成EVM 的字节码执行是确定性的。因此,如果智能合约想生成一个随机数,就需要通过一个随机数种子生成一个伪随机数。而随机数种子的选取方式,对生成随机数的公平性有很大的影响。一个常用的做法是,使用一个给定时间或给定高度区块的哈希值或时间戳。这件事情在给定区块被确认以后,在每个矿工看来都是一样的。看起来这是一个公平的做法,因为没有人能预测未来的区块。但是,一个恶意的矿工可能尝试操纵自己生成的区块来影响随机数的生成与合约的执行结果。一个分析表示,一个控制少数算力的矿工,只需要投入 50 个比特币就可以显著地改变输出结果的概率分布。另一个方式是使用“延时委托协议”。在这个协议中,每个参与者选择一个秘密的随机数,并将哈希值广播给其他人。在晚些时候,所有参与者公布它们选取的秘密随机数,或者丢失押金。最终随机数由所有公布的秘密随机数和一个公开的算法生成。攻击者可以在“其他所有人都已经公布了随机数,自己还没有公布”时,预先计算最终生成的随机数,如果生成的结果它不满意,就通过拒绝公布自己选择的随机数方式,来使这个结果无效。当然,攻击者要损失一些押金。所以,押金的设定要足够高,高于随机数生成中改变结果可能带来的收益。不可预测状态一个合约的状态包括合约变量和合约余额。一般情况下,当用户通过一笔交易调用合约函数的时候,从交易广播到交易被加入区块之间,可能有其他的交易改变了合约的状态。也就是说,当用户发起一笔交易时,并不能确定这笔交易被执行时,合约的状态是什么。一个基于 library 和不可预测状态的攻击下面我们来看一个例子,以下的 Solidity 代码定义了一个名为 Set 的 library。下面是一个名为 SetProvider 的合约,提供了一个 Set library 的地址,合约拥有者可以修改这个地址,任何人/合约可以获取这个地址。假设 Bob 合约是一个使用 SetProvider 的诚实用户,他的代码如下:Bob 记录了一个 SetProvider 合约的地址,在 getSetVersion() 中,使用这个地址获取了一个 Set library 的版本号。现在,假设 SetProvider 合约的控制者是个坏人。他制造了一个恶意的 Set library, 希望偷得一些钱存到他自己的钱包地址 0x42 中。如果合约 SetProvider 中 setLibAddr 的地址被修改为 MaliciousSet 的地址, Bob 合约中调用 getSetVersion() 函数时,会调用 MaliciousSet 的 version() 函数,而不是 Set 的。因为 Bob 合约中将 Set 声明为一个 library, 所以对 version() 的调用采用的是 delegatecall 模式。 delegatecall 模式意味着转账操作 attackerAddr.send(this.balance); 是从 Bob 合约中转账出来。 Bob 合约中的钱将被偷走。上述例子说明了,对 library 函数的调用使用的是较为危险的 delegatecall 模式。因此合约编写者在使用其他合约地址作为 library 时,一定要保证通过 library 加载进来的代码是自己可控的。比如,手动指定一个已经在区块链上不可修改的 library 的地址。而不是在本例中依靠于一个不可靠的 SetProvider 合约来获取 library 的地址。另外,“不可预测状态”问题也加剧了这件事情。即使在调用 Bob 合约的 getSetVersion() 函数时, SetProvider 指向的是诚实的 Set library. 攻击者也可以在这一交易还没有被加入区块的时候,通过发起一笔交易费数额较大的交易,抢在 getSetVersion() 被加入区块之前,将 SetProvider 的指向修改为 MaliciousSet。Conflux 是致力于打造下一代高性能的 DAPP 公链平台欢迎关注我们的微信公众号:Conflux中文社区(Conflux-Chain)添加微信群管理员 Confluxgroup 回复“加群”加入 Conflux官方交流群 ...

January 30, 2019 · 1 min · jiezi

第11期 DApp 榜单:这是一篇让DD君重伤住院的内容

作者:DD君欢迎添加作者微信 btcbtc555 与他进行交流!未经授权禁止转载!上周我们DAppDiscover创始人,在被采访时再一次提到了游戏DApp的引导性价值。旁听全过程的DD君心里就在纳闷,既然这么重要,为什么当下的DApp做的还这么差,3W疑惑渐涌心头。历尽千辛万苦后,终于DD君找到原因了,详情请看下文观点分析部分。以下先进入,我们的本周榜单。ETH榜单游戏1 ETH 在本周已经彻底出榜了。这类游戏,来的快去的快的铁律又一次被验证。其实ETH上开发一个DApp的成本仅是开发合约的费用,而DApp运行的成本全部由用户自己承担。但即便如此,也挡不住越来越多的以太开发人员“下乡”到EOS和TRON上。流量既是王道,DAU即是风向标。排名第一IDEX日活才600多,以太还有什么希望呢?EOS榜单本周EOS榜单前五相较于上周没一丝起伏变化,EOS的头部DApp已基本固定。昨晚 20:23~21:07 之间,PeckShield 监测到黑客又向 EOS 竞猜类游戏 EOSlots 发起连续攻击。目前游戏已经暂停运营。树大招风这句话,没毛病。TRON榜单人类的本质就是一台复读机。榜单第10名,是不是超级眼熟,前不久好像也有一款火到不行的游戏叫什么3D来着。还记得高中语文老师有一次戏说“天下文章一大抄,看你会抄不会抄”,宇晨哥绝对是其中好手。如果只看DAU给三大公链排行,TRON系DApp可占据半数以上。与此同时,在全球市值流通榜单上,TRON也稳占前10位置。QQ当初也是模仿ICQ,但由于对中国互联网用户理解更深,照样击败ICQ,成为中国即时通讯和社交领域之王。波场真有可能在未来搅了个天翻地覆。观点分析对,没错,DApp游戏的关卡设计师,别到处瞅了,接下来怼的就是你。在目前的大环境下,大部分玩家已经达成这样的一个共识——游戏DApp可能成为未来率先爆发领域。但当下的任何一个游戏DApp的体验,不是一个“差”字就可以形容的。游戏DApp本质上,还是游戏。DD君仔细研究了一下传统互联网游戏领域,终于找到问题出在哪里了——关卡设计师尸位素餐。“关卡设计师是游戏环境、关卡和任务的设计者”-维基百科一款游戏,不管是对关卡流程和游戏玩法思考新的游戏创意,还是游戏画面效果,抑或是游戏中AI,都离不开关卡设计师的存在。游戏关卡设计师对以下五个维度的负责:1.逻辑流畅游戏应该具备最基本的逻辑客观性,一切关卡设计都要符合游戏世界的背景设定或者游戏世界的客观规律。2.难度合理游戏的难度设定有两种方法:一种是线性设计,也就是将难度在游戏过程中逐渐提高。比如,在动作游戏里把跨越的障碍增加宽度或者是高度,或者是用其他难度较大的物件替代难度较小的物件。一种是非线性设计,就是直接设置游戏的不同难度水平,在游戏开始之初让玩家自己进行选择,通常分为Easy、 Normal、Hard、Very Hard等。过高的难度设定会让玩家丧失信心,过低的难度设定又会导致玩家感到乏味。关卡设计师需把握二者关系,设计出达到微妙程度的平衡。3.趣味性趣味性并非三言两语可以解释清楚,不同的人对趣味的定义也不尽相同。关卡设计师没办法满足每一个人对趣味的要求,但设计关卡时向玩家提供适当的游戏奖励,却可以提高每个人已有感知的增加。例如,在一个难度较大的关卡通过后,适当地对玩家给予补偿或奖励,或者在通过难度较高的关卡后会出现一段低难度的流程。再例如在游戏设置大量的收集类道具,通过收集给予额外的游戏奖励。4.耐玩性一款游戏是否有价值,有一个很简单的衡量标准——玩家愿意在该款游戏上耗费的时间。如果一个花费大量时间设计的游戏关卡,但玩家在短时间通关后就丢置一边,这样的游戏无疑是失败的。增加游戏关卡的耐玩性通常有以下几种方法:①设计大量的分支流程。让玩家在主流程的体验过程中不断体验到分支流程,这样大大增加了游戏持续的时间。②设置隐藏要素。在游戏关卡中设计大量的隐藏道具、任务等,让玩家花大量时间来探索和完成。5.视觉效果游戏关卡还要设计得合理、简洁和有序,不能看起来混乱。以上五点,有哪一款DApp游戏成功布局了全部???一款游戏你可以设置宏大的世界观,仙侠神魔,星际宇宙等等,仅凭君愿。但我们还应记得“贪吃蛇”“俄罗斯方块”等小游戏至今屹立不倒。再让你重温“超级玛丽”,你可能会不屑一顾,但逃不掉的“真香定律”,很快就会啪啪啪打你脸。好的游戏都离不开优秀的关卡设计师,没有他们无异于空中楼阁。DApp项目方的关卡设计师们,看看我们这些小菜鸡渴望的眼神,听听我们内心无声的呼唤,努力啊!DApp项目方笑了:“我们一般Ctrl+C,Ctrl +V,quan完钱,好回家过年。真是感谢DD君科普,我们也是第一次听说这个职位”DD君:“你们…我…”后续报道:由于DD君情绪起伏过大,心血管破裂,吐血三升,目前正在抢救中。

January 29, 2019 · 1 min · jiezi

以太坊合约的安全性弱点,你都绕开了吗?

很多以太坊的智能合约控制着有实际价值的数字资产。因此,保证合约没有安全漏洞是十分重要的事情。这几期为大家带来一篇 2017 年对以太坊合约攻击调研的文献,来帮助大家避免以太坊智能合约设计中的一些可能导致安全性问题的弱点。在这里,你也可以看到,导致以太坊分叉的著名事件 The DAO 攻击,其原理是什么。这篇文献分两部分,第一部分介绍了一些如果对 Solidity 语言和智能合约不当使用会导致问题的弱点;第二部分则用一些实例展示了这些弱点可能会导致怎样的问题。我们今天还推送了另一篇文章作为背景资料,为不熟悉智能合约和 Solidity 语言的读者介绍一些背景内容。不当使用会导致问题的点合约内函数调用在使用 Solidity 编写智能合约时,可以调用其他合约中的函数。假设 Alice 合约里有一个 ping(uint) 函数, c 是一个 Alice 合约在以太坊上的地址。如果其他合约(或 Alice 合约自身)想要以参数 42 调用 ping 函数,有三种方式:第一种call 调用:通过合约地址,合约函数,函数签名和调用参数进行调用。如果被调用函数中有修改合约变量的代码,将修改被调用合约中相应的变量。第二种delegatecall 与 call 类似,区别是 delegatecall 执行时,仅仅使用被调用函数的代码,而代码中如果涉及到合约变量的修改,则是修改调用者合约中的变量。如果被调用的函数中有 d.send(amount)的指令,表示向地址 d 转一定数额的以太币,在 call 模式下这笔钱从被调用合约的余额中转出。在 delegatecall 模式下将从调用者合约的余额中转出。因此, delegatecall 是更危险的命令,如果这一命令加载的函数代码是合约编写者不可控的,可能会导致合约的钱被转走或合约被销毁等严重后果。第三种这第三种调用方式在论文中被称为直接调用 (direct call). 它先在合约里声明了 Alice 合约需要调用的函数,然后调用它。这种方式与以上两种方式在异常处理上会有区别。需要注意的是,以上三种方式如果将函数名或者参数类型设置错误,则会调用回退函数 (fallback function). 如果是因为笔误打错了内容,可能会触发本不该执行的回退函数中的代码。Gasless Send在 Solidity 中,如果变量 rec 的类型为 address, 那么 rec.send(amount) 表示由合约向地址 rec 转账数额为 amount 的 wei. (10^18 wei = 1 ether ) 在这个执行的过程中,还会触发地址 rec 的回退函数。如果回退函数执行过程中消耗的 gas 大于 2300,则会触发一个异常,导致转账失败。异常处理在背景介绍中我们提到过,使用 Solidity 执行智能合约时会抛出异常,但是不同的合约内函数调用方式对异常(exception)的处理方式不一样。如果合约执行过程中没有函数调用,或者只有 direct call 直接调用,那么当触发一个异常的时候,视为合约执行失败,直接停止合约的执行,回滚执行过程中的转账和对合约变量的修改等操作,并扣除全部的交易费用。如果通过 call, delegatecall 或 send 调用其他合约函数,在执行期间触发的异常不会影响原有函数。也就是说,如果在执行 send 的触发的回退函数过程中,如果 gas 不足引起了异常,转账会失败,但是原有合约会被成功地执行。如果对这一点缺乏足够的理解,错误地认为合约执行成功意味着 call 调用也一定成功,错误地认为没有触发异常就意味着 ether 转账成功,就可能导致合约有安全性问题。正确的做法应当是通过函数调用返回的结果判断其执行是否成功。而一些研究表明有 28% 的合约没有检查返回结果。(当然,这不意味着一定有安全问题)重入问题Solidity 中回调函数的机制,可能会让合约调用其他函数后,被调用的函数又调用了调用者合约的函数,造成循环,下面是一个例子假设区块链上已经如下的合约 Bob,如果 sent 变量为 false, 就向给定地址发送一笔钱。而 Mallory 是攻击者恶意构造的合约,代码如下所示。Bob 合约设计的本意是,如果 sent 变量为 false, 就向给定地址发送一笔钱。然而,当这笔钱发往攻击者合约时,会触发攻击者合约的回退函数,回退函数再次调用 ping 函数,如此无限循环,直到交易费耗尽或调用深度达到上限 1024 次触发异常。但之前提到了,对于 call 调用的函数在执行过程中触发的异常,不会影响原来的函数的成功执行。也就是说,除了最后一步转账会失败,之前的转账都会成功。几种攻击接下来,我们介绍几种利用上面提到弱点的攻击例子。DAO 攻击DAO 攻击是以太坊历史上最著名的攻击,盗走了价值 6000 万美元的以太币。以太坊社区通过强行回滚硬分叉了以太坊,导致了以太坊和以太经典两条分叉链并存的局面。下面是一个简化版的 DAO 智能合约,但足以描述 DAO 合约的漏洞。这个合约的功能很简单,任何人可以向指定地址捐献以太币,受捐赠人可以提走自己受捐赠的币。而攻击者通过以下的合约,就可以大量转走合约中的币。其原理与上文所说的重入问题完全一样, SimpleDAO 合约的 withdraw 函数执行时向攻击者合约转账,转账会触发攻击者合约的回退函数,攻击者合约的回退函数会重新调用 SimpleDAO 合约的 withdraw 函数,形成一个循环。当循环因为各种原因结束的时候,除了最后一步,之前的执行都不会失败。攻击者转出了大量的钱。另外,这个合约没有考虑整数溢出问题,因此有如下攻击成本更低的方案 在这个合约中,攻击者设计了一个函数 attack, 当这个函数被执行的时候,攻击合约先给自己捐赠 1 wei, 然后把这 1 wei 取出来。在取钱的时候,会触发攻击者合约的回退函数。与之前的攻击不同,这次我们只利用重入问题 1 次,也就是 withdraw 函数被执行了两遍。在 withdraw 第二次向攻击者转账以后,攻击者不再调用 withdraw.于是 withdraw 函数中的转账操作 msg.sender.call.value(amount)() 发生了2次,自然地,它的下一行也会被调用 2 次。这两次被调用将 credit[攻击者地址] 变成了 -1 wei, 会被虚拟机解读为 2^256-1 wei. 这时,攻击者可以从中取出几乎无限多的钱出来。特别的是,即使 withdraw 函数在转账后检查 send 执行是否成功,也只能防范第一种攻击。以太王座考虑下面一个游戏合约,在游戏中,大家将竞争一个王座。后来者可以通过向王座上的人支付一笔钱来取而代之,每一轮取得王座需要的钱都要比上一轮高。最后取得王座的人有额外的收益。(没有在合约中体现。) 这个合约看上去没什么问题。事实上,他人在向王座上的人(地址)支付费用的时候,会触发那个地址(如果是一个合约)的回退函数。如果王座上合约地址的回退函数需要的交易费过高,会触发 gasless send 的问题,就会导致转账失败。但后续变更王座拥有者的代码还会照常执行,新来者可以毫无成本地获得王座。修改这一问题的思路看上去很简单,只要将转账的代码 king.send(compensation) 变成 if(!king.call.value(compensation)())throw; 来判断一下转账是否成功就可以了。然而这会导致另一个问题。王座上的地址(合约)将自己的回退函数设定成一定会触发异常,例如 function(){throw;},就没有人有能力将他从王座上赶下去了,因为所有转账的结果都会失败。以上就是这一期的内容,在接下来的文章中,我们将会介绍文献中提到的其他的 Solidity 的弱点与可能导致的问题。参考文献:[1] Atzei, Nicola, Massimo Bartoletti, and Tiziana Cimoli. “A survey of attacks on ethereum smart contracts (sok).” Principles of Security and Trust. Springer, Berlin, Heidelberg, 2017. 164-186.Conflux 是致力于打造下一代高性能的 DAPP 公链平台欢迎关注我们的微信公众号:Conflux中文社区(Conflux-Chain)添加微信群管理员 Confluxgroup 回复“加群”加入 Conflux官方交流群 ...

January 28, 2019 · 1 min · jiezi

对话 | DAppDiscover创始人:对用户而言,DApp体验比排名更重要

2018年年末,DApp被推到了聚光灯下,资本又一次在这里汇聚。今天我们Boon区块链社区有幸采访了DAppDiscover创始人Johnny,与其共同探讨了目前关于DApp的一些焦点问题。以下为采访详情:“ 用户体验比排名更重要小九:DApp在今年下半年可谓是相当火爆,目前每天都有新的DApp产生,您是从什么时候开始接触到DApp?做DAppDiscover的初衷是什么呢?Johnny:其实我个人很早就进了币圈了,94过后,随着国家政策的收紧,币价遭遇断崖式下跌,我就开始思考,区块链真正的应用在哪里。17年年底,加密猫大火,一度造成以太坊网络交易拥堵,从那个时候起,我就开始关注DApp的发展。目前来讲,DApp的数据监测网站比较多,国外有radar,国内也有review等。但是这些网站关注的重点都是链上的数据,对于普通用户不是太友好。就拿我自己而言,我在选择一款DApp游戏的时候,首先考虑的不是它的排名,而是它的体验和可玩性,数据对于我而言没什么太大的意义。与此同时,我还渴望与和我玩同一个DApp的人一起沟通交流,渴望获得更多有价值的资讯,但是这些网站却都不能满足我的这种需求。所以我决定自己做一个网站,DAppDiscover就由此萌发了。“ 掌握自己的数据小九:大家都知道DApp其实就是去中心化的App,单就普通用户而言,目前的App其实已经可以满足其的日常工作生活所需,那为什么还需要DApp,换句话说,DApp是否就是一个伪命题?Johnny:去中心化和中心化的概念,离用户确实挺远的。因为我们一直处在中心化的而世界里面。今天我们不讨论这种形而上的概念,我想谈一谈具体的东西,比如用户数据。DApp与App的区别,本质上是用户是否能独立掌握数据的区别。如今,数据是重要的生产资料已经逐渐成为共识。用户是数据的生产者,但在传统互联网的分配机制上,用户却不能掌控自己的数据,也不能享有数据产生的价值,更有着数据被任意窃用,篡改的可能性。作为一个新生事物,DApp目前确实没有办法替代App,但随着数据化时代的推进,DApp的优越性将越发凸显。在掌握自己数据的同时,获取到相应的价值,同时能兼顾享受目前App所提供的所有功能,这是未来所有用户的需求。“ 能抓到老鼠的就是好猫小九:目前的DApp上种类少,并且吸引用户的大多博彩类DApp,像TRON干脆被称为“博彩链”,对于这种现状,您是怎样看待的?Johnny:大家其实都明白“黄赌毒”永远都是最吸引人的地方。我们就拿互联网来说,互联网早期就是一个泥潭中野蛮生长的过程,抄袭、盗版、流氓软件、涉黄、涉赌、等等层出不穷。但也就是这些“不入大雅之堂”的东西,催生了互联网快速的更新换代。举个例子,你在浏览某些网站的时候,画面清晰后,你肯定还会希望加载速度快。那这就要求后面的技术人员,不断的对系统升级。从宏观角度来看,长此以往,肯定是整个互联网行业的快速发展。现在的DApp也是,我们不能仅仅因为“博彩”二字,就将这类DApp定义为不好的。但如果它能通过这种途径,不断刺激背后的逐利者,让他们愿意花更多的人力物力财力去研究如何提升自身性能来满足这些用户需求,在某种层面上看,这不是一件坏事。“ 游戏不好玩怎么可能吸引用户小九:游戏永远是我们最感兴趣的话题之一,现在DApp面临的一个共同的问题就是用户太少,您认为目前DApp游戏是否能拯救当下这一颓势?Johnny:现在还不行。我们为什么去玩游戏,其实就是为了好玩。每天都会出现大量的手机游戏、PC游戏,只有非常少数需要用到最新的硬件和技术,绝大多数用几年前的电脑照样可以玩。必要的趣味性,以及有趣的故事情节,才能够吸引足够的玩家,而非单单依托于性能。目前的DApp 游戏都过于简单化,也基本没有太吸引人的地方。目前的DApp游戏还不足以吸引更多的用户进入这一领域。“ 但最先爆发的肯定还是游戏领域小九:作为DApp领域的资深人士,在您看来,2019年DApp可能最先会在哪个领域爆发?Johnny:虽然说现在的DApp游戏还处于初始阶段,但如果说爆发的话,还是游戏领域,原因有几点。首先,游戏用户群体整体偏年轻化,这类群体的接受程度和学习能力相对较强。DApp本身就是一个有门槛的领域,显然,将游戏用户从传统App争取到DApp上来,相对来说,是成本最低的一件事。第二,传统领域,玩家在玩游戏过程中只拥有游戏的使用权而没有所有权。游戏厂商任意增发道具,或者是更改某些设置,玩家只能被动接受,这其实已经引发了大批量玩家的不满,而DApp游戏却不会有这样的问题。第三,通证经济和资产代币化同时增加游戏的经济属性和激励机制,这可以让玩家像拥有现实世界中的实体物品一样,拥有游戏中的虚拟资产。这种方式可以改变开发商与玩家之间的协作关系,使玩家相对于传统的互联网领域拥有了更多的话语权。我已经注意到很多老牌的游戏厂商已近开始慢慢入场,包括网易还有腾讯,他们也已经在做了一些区块链游戏的尝试。如果后续真的有一个杀手级别的DApp出现,那绝对是游戏领域。

January 28, 2019 · 1 min · jiezi

想玩DApp,没有钱包账户怎么行?—— ETH钱包

*作者:DD君欢迎添加作者微信 btcbtc555 与他进行交流!未经授权禁止转载!*MetaMask是一款在谷歌浏览器Chrome上使用的插件类型的ETH钱包。该钱包不需要下载,只需要添加对应的扩展程序即可。非常轻量级,使用起来也非常方便。本文以MetaMask为例,手把手教大家创建ETH账户,让您玩转整个ETH生态。ETH账户创建教程进入谷歌商店,搜索MetaMask,选择“添加至Chrome”。选择后弹出如下窗口,选择“添加扩展程序”。若跳转到此页面,并且右上角出现小狐狸图标,则安装成功。点击小狐狸图标,在弹窗中选择"CONTINUE"。在这个页面创建MetaMask登录密码(不少于8位),密码输入完成后点击“CREATE”。进入如下页面后,可以注意到左上角有一个圆形图案,是通过相应算法系统生成,每一个账户,对应的图案都不相同。此后会有三个默认选项,可以直接选择"NEXT"或“ACCEPT”。一系列默认选项后,进入如下页面,灰色区域为助记词位置,点击“CLICK HERE TO REVEAL SECRET WORDS”显示助记词。MetaMask会默认为用户创建12个英文助记词,这些助记词一定要保存好。我们所有的私钥-公钥-地址都由该助记词创建。建议大家可以拿本子记好,以防丢失。备份好后,点击“NEXT”,依次选择助记词的顺序,完成后点击“COMFIRM”。完成后点击“VIEW ACCOUNT”,MetaMask主界面如下:点击右上方图标,可以建立新的账户。输入账户名字后,点击“CREATE”,便创建了一个新的账户。在主界面中点击“…”,即可了解账户详情点击过后,您可查看您的账户地址。点击上图下方“EXPORT PRIVATTE KEY”,进入如下界面,输入您初始设置的登陆密码(步骤5),即可查看您的私钥。您的钱包已经创建好,打开任意您想玩的ETH游戏,勾选二者默认绑定选项,即可体验该游戏。你有哪些感兴趣的DApp?欢迎留言回复下一次讨论的,也许就是它。

January 17, 2019 · 1 min · jiezi

Ethereum 君士坦丁堡安全漏洞对 FOD 的影响

FOD 与 Ethereum 的前世今生FOD 是 FIBOS 生态中的稳定币,与 USDC 1:1 锚定,其服务于需要稳定价值衡量的应用场景。FOD 通过跨链网关将 ETH 链上的 USDC 与 FIBOS 链上的 FOD 价值绑定。这相当于 1:1 锁定了流通 FOD 同等数量的 USDC,并提供稳定即时的双向兑换。Ethereum 君士坦丁堡升级对 FOD 的影响本次 Ethereum 君士坦丁堡升级是 Ethereum 由大都会转向宁静前的最后一次升级,升级采取的硬分叉模式,为了防止用户在升级时转账出现问题,我们决定暂时关闭 FOD 通道。由于在 2019 年 01 月 16 日凌晨,Ethereum 君士坦丁堡版本被曝出安全漏洞因此 FOD 通道重启只能延期,重启日期需要根据 Ethereum 基金会对这次安全漏洞对处理结果待定。Ethereum 君士坦丁堡安全漏洞智能合约中 address.transfer(…) 和 address.send(…) 存在重入攻击漏洞。漏洞产生的情况合约中有一个函数 A,A 中在改变状态后调用了 transfer/send 函数。这种情况有的时候不是很明显,比如二次 transfer 或者内部调用另一个智能合约必须存在一个攻击者可访问的函数 B,其中(a)改变状态,(b)状态改变与函数 A 的状态改变冲突。函数 B 执行消耗需要小于 1600 gas (2300 gas 限制 - 700 gas(为 call 提供的))为什么此次升级会产生安全漏洞在 Ethereum 拜占庭版本每个存储操作需要消耗至少 5000 gas,而 transfer/send 操作 gas 消耗要求小于 2300,在执行上述操作的时候会因为 gas 限制而无法执行。在 Ethereum 君士坦丁堡版本中,改良了 EVM 机制,从而减少了 gas 的消耗,因此出现了重入攻击的安全漏洞。Parity 客户端升级方法在这次安全漏洞之前的 Parity 客户端包含了 Ethereum 君士坦丁堡版本的升级并会在区块高度达到 7080000 时激活。针对这次的安全漏洞,Parity 官方紧急发布了新的 Parity 版本。Parity 升级方法升级指令:bash <(curl https://get.parity.io -L) -r stable验证是否更新成功parity -v得到的结果查看版本是否是 Parity-Ethereum/v2.2.7-stableParity Ethereum version Parity-Ethereum/v2.2.7-stable-b00a21f39-20190115/x86_64-macos/rustc1.31.1Copyright 2015-2018 Parity Technologies (UK) Ltd. ...

January 16, 2019 · 1 min · jiezi

FIBOS 与 Ethereum 技术对比

共识机制Ethereum 使用的是 PoW 共识机制,未来几年里将会换成 PoS 共识机制。Ethereum 区块是由矿工计算哈希产生,在 PoW 共识机制中区块需要得到全网络超过51%的节点确认才能够正式被区块链认可。在 Ethereum 网路中,任何人都可以成为矿工。FIBOS 使用的是 DPoS 共识机制。FIBOS 区块的产生是由21个 BP 轮流出块,产生的区块需要2/3以上的 BP 确认才能够被区块链认可。21个 BP 是由 FO 通证持有者投票选举出。账户/地址Ethereum 的用户使用的是地址,一个长达40位的的16进制数。FIBOS 使用的是账户管理,账户名采用12位数字与字母组合,可自定义,方便用户记忆。权限Ethereum 的权限是由地址唯一对应的私钥管理,并且这个私钥是随机生成的,在需要使用的权限的时候用户只能通过私钥授权。FIBOS 账户默认有2种原生权限: owner、active,一个账户必须“关联” owner、active 权限。owner 拥有超级权限,代表着账户的归属者,因为拥有此权限者可以用于操作其他权限配置,该权限常用事务中(转账、合约 action 等)一般不会使用。active 常用业务的权限,比如:转账、投票等。另外还可以根据自己需求自定义权限。手续费/资源Ethereum gas在 Ethereum 中使用区块链上的资源需要消耗 gas,消耗的 gas 作为区块打包的费用支付给矿工。FIBOS 资源FIBOS的资源分为两种类型:抵押型资源,包括 CPU 和 NET;消耗性资源,叫做 RAM,也称存储。开发者发布一个合约必须拥有足够的资源,包括 RAM、CPU 和 NET。智能合约编程语言的区别Ethereum 上开发智能合约使用的语言为 Solidity,这是一门专为 EVM 而开发的语言,对于一般没有接触过 Ethereum 或智能合约的开发者来说,该语言的研发门槛很高。Ethereum 合约示例:pragma solidity ^0.4.0;contract hello { function hello(uint i){ }}FIBOS 使用 JavaScript 编写智能合约,开发成本极低。这让开发智能合约的门槛降低了许多。FIBOS 合约示例:exports.hi = user => console.error(‘in contract:’, user);合约的发布和更新Ethereum 合约发布成功后会得到一个合约地址。合约地址格式长并且没有规律记忆起来十分困难。Ethereum 合约发布后无法更改。在 Ethereum 中如果合约发布后发现问题,现有两种解决方案:一个是在合约中预先设置销毁函数,并设置权限只有合约发布者可以调用,在需要的时候调用销毁函数销毁合约。另一个方法是在合约中预先设置 delegatecall,由于 delegatecall 保留了函数调用的状态,因此可以更新目标合约的逻辑,并且状态将保留在代理合约中以供更新后的目标合约的逻辑使用。这两种方法都需要预先的设置,以及发布合约的账号丢失后,也将失去对合约的控制权。FIBOS 合约账户名就是发布账户的账户名。发布合约时需要发布账号的资源,包括足够的 RAM、CPU 和 NET。在 FIBOS 中开发者可以使用发布账户随时更新合约代码。相较于以太坊的合约,FIBOS 的合约后期的维护和更新在技术上容易很多,在成本上低了很多。生态支持Ethereum:开发框架: Truffle 具有以下功能:内置的智能合约编译,链接,部署和二进制文件的管理。快速开发下的自动合约测试。脚本化的,可扩展的部署与发布框架。部署到公网或私网的网络环境管理功能使用 EthPM&NPM 提供的包管理,使用 ERC190 标准。与合约直接通信的直接交互控制台(写完合约就可以命令行里验证了)。可配的构建流程,支持紧密集成。在 Truffle 环境里支持执行外部的脚本。在 Truffle 框架中,可以根据需要编译、部署合约,Truffle 也提供一键启动测试链的工具。托管节点: InfuraEthereum 的合约可以通过使用 Infura 提供的节点发布合约。FIBOS:fibos.js 是 FIBOS 区块链的通用库,具有以下功能:使用 NPM 提供的包管理。快速开发下的自动合约测试。提供合约与客户端交互接口。提供合约内部所需的 API 接口。节点: FIBOS 提供一键脚本发布十分简单易用。FIBOS-tracker 是一个 FIBOS 区块链数据 API 服务框架,基于 fib-app 框架实现。提供对 FIBOS 区块数据的 emitter 监听事件。提供 http 服务,支持 GraphQL 调用。支持使用 ORM 定制自己的数据模型 model,自定义数据表以及自定义 hook 监听数据。 ...

January 16, 2019 · 1 min · jiezi

阻碍区块链应用落地的五大难题和解决方案

2018年初区块链掀起了一阵新热潮,多家互联网公司纷纷宣布推出区块链项目,新兴的区块链项目方和媒体百家争鸣,一时之间区块链行业风光无限。区块链概念的火爆,使得越来越多的人开始学习它、理解它,甚至“拥抱”它。只是沉浸在“狂欢”里的众人怎么也没有想到之后坏消息接连而至。从一开始的币价大跌“”币价大跌开始,接连有项目解散跑路,一众空气项目接连有序走向归零,市场恐慌接连不断,人们不禁开始怀疑区块链是否真的有出路。2019 年人们已从开始的狂热转向理智。关于区块链,大家关注的不再只是区块链是什么,而是区块链能做什么?提起区块链的应用,最先想到的便是以比特币为代表的数字货币领域。但是随着 1C0 的爆发,数字货币的投机性被疯狂放大,甚至部分沦为诈骗工具。目前区块链技术真正的落地应用却很少,我们不禁要问,被众人寄予极大期望的区块链为何落地会如此艰难?一、为什么区块链应用落地困难?我们可以发现区块链在应用落地方面遇到的困境可能主要有以下 5 个方面,在非技术方面,它面临炒作和投机、认知和应用门槛高等问题,在技术方面,它面临性能无法与互联网媲美,以及无法与互联网进行数据交互等问题。1、投机与空气项目之前的“区块链狂热”现象,仅仅是一些人利用空气项目和 1C0/IF0/IM0 的热潮在投机炒作而已,这些人的目的只是圈钱而并非真正地去研究、应用区块链技术。一开始就动机不纯又如何做到真正发展区块链,早已为后期众多项目跑路和解散埋下伏笔。2、认知门槛偏高区块链对于普通人而言,存在很高的认知门槛。及时是对于大多数行业内从业者,对区块链的认知也参差不齐。区块链本身是一门跨学科的边缘技术,涉及密码学、分布式网络、计算机软件、博弈论等多个不相关的学科,且资料匮乏,技术发展又异常迅速,知识更新非常之快,要完全了解和掌握是很困难的,需要投入大量的时间和精力去进行研究。3、应用门槛偏高区块链应用门槛高主要体现在对用户不友好。大部分应用存在存在一定的操作门槛。首先,用户需要具备一定的区块链技术知识,就拿基础的数字货币交易来说,用户可能就需要知道“私钥是什么”、“助记词是什么”、“冷钱包和热钱包”等等,大部分第一次接触的用户无法在短时间之内通过自身理解与操作融会贯通。其次,对于开发者而言,技术门槛也偏高,目前链上应用(Dapp)的开发可能需要掌握一门新的语言(如Solidity),但目前此类教程并不多,而且网上缺乏完善的资料。导致开发的 Dapp 可能不够友好或者存在诸多漏洞。4、效率和性能不足我们通常将交易吞吐量(TPS)看作是区块链的性能指标,它表示在固定时间能处理的交易数。在实际应用中,如果 TPS 并发太低,容易造成网络拥堵严重,大量交易排队,从而使得区块链在高并发业务的场景下无法落地,甚至连目前我们要求的简单支付都是问题。5、无法与链外信息直接交互目前智能合约还无法主动与外界数据/信息进行交互,在智能合约的触发条件取决于区块链外信息时,这些信息需先写入区块链内,但是目前区块链还无法主动完成这一个操作。而智能合约在多数场景下,往往需要与外部世界进行数据交互,典型比如去中心化保险、稳定货币及借贷平台、预测市场、去中心化旅游等等。二、如何解决这些问题?针对非技术问题,如炒作圈钱,我们相信这个寒冬没有价值的项目终将被识破,并被剔除。而我们也可以看到目前主流交易平台已经开始了清理工作,逐渐下架一些不正规的项目代币。针对认知门槛高问题,可能并不是短时间之内可以解决的,或许也可能并不需要解决,就像互联网发展至今,大家都在使用微信和支付宝支付,但是完全可以不懂第三方平台是如何与银行进行结算,以及通过什么技术实现和保障资产安全的。区块链发展壮大之后也会降低普通用户的使用门槛。对于应用的技术门槛,一方面很多项目在推进更友好的开发环境和语言,让普通开发者可以直接上手。另一方面,目前已经很多团队在做相关的技术课程,比如我们深度合作的一块链习技术社区,在做以太坊的智能合约高阶课。随着越来越多的智能合约开发者参与进来,其社区相关内容的不断完善,这个门槛也会逐渐被开发者所接受。而效率和性能问题,这个也是大家最关注的,涌现出了多种解决方案及项目,比如状态通道、Plasma、Turebit 等 Layer 2 方案,像是 Celer Network、Raiden Network 等项目,当然也有很多团队在研究和开发更好的公链,比如ThunderCore、Dfinity、Algorand 等项目。对于区块链无法直接获取链外信息的问题,解决方案就是预言机。以太坊创始人 Vitalik Buterin曾在王峰十问的采访中也肯定了预言机的作用,Vitalik 表示:“I think that one component that needs to be built that can make smart contracts work better is oracles, for providing information to smart contracts about the outside world. I know that Oraclize has been working on centralized oracles for a long time, though I am also interested in the decentralized oracle projects. ”翻译:我认为,需要建立一个可以使智能合约更好地运作的组件预言机,为智能合约提供外部世界的信息。我知道 Oraclize 长期以来一直致力于中心化的预言机,尽管我对去中心化的预言机项目也很感兴趣。引用来源:https://www.yours.org/content…三、什么是预言机?预言机就是一种单向的数字代理,可以查找和验证真实世界的数据,并以加密的方式将信息提交给智能合约。预言机就好比区块链世界中的一个第三方数据代理商。举例来说,假设现实世界中的“数据源”和区块链中的“数据接口”,是两个使用不同语言的国家,预言机就是中间的翻译官。通过预言机智能合约就可以和链外数据进行无障碍交流。在实际使用智能合约中,去中心化的预言机可以保证提供的数据无法被篡改。进一步了解预言机请参考:区块链技术科普丨什么是预言机(Oracle)四、DOS Network 为什么要做预言机?我们在 2017 年就在关注以太坊 Dapp 的开发,但是却发现区块链应用无法主动与链外信息进行数据交互。我们意识到这是阻碍区块链生态发展和去中心化应用大规模普及的一个重要因素。经常调研之后,我们发现还没有可用的去中心化预言机服务,于是开始研究更好的解决方案。在找到更好的解决方案之后,我们便启动了 DOS Network 这个项目。其中 DOS 是 Decentralized Oracle Service 的缩写。它所提供的预言机服务可以连接智能合约和链外互联网世界,同时也为区块链提供无限的且可验证的计算力。DOS Network 在性能上可支持多条链,且数据结果接近实时,同时 DOS Network 分片的网络结构设计,可以并行处理请求,达到高性能和可扩展性,帮助扩展智能合约的处理能力,是一个二层(layer 2)网络解决方案。我们的核心技术团队位于硅谷,两位创始人王琦和华思远均毕业于美国卡耐基梅隆大学,并获电子与计算机工程专业硕士学位。华思远曾任职于 Amazon、Google高级软件工程师,王琦曾任职于 Oracle 总部、Pure Storage 高级软件工程师。作为区块链技术的早期爱好者且在硅谷从事技术开发工作多年,具有丰富的技术开发经验,对区块链行业也十分了解。我们相信 DOS Network 是一个有价值且非常有意义的项目,它可以让更好的提升区块链的可用性,我们也一直在为之努力。如果你是一位开发者,欢迎来试用 DOS 的 Oracle 服务,目前我们已经在以太坊测试网发布了 alpha 版本,2 月份我们会发布 beta 版本。(请复制到浏览器打开)https://dosnetwork.github.io/…如果你是区块链爱好者,也欢迎后期作为服务节点参与到网络中,可以获得 Token 奖励。我们也会在近期公布白皮书及其他细节。大家可以通过官方渠道持续关注我们,或直接添加dosnetwork001加入社区。本文图片皆来源于网络,版权属于原作者 ...

January 9, 2019 · 1 min · jiezi

区块链与分布式超级帐本技术(Hyperledger Fabric或R3 Corda)

与分布式超级账本技术(如Hyperledger Fabric或R3 Corda)相比,以太坊区块链保持了相似性和差异性。在对区块链和分布式超级账本平台进行有根据的评估及其为企业带来的价值时,根据平台的核心功能和特征对平台进行分类是有用的。由于区块链源自密码学和数据配置的原则,某些功能可以在协调的数据库系统中复制,而其他功能仅在真正的区块链环境中可行。在本文中,我们将评估面向平台的主要企业的基本业务功能,包括以太网,Hyperledger Fabric和R3 Corda,无论是通过传统的分布式系统还是通过现代的区块链基础系统,都可以从软件获取其影响的位置以及系统的整体优化方式进行评估。图1:基础技术的划分特别是,我们将重点关注三个关键功能领域:数据协调——如何在利益相关者之间更好地分配和分配系统内的信息和信任。加密经济内部激励层——如何构建系统,以便基于经济激励来激励不同的利益相关者和用户,以确保系统的功能,例如。博弈论与机制设计。融入资产的数字商品化——系统如何融入数字商品经济。在一些名义上的特征中,这被称为代币经济。区块链的主要目标:企业希望通过这项技术实现什么目标?像以太坊这样的区块链与他们的分布式对手有类似的目标。确定企业希望使用区块链技术实现目标的目标可能是一种具有挑战性的方法,因为像1990年代的互联网一样,企业还不知道如何概念化强大工具的使用。类似地,今天已知区块链技术能够实例化各种功能,但是如何将这些功能构建到业务解决方案中需要对底层能力的进一步见解和评估。探索的三个主要轴:数据的处理和协调,可信和不可变记录以及资产的数字化。足够广泛,可以封装区块链的主要可用性,同时允许将这些功能进一步推断到业务场景中。通过讨论这三个方面,可以揭示商业实体为什么要使用该技术背后的含义。高效的信息处理和协调如果改进的分布式系统设计或数据库协调是协议或平台的唯一目的,那么区块链可能不一定是所需要的。区块链平台传统上促进了更好的数据协调和分布式共识机制的概念,其中数据通过技术平台得到促进和传递。虽然有用,但通过更好地协调中央数据库或改进的分布式系统设计,可以获得这些所需功能特征的重要部分。在此调查中,有必要确定平台和协议尝试优化现有数据协调功能与实施新区块链功能的程度。区块链的设计不仅仅是高级数据协调。产品和交易的不可变/可信记录关于我们为什么需要区块链的原始论文围绕着数字化信任的概念。ConsenSys的Andrew Keys推出的一个主题是“随着互联网导致信息数字化,区块链导致信任和协议的数字化。”这篇有意义的论文体现了区块链希望实现的精神,同时也为其铺平了道路。另一条路。附加变量是值的数字化。当值附加到系统中实现的信任时,某些对齐结构和激励机制将影响和激励系统内的正确行为,从而形成一个强大的平台。通常情况下,在设计系统时,不可变性与信任同义使用,即因为系统是不可变的,所以可信的是坏事不会逍遥法外。虽然在我们的平台协议评估中,重要的是还要评估可信系统如何实施的机制,以确保可以有益于平台用户的业务模型(通过加密经济学进一步探索)。资产数字化商品和资产的数字化被认为是大多数区块链或分布式账本平台的主要目标。如果企业正在寻找资产的数字化,则分布式分类帐或数据库协调能够提供一些功能,但应充分考虑这些数字商品的可访问性。因为协调数据库基本上是通过传统软件范例集中运行或分布在交易对手的一个或多个子组之间,所以数字化的级别可以基于数字化平台提供的自由度来限制。虽然数字化商品的概念听起来像一个简单的过程,但不同的激励动态和围绕商品如房地产,人类关注甚至电力等数字化的经济推理需要考虑哪种类型的平台将对数字化负责。供应商平台确实展示了“供应商锁定”的程度,并且在各种情况下依赖于集中管理的平台。如果依赖于封闭的专有系统,并且这些资产扩散到数字生态系统或市场,它们与经济激励层的相互作用水平相当有限,那么通过分布式分类帐系统也可以使用诸如标题系统和供应链等记录和注册表。如果基于封闭的轨道将会严重发育不良。充分利用开放市场能够提供的各种方面的自由市场系统对于在不断发展的数字生态系统中促进真正的数字商品是必要的。评估数据库协调特征数据库协调:特征虽然已经在不变性,安全性,可伸缩性,可管理性和性能等特性方面对这些平台的功能进行了深入分析,但通过了解构建体系结构的基础,可以确定更多内容。已经发明并实现了许多工具,用于在分布式系统内进行适当的数据协调。一个例子就是强调像Hadoop这样的工具以及这个生态系统中的各种集合,包括Spark,Hive和Zookeeper。对这些产品的依赖表明了分布式系统工具和协议的高度集成。进一步的相似之处可以在诸如Tendermint之类的协议中显示,这是一种BPFT共识引擎,其设计具有与Apache Zookeeper等工具类似的功能。在内部,还有一些event sourcing databases的研究,可以复制协调数据共享系统所需的几个功能。通过评估Apache Kafka等工具以及数据流服务如何在企业环境中实现显着的吞吐量水平,我们可以根据对这些数据库协调和优化的不同依赖程度划分区块链和分布式分类帐之间的功能差异。基础概念方面的工具。包括Plasma在内的以太坊的实现正在利用MapReduce等工具在UTXO和基于帐户的模型之上增强某些映射功能,同时还将组件简化为merkle证明,尽管重要的是要认识到协议的基础层仍然依赖于以太坊作为根区块链。通过分解这些细节,可以获得有关如何最好地评估这些软件平台的技术特征的进一步见解。数据协调:平台比较IBM Fabric通过深入研究Fabric架构,可以确定该平台已经创建了一个复杂的开发环境,专注于基于软件架构的详细配置实现卓越的吞吐量,以在分布式系统环境中实现最佳性能。客户端和分布式签署对等节点网络之间的链代码的移动以及交易机制和满足认可策略的收据的转移在封闭系统中是有效的,而在私有信道内传播交易的gossip(八卦)协议允许协调大数据集。虽然基础设施稳健且能力强,但应该考虑如何设计架构以允许多边协调结构的思考过程,其中最终可能存在难以管理的网络中涉及的通道因素。图2:Hyperledger Fabric架构此图演示了Fabric的一些体系结构配置,以及如何将组件组织到专为高级信息处理和最大事务吞吐量而设计的系统中。主要思想是渠道为在平台内移动交易提供了机会。 在查看体系结构时,订购服务节点(OSN)的功能用于记录Apache Kafka订购服务中的交易。在数据流生态系统中,Kafka是一个功能强大的工具,具有将各种形式的事务附加到单独的Kafka集群并最终分区的功能。在此设置中,数据能够跨群集分布,以形成分布式存储平台,该平台可以记录在其键/上下文中“状态”的Fabric定义内有时称为“块”或blob的数据结构/值存储配置。在该软件框架内承认的概念是该生态系统中的所有参与者和数据结构都是本机的,因为它们主要与该软件生态系统中的其他用户一起运行。图3:Apache Kafka资料来源:Apache KafkaFabric实际上采用了部署类型的子结构来部署某些散列链接数据存储,但应该认识到散列的配置不遵循从比特币或以太坊派生的区块链系统附属的原始架构设计。虽然数据blob被批处理并且经历传递事件以最终创建交易的哈希链接,但是必须理解该过程不一定将数据转换为系统状态的修改。相反,这些块的配置方式是信息存储在具有不同哈希实例的数据库类型结构中。在Fabric生态系统中,交付事件称为块,而链代码通过部署事件最终保护订购服务结构的链分区内的数据。该系统的数据结构和模块的配置能够允许分布式数据库体系结构所期望的事务吞吐量,尽管应该承认,资产代码协调仍然是一个尚未完全解决的挑战作为资产和价值的Fabric生态系统不一定具有可在分类帐内协调的数字表示。R3 CordaR3 Corda建立在一个不要求区块链的环境之上,而是一个分布式的数据库,利用各种形式的结构重构来构建一个主要由银行和其他机构用于其流程的系统。该平台大量借用比特币交易中使用的UTXO模型,其中状态由一系列输入和输出定义,输入的变化重新配置可以决定输出的状态。R3 Corda架构框架依赖于节点结构,该结构依赖于称为公证人的子模块,这些子模块有助于维护网络的有效性,类似于抽象共识功能的其他平台中的验证器结构。节点附带有关系数据库,这些数据库附加在数据结构中,允许使用SQL进行查询。交易通信在称为流的子协议中受到限制。这些流程与IBM Fabric中的通道体系结构相当,其中只有交易的各方能够访问信息。类经历转换,导致称为光纤或协同例程的状态机。该体系结构依赖于与子流通信的流以及与在平台范围内具有预定义功能的流库交互。此外,Corda中还有一个自包含的身份层,允许在整个网络中进行不同程度的访问控制。虽然R3 Corda公开声明它不打算成为区块链,但应该考虑到将分布式数据库的概念重新配置到去中心化数据库确实非常依赖于传统的数据库系统。虽然系统围绕新颖的数据结构和分布式系统如何组织的不同组成进行架构,但该平台确实考虑了数据分配,并且确实找到了各种方法来优化数据分发系统的功能。需要记住的一点是,由于系统仅限于特定体系结构范围内的数据协调的某些方面,因此,由于未对原始设计实施模块化和互操作性,因此牺牲了与实际区块链系统的集成。图4:R3 Corda工作流程图详细信息:Corda中的交易工作流以及如何通过系统移动输入状态和输出状态以及如何将文档附加到工作流过程中。以太坊以太坊生态系统由私人区块链和公共区块链生态系统组合而成。公共链没有任何接近数据协调上下文中描述的吞吐量和数据处理能力,因此不应基于这些能力进行评估。在评估以太坊的这一方面时,最有意义的是合成以太坊私有实例的网络拓扑的不同细微差别。以太坊黄皮书坚定地规定了关于构成以太坊的一系列规范以及代码库的技术细节。由于严格遵守该协议的蓝图,以太坊以及联盟实施的forks确实类似于构建该技术的原始基板。实际上,无论是在工作量证明,股权证明还是资产证明中,相同的规范都是连续的,因为协议被认为是相同的以太坊虚拟机(EVM)规范的后代。修改的体系结构仍与原始EVM明确校准。Quorum等平台的主要变化包括改变共识机制,修改全球根状态以适应私人和公共状态,改变Patricia Merkle tries 状态以及处理私人交易的其他模块。该架构允许该软件维护原始以太坊配置的沿袭和数据结构,同时通过更改提供增加的交易吞吐量。除了Quorum提供的改进的数据交易优化之外,通过Plasma,Truebit和Cosmos等工具协调和集成公共以太坊环境的能力为协议提供了额外的可扩展性。通过对像Plasma这样的工具的技术评估以及在Casper中获得共识的格式,很明显,MapReduce和Abstract Rewrite Systems等数据库管理工具将在以太坊中实现。在Plasma中,MapReduce是组装基于帐户的系统和多线设置的位图-UTXO承诺结构的协调的不可或缺的一部分。通过防欺诈机制设计和保真债券激励结构的组合,使用根链,等离子链和子链之间的相互作用的协调交易处理范例有助于满足块扣除和质量提取表面之间的动态。它还允许使用来自Casper或Truebit等系统的机制来填充进一步的加密经济结构,以便根据空间中普遍存在的数据可用性问题来镜像擦除编码中使用的概念。对于多链体系结构,以太坊将能够将分布式数据库系统的数据库协调和吞吐量功能与实际区块链的公共链兼容功能相结合。数据库协调:结论关于数据库协调能力范围的可行结论将是IBM拥有卓越的数据库管理工具集,因为依赖于传统数据库和分布式系统软件架构,基于整体单片设计和构建Fabric的大量资源密集型流程。R3 Corda还在进一步定义其功能,同时通过比特币协议私密重新配置细微差别,为银行和金融机构提供多种协调服务。Ethereum虽然是为公共链兼容性而设计的,但它没有IBM Fabric的原始数据库处理功能,尽管它在Fabric可用的企业用例的可伸缩性环境中确实具有某些协调原理图。以太坊和互补客户的私人实例可以作为构建更大系统的架构构建块,基于模块化设计,坚持相对基于unix的理念。与以太坊相关的代码库旨在与Fabric等数据库平台的交易吞吐量功能相媲美,同时允许Corda和Fabric中不存在的功能,但也可以跨平台探索互补关系。主要的区分因素可以从后续因素的评估中进一步阐明。区块链平台的加密经济配置软件平台内部的密码经济子系统需要各种机制设计和博弈论配置,以激励参与者以最佳方式行事,既有利于自身利益,又有利于生态系统。将区块链生态系统与分布式分类账设计的数据库系统区分开来的核心原则是能够将机制设计用作经济激励层,确保信任和合作的正确分配,使系统的行为方式有利于实现分散的共识。用户以及安全。依赖于“反向博弈论”设计的这些系统的主要目标是在子系统中创建主导策略,从而产生激励的均衡结构,进一步增强整个系统的整体完整性。密码经济机制设计的例子等离子和真实比特Plasma的设计旨在为以太坊网络带来可扩展性和多链功能。通过提供其上多个以太坊谱系的区块链可以相互通信的催化剂,Plasma充当私有区块链和公共区块链网络之间的可行桥梁。从进一步分析可以看出,Plasma为以太坊网络提供了可扩展性和可用性。虽然要了解等离子体的有效性,但了解等离子体设计的机制非常重要。通过所谓的欺诈证据实现了大量的互操作性。通过配置区块链,使得派生的子区块链(或子区块链)仍然可以基于MapReduce函数的计算可靠地验证事务,可以通过最小化的信任来实现可伸缩性。围绕等离子体设计了一种机制,以便在发现故障链时允许所谓的质量存在。这些与错误操作有关的情况与数据可用性的不一致和阻止预扣攻击有关。通过允许通过交替配置相互关联的链来惩罚邪恶活动的机制,生态系统希望实例化实体如何相互作用的内聚平衡。等离子体具有相当大的影响力,来自一个名为Truebit的密集加密经济激励结构的平台,旨在提高以太坊网络的离链计算能力。通过围绕验证游戏设计Truebit系统,其中整体共识机制的解决方案可以被验证者挑战,如果他们识别出一个邪恶的交易对手则获得奖励,创建系统的内部加密经济“检查和平衡”以激励占主导地位行为公平的策略。由于Plasma通过TrueBit的影响专注于创建多链互操作性网络,因此系统的内部实施对于实现信息和共识保真度至关重要。如下图所示,涉及Truebit并衍生到Plasma中的加密经济游戏包括求解器和挑战者之间的平衡相互作用,以验证最终在链上验证的计算的正确性。挑战者被激励不断挑战,因为强制错误可以保证如果正确解决支付。图5:加密经济设计以太坊Casper股权证明机制密码经济激励层的一个例子也可以在以太坊通过Casper的实现过渡到股权证明共识机制的证据中看到。虽然工作量证明有自己的内化游戏理论激励结构,以阻止参与者征用网络,但是向股权证明的过渡甚至还有进一步的内部结构,以阻止参与者在遇到货币时模仿或试图创建区块链的替代实例。staking协议创建了一个拜占庭容错环境,其中Ether将被绑定到共识机制中。这意味着个人将受到忠诚的约束,以在系统内表现得光荣。如果攻击者计划在共识机制中模仿或试图控制,那么与“slasher算法”相关的各种协议将破坏以太网持有者或攻击者的联系,因此惩罚他们的邪恶行为。在惩罚背后的机制设计中,被破坏的以太网的数量始终被编程为与攻击者希望获得的数量成比例,其中所达到的均衡是攻击者首先不想破坏系统的地方。Cosmos和TendermintCosmos还在建立一个依赖于Tendermint共识机制的生态系统,该机制在很大程度上依赖于拜占庭容错算法。该平台依赖于与比特币网络中的矿工具有类似角色的验证器。验证器具有称为Atoms的标记代币,用于通过依赖于绑定验证器生成的信任的股权证明机制来保护网络。生态系统中的参与者之间的相互作用也表示游戏理论结构,其中如果发现违反协议,验证者可能丢失其代币或授权给他们的代币。由于该系统内利益相关者的这种保税存款设计,共识机制允许一种保护网络的激励机制。此安全设计允许应用程序区块链接口(ABCI),区块链间通信协议(IBC)以及Cosmos集线器和区域之间的不同交互的正常运行。R3 Corda和IBM Fabric需要注意的一个重要注意事项是,R3 Corda和Hyperledger Fabric在其软件架构中没有实例化这些加密经济激励层。由于软件体系结构是基于分布式数据库聚焦范例进行基础设计的,因此它们最初并非设计用于在整个框架内结合本机加密货币层。由于软件设计的这种固有差异,它们尚未经过校准,无法参与多链生态系统,在这些生态系统中存在与多个区块链的互操作性和协调性。由于系统的结构考虑了最大吞吐量,因此基于这些系统的初始构建,忽略了包含公共区块链主网的区块链的可互操作网络拓扑的架构布局。为什么需要加密经济机制设计?人们可能会问为什么在软件设计中需要加密经济基础设施层。这种范式创造的是一个新的信任和不变性层,可以存在于计算环境中而不依赖于集中式实体。几十年来,我们一直在特定的客户端服务器和数据库架构中构建软件。像IBM,Intel和Oracle这样的公司已经完善了这个模型以及在初始创建之后创建的系统和子系统,这些模型仍然在分布式系统架构以及新标记的分布式分类帐系统中使用。虽然这些系统仍然集中在各个方面,无论是通过中央实体还是类似卡特尔的财团结构,其中激励措施是基于对集中实体的固有依赖而不是真正的激励结构来确保系统的正常运行。图6:客户端服务器模型去中心化系统允许在软件环境中实现某些目标的可行替代途径。在这种交换中突出显示的主要权衡是信任与执行。因为大型集中式系统更受信任,所以它被认为能够更好地执行。虽然区块链系统希望灌输的是系统的特征,在这种系统中,信任和价值可以在不依赖大型集中化实体的情况下重新分配。在系统设计的某些方面支持的一个想法是,为了优化系统,还必须对子系统进行子优化。这意味着必须协调和架构系统的协调,以便内部子系统在整个更大的生态系统中也具有利益或激励机制,以进一步实现合作目标。通过为整体环境的优化创建加密经济博弈理论方法,可以创建计算机科学和经济模型的汇合,从而允许创建可以在数字经济中设想的新软件架构。基于对数字经济的这种愿景,应该认识到,使用可以互操作的私有区块链和公共区块链的组合将创建一个可行的数字生态系统,在这个生态系统中可以出现各种商业和商业关系层,并在在传统技术配置中是可能的。融入区块链代币经济出于本次调查的目的,有必要定义标记化的概念。该概念借鉴了企业或实体能够根据我们生态系统中目前存在的某些数字标准创建各种形式的资产,商品和服务的可替代或非可替代表示的概念。虽然代币经济仍在发展,但重要的是区分第一波产品最初会有各种各样的失败和缺陷需要时间和迭代来完善。即使资产,金融产品,能源和数字注意力的标记化都是可行的商业模式,它们实施的确切动态需要额外的功能和访问层,只能随着时间的推移而改进。成功的代币经济将是由游戏理论机制设计和区块链创新中的重大发展和发现所创造的结果。正如Josh Stark关于加密经济学的文章所述,表现出最强可用性标志的标记是否构成了整体业务的经济学和博弈论设计中的必要组成部分。如果企业可以将其生态系统的各个方面数字化或标记化,那么可以创建的产品线将以指数方式扩展,超出我们传统的交换实物,金融资产,商品或技术服务的方式。通过创建标记化资产可以实现的数字媒体,重要的发展可以从新的生态系统发展而来。在观察区块链工具的生态系统时,很明显,以太坊实际上是可以建立代币经济的基础。如果代币经济模型能够结合私有区块链,可扩展性解决方案和ZK-Snarks等隐私工具的功能,数字资产的整体标记化将使我们的经济模型受限于当前的能力,因为组织可行性。实现区块链的业务目标为了实现区块链的上述业务目标,我们必须评估需要服务的各种途径。在概述详细说明所述模型的功能的图表时,以太坊能够为分布式数据库协调方案以及附加功能提供服务,而R3 Corda和IBM Fabric尚未选择触及这些功能层。在业务用例的背景下,我们覆盖了在现实世界业务场景之上讨论的不同功能,以更好地理解平台的功能。图7:功能摘要有效分配信息从功能上讲,从分布式系统的数据库协调和利用的角度来看,产品类似地匹配。事实上,R3 Corda,IBM Fabric和以太坊的企业版本具有分布式信息分配功能,可以通过不同的访问控制层和联盟的治理配置来促进信息的分配。虽然每个平台在其软件架构配置方面都不同,但每个平台都能够在有效的信息分配和协调上执行必要的性能。可信的不可变信息在大量这些技术的背景下,不变性在某种程度上被用作信任的同义概念。在评估不变性特征时,必须理解在利用基于Apache的数据流工具(如Kafka)的生态系统中,存在允许对数据进行读/写访问的固有功能。因此,由于系统设计中的一些选择,IBM Fabric的不变性方面有些受限。对于R3 Corda的基于UTXO模型的系统,不变性方面在系统的整体范围内保持不同。由于他们系统的整体分布式分类帐设计,他们已经建立了可以在整个平台上展示的某些信任方面。在以太坊上下文中建立的信任和不变性层都是在Patricia Merkle Tries的公共区块链派生状态根的子协议中概念化的。由于生态系统内核心软件范例的这种保留以及与公共链的可行连接,以太坊区块链和以太坊的相关推导能够充分证实不变性。随着资产开始数字化,从这种不变性获得的信任最终可以附加到新的价值体系。资产数字化应该认识到,IBM Fabric实际上能够在名义意义上创建数字资产,因为资产的数字化是从产品的注册表导出为数字格式的。虽然Fabric上资产的数字化会导致资产只能在使用Fabric的系统上运行。这相当于如果创建电子邮件客户端只能与使用完全相同的电子邮件客户端的人来回发送电子邮件,这与我们当前世界中存在的大量电子邮件客户端可以一起互操作的情况不同。R3 Corda具有类似的不一致性,因为R3平台的用户将被限制在其整体环境中与R3之外的其他平台进行交互,从而造成一些供应商锁定。因为R3 Corda主要关注银行客户,所以有可能有一个虽然应该注意平台的用户将仅限于使用R3 Corda的机构的银行业务关系,并且无法与不使用供应商平台的交易对手的生态系统无缝互操作。因为以太坊意味着充当类似于Web服务中的HTTP或TCP/IP的底层协议,所以对于只有一个以太坊应用程序的构建者,没有“供应商锁定”的概念。可以通过以太坊区块链的不同方面建立的信任允许全球资产的数字化,这种资产可以在新的经济体系内发生,而不像现有的那样。如果回头参考电子邮件示例,可以将以太坊协议视为与IMAP或POP3类似,作为访问电子邮件的通用协议。以太坊和以太坊派生的协议能够充当区块链基础设施,公司可以在此基础设施上构建数字资产。类似于每个公司在90年代后期使用HTML为网页搭建网站创建网站的方式,每家公司都能够使用以太网智能合约为其服务和产品创建数字经济,这些合约可以创建代币。可通过更广泛的网络访问。前方的路为了拥有足够强大的平台,可以与公共市场互动,系统必须能够满足业务需求,从而实现数据的有效处理,额外的信任分配层以及在发展中的数字经济中代表资产的能力。 很明显,所有三个平台都旨在通过技术进步和技术配置的不同途径实现类似的目标。在未来的道路上,我们必须考虑在这个发展中的生态系统中我们看到经济商业模式在哪里发展,显然基于以太坊的平台在真正融入数字经济方面具有优势,尽管在某些数据交易中存在明显的弱点IBM Fabric和R3 Corda可以擅长的吞吐量功能。由于不同的区块链和分布式账本平台被迭代并超越了我们当前技术时代精神所存在的能力,围绕哪个平台进行构建的决策将严重依赖于方向在我们的生态系统中的用例,我看到不同类型的用例相互分层。本文档的目的并不是说一个平台总体上比另一个平台更好,而是旨在规定这些平台本质上是彼此不同的。以太坊具有某些功能,分布式分类账(如Fabric和Corda)没有,而Fabric和Corda具有以太网目前无法达到相同程度的性能。为了真正实现我们现有系统所需的交互和可扩展性水平,必须在构建和设计协议时考虑所有交互,类似于首次设计互联网的方式。以太坊作为一种协议,能够充当基础技术堆栈,为广泛的生态系统提供服务,涵盖经济环境中的必要因素,但请记住,该平台目前尚未完成,也可能受益于某些固有的功能在DLT同行中。虽然前面的道路将包括尚未完善的技术,但应该检查协议是否最终会复制我们希望在下一代互联网中看到的功能程度,有时最明显的解决方案不是只关注一项技术。======================================================================分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。汇智网原创翻译,转载请标明出处。这里是区块链与分布式超级帐本技术(Hyperledger Fabric或R3 Corda)

January 8, 2019 · 1 min · jiezi

从2018年以太坊统计数据看区块链发展趋势

今年6月,我们发布了“以太坊网络状态”,重点介绍了整个网络的一些关键数据和统计数据。六个月后,即将在2018年结束时,我们处于长期“加密货币冬天”的尾声,2017年末至今的市场波动已经引起了区块链行业的普遍关注。然而,仔细研究这些数字可以发现一种强大的技术,它充斥着项目和开发人员,并且在新的一年里有着坚定的上升发展轨迹。交易活动迄今为止,以太坊网络共处理了超过3.53亿笔交易。自6月1日以来,这一交易量增加了超过1亿笔(占总交易量的2.4亿笔)。1月4日,该网络在24小时内处理了130万笔交易,这是有史以来最多的一天。自6月1日起,平均每日交易量约为610,000来源。在以太坊的价值交易中潜水更多,我们看到在2017年末和2018年初的“繁荣”之后网络的相对稳定性。从2018年3月开始,网络稳定在每月交易的约5000万ETH,并且名义上有波动从那以后每个月。自第三季度以来,每月的交易数量略有下降,从7月的每月约2000万减少到11月的每月约1600万。每个交易的平均ETH在同一时间段内有所增加,然而,从11月ETH/交易的2倍到ETH/交易的不到2倍[图1]。图1.以太坊交易数据2017年12月——2018年11月。Alethio数据科学。以太坊区块链上有近4900万个唯一地址。在一年内,这比2017年12月3日的约13,000,000个地址增加了近4倍。在六个月内,增加了1.5倍,高于2018年6月的约3500万个地址[图2]。每个地址的平均ETH持有约为2.17ETH。如果没有前10个地址,每个地址的平均ETH保持为1.87ETH。没有前50个地址,平均持有量为1.59ETH 来源。图2.以太坊唯一地址增长。Etherscan。在2018年,平均使用新创建的地址为35.45天,然后才“失效”。今年的使用时间比2017年的平均11.25天增加了3倍。除了价值交易之外,智能合约在以太坊区块链上的部署也在稳步增加。自6月以来,创造了约20万份智能合约,费用已经增长,10月超过100万,并在11月达到近150万部署智能合约[图3]。自2017年底以来,智能合约的成功调用数量一直保持在每天120万。图3.智能合约创建2018。Alethio数据科学。毫无疑问,以太坊区块链仍然是现有最强大的智能合约平台。在按市值计算的前100个代币中,96%是以太坊建立的。在前1000个代币中,89%是由以太坊构建的来源。用户和开发人员活动以太坊的独特功能之一是能够在该技术之上编程和构建去中心化应用程序。Dapps state列出了区块链生态系统中的2,286个实时dApp,10月份刚刚超过2,000个。这些现场dApp中有2,175个基于以太坊。对于许多用户来说,访问dApp最容易通过移动钱包完成,例如MetaMask,这是最广泛使用的Web3浏览器扩展。MetaMask在4月份的终身下载量达到100万次,此后又增加了约200,000次。开发商是以太坊生态系统持续增长背后的推动力。虽然市场波动,他们在继续构建解决方案时仍然致力于技术及其应用。Truffle Framework是一套工具,旨在让开发人员尽可能舒适地从创意到dapp。仅在Github上就有26,000种Truffle产品。Truffle Framework的第一个产品,恰当地命名为Truffle,是一个开发环境和测试框架,它有助于开发人员在以太坊区块链上创建dapps的能力。Truffle最近的下载量超过了100万,自2015年5月发布以来,终身下载量为1,168,595次。平均而言,Truffle每月下载100,000次。Ganache,Truffle Framework的第二个产品,是用于部署,开发应用程序和运行测试的以太坊开发的个人区块链。自2017年10月发布以来,Ganache已被下载近600,000次。11月,它被下载了86,000次,并且没有显示出任何时候会放缓的迹象[图4-6]。图4.Truffle每月下载量。Truffle Framework。图5.Ganache每月下载量。Truffle Framework。图6.Truffle Suite开发人员的采用。Truffle Framework。Loom Network在以太坊上开发并推出了第2层平台,允许游戏和社交dApp扩展,同时仍然依赖于以太坊的核心安全和去中心化。该团队发布了CryptoZombies ,这是一款实时应用,可让任何人学习在以太坊上编写智能合约。CryptoZombies拥有330,000名用户,比2018年6月增加了1.5倍。看起来开发人员留在这里,而且还有更多的开发人员在路上。矿工和网络活动Ethernodes报告了超过11,000个与以太坊区块链交互的活动节点。这些节点分布在六大洲,展示了网络的地理多样性。在2018年,矿工奖励保持相当稳定,平均每月620,000ETH——1月(640k)和2月(572k)2018(图7)的离群值最大。图7.矿工奖励2018.Alethio数据科学。生态系统采用除了开发商和矿工之外,人们对以太坊的兴趣正在增长。Reddit的r/ethereum社区增长了一倍以上,从2017年12月初的17.6万增加到2018年12月初的418,000来源。赏金网络是一个允许任何人提交和完成任务的平台,从撰写请求和创意练习到研究和技术任务。2018年,网络上的交易数量激增,从1月份的不到50个增长到10月份的顶峰,超过1,500个。值得注意的是,每月交易的唯一地址数量在同一时间段内增加,10月份达到350多个,这表明与平台交互的人数越来越多。图8.Bounties每月的网络交易(左)和每月唯一交易的地址(右)。随着2017年底和2018年初的加密热潮,随着市场疲软,ICO的下滑被预示着,监管机构介入。然而,ICO市场的放缓并没有阻碍企业,研究和政府采用区块链。技术和研究其可能性。特别是,ICO资金的减少为主要参与者的传统风险投资打开了大门。2017年,风险投资公司向区块链公司投资10亿美元,中位投资额为150万美元。在2018年,风险投资公司的投资仅为40亿美元,中位投资额为250万美元[图10-11]。大型风险投资公司Andreessen Horowitz表示,它特别相信区块链和以太坊。该公司去年夏天筹集了3亿美元,这是它首次专注于加密货币来源的基金,最近在MakerDAO上投资了1500万美元,MakerDAO基于以太坊来源。在9月份对Breaker的采访中,Andreessen Horowitz的普通合伙人克里斯·迪克森(Chris Dixon)广泛谈到了他对以太坊的热情,称其为“技术界的聚集点”。图10.2013-2018区块链的资本投资。Diar.co。图11.2013-2018区块链中位数资本投资。Diar.co。9月,世界上最大的十五家银行和商品公司宣布成立komgo,以便在以太坊上建立一个基于区块链的全球贸易融资平台。亚利桑那州和俄亥俄州都通过法律,合法地承认在区块链平台上存储和交易的数据。Signature Bank宣布推出一个基于许可的以太坊区块链建立的支付平台,允许人们以ERC-20代币的形式发送近乎即时的支付。佳士得最近在获得许可的以太坊区块链的单一房地产拍卖中录得3.17亿美元的销售额。索尼已经审查并批准了一款名为Plague Hunters for PlayStation的基于以太坊的游戏。该游戏将利用以太坊区块链上的不可替换的代币,计划于2019年第一季度发布。以太坊的采用正在加速。企业,私人投资公司,政府,公共机构,艺术品和娱乐公司只是一个开始。即使面对波动的市场和媒体对价格的关注,公司也会认识到区块链的效用——特别是以太坊的可编程性——在他们的商业模式中并寻求探索其应用。生态系统所有这些信息意味着什么?以太坊网络很强大。它是多样化的,它正在增长,它正受到全世界个人和业界人士的关注。在全球范围内,以太坊的用例有望改善困扰系统,结构和组织的当今许多问题。例如,我们ConsenSys致力于去中心化未来,以及以太坊帮助我们实现目标的能力。======================================================================分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。汇智网原创翻译,转载请标明出处。这里是从2018年以太坊统计数据看区块链发展趋势

January 8, 2019 · 1 min · jiezi

如何通过Geth、Node.js和UNIX/PHP访问以太坊节点

本文旨在说明通过Geth、Node.js如何访问以太坊节点和UNIX下PHP如何访问以太坊节点。说明如何通过RPC使用此(A)以太坊节点对于以太坊主网络使用RPC url:http://85.214.51.53:8545对于Ropsten测试网络使用RPC url:http://85.214.51.53:8546通过本地系统上的“geth”访问节点:1.确保你的本地IP已在你的用户配置文件中注册。使用RPC服务时,不会阻止从此IP访问。2.在本地系统上安装geth二进制文件约30MB,geth二进制文件包。3.查找geth目录位置4.使用命令./geth attach rpc:http://85.214.51.53:8545连接并启动JavaScript环境,参考文档。5.控制台正在启动,你会看到>作为输入提示符。6.写eth.getBlock(10000)并获取块信息作为结果,参考文档。你的系统在几分钟内运行,无需安装已经500GB以上的以太坊区块链!故障排除:安装正确的geth二进制文件。验证geth在本地系统上是否可用。检查用户配置文件中的IP。确认没有个人防火墙阻止你的发送出去请求。尝试Ropsten测试网络:http://85.214.51.53:8545适用于主网络。http://85.214.51.53:8546适用于Ropsten测试网络。通过本地系统或服务器上的node.js访问节点1.这将返回一个webserver响应并输出一个html文件。2.在node.js系统中通过NPM或其他方式安装web3。3.将服务器文件指向app.js。这将为你带来一个帐户余额(钱包)的输出。文件:app.jsconst http = require(‘http’);const walletAddress = ‘0xDED5f23C157aCef931946D9A695cAc3eF1AaaA8D’;var Web3 = require(‘web3’);var web3 = new Web3();web3.setProvider(new web3.providers.HttpProvider(‘http://85.214.51.53:8545’));var balance = web3.eth.getBalance(‘0xDED5f23C157aCef931946D9A695cAc3eF1AaaA8D’);http.createServer(function(request, response) { response.writeHead(200, {‘Content-Type’: ’text/html’}); response.end("<!DOCTYPE html>\n" + “<html lang="en">\n” + “<head>\n” + " <meta charset="UTF-8">\n" + " <title>ethernode.biz</title>\n" + “</head>\n” + “<body>\n” + “<p>ethernode.biz</p>” + “<center>\n” + “</center>\n " + “<p> Ethereum balance : " + balance +"</p>\n” + “</body>\n” + “</html>\n”);}).listen(process.env.PORT);在Unix系统上通过PHP访问节点1.确保你的geth通过RPC正常工作。2.在geth_rpc_getblock.js下的Unix系统上保存以下shell脚本。确保你具有执行它的正确权限。3.在脚本中调整geth命令的路径。4.检查命令./geth_rpc_getblock.js是否会带来一些正确的输出。它应返回类似Data::QBIT=27867000000;WETH=0;ETH=0.002650772的内容。5.将下面保存在同一目录下的geth_access.phpPHP脚本。6.将$shellstring中的路径调整为脚本文件位置。7.php脚本应该回显脚本的输出。Data::QBIT=27867000000;WETH=0;ETH=0.002650772。你说对了!请记住,从长远来看,使用php shell_exec命令访问geth并不是很省事。文件:geth_rpc_getblock.js#!/bin/sh# ——————————————————————————# Qubitica.net# ——————————————————————————# Don’t define PARAM to use the standard IPC comms# Use below to connect to RPC portPARAM=“rpc:http://85.214.51.53:8545”/var/www/vhosts/ethernode.info/php/geth attach $PARAM << EOF | grep “Data:” | sed “s/Data: //“var erc20ABI = [{“constant”:true,“inputs”:[],“name”:“name”,“outputs”:[{“name”:””,“type”:“string”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:false,“inputs”:[{“name”:"_spender”,“type”:“address”},{“name”:"_value",“type”:“uint256”}],“name”:“approve”,“outputs”:[{“name”:“success”,“type”:“bool”}],“payable”:false,“stateMutability”:“nonpayable”,“type”:“function”},{“constant”:true,“inputs”:[],“name”:“totalSupply”,“outputs”:[{“name”:"",“type”:“uint256”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:false,“inputs”:[{“name”:"_from",“type”:“address”},{“name”:"_to",“type”:“address”},{“name”:"_value",“type”:“uint256”}],“name”:“transferFrom”,“outputs”:[{“name”:“success”,“type”:“bool”}],“payable”:false,“stateMutability”:“nonpayable”,“type”:“function”},{“constant”:true,“inputs”:[],“name”:“decimals”,“outputs”:[{“name”:"",“type”:“uint8”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:false,“inputs”:[{“name”:"_value",“type”:“uint256”}],“name”:“burn”,“outputs”:[{“name”:“success”,“type”:“bool”}],“payable”:false,“stateMutability”:“nonpayable”,“type”:“function”},{“constant”:true,“inputs”:[{“name”:"",“type”:“address”}],“name”:“balanceOf”,“outputs”:[{“name”:"",“type”:“uint256”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:false,“inputs”:[{“name”:"_from",“type”:“address”},{“name”:"_value",“type”:“uint256”}],“name”:“burnFrom”,“outputs”:[{“name”:“success”,“type”:“bool”}],“payable”:false,“stateMutability”:“nonpayable”,“type”:“function”},{“constant”:true,“inputs”:[],“name”:“symbol”,“outputs”:[{“name”:"",“type”:“string”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“constant”:false,“inputs”:[{“name”:"_to",“type”:“address”},{“name”:"_value",“type”:“uint256”}],“name”:“transfer”,“outputs”:[],“payable”:false,“stateMutability”:“nonpayable”,“type”:“function”},{“constant”:false,“inputs”:[{“name”:"_spender",“type”:“address”},{“name”:"_value",“type”:“uint256”},{“name”:"_extraData",“type”:“bytes”}],“name”:“approveAndCall”,“outputs”:[{“name”:“success”,“type”:“bool”}],“payable”:false,“stateMutability”:“nonpayable”,“type”:“function”},{“constant”:true,“inputs”:[{“name”:"",“type”:“address”},{“name”:"",“type”:“address”}],“name”:“allowance”,“outputs”:[{“name”:"",“type”:“uint256”}],“payable”:false,“stateMutability”:“view”,“type”:“function”},{“inputs”:[],“payable”:false,“stateMutability”:“nonpayable”,“type”:“constructor”},{“anonymous”:false,“inputs”:[{“indexed”:true,“name”:“from”,“type”:“address”},{“indexed”:true,“name”:“to”,“type”:“address”},{“indexed”:false,“name”:“value”,“type”:“uint256”}],“name”:“Transfer”,“type”:“event”},{“anonymous”:false,“inputs”:[{“indexed”:true,“name”:“from”,“type”:“address”},{“indexed”:false,“name”:“value”,“type”:“uint256”}],“name”:“Burn”,“type”:“event”}];//var QBITWalletAddress = “$1”; You may pass a parameter from the php call into this $1.var QBITContractAddress1 = “0xCb5ea3c190d8f82DEADF7ce5Af855dDbf33e3962”;var QBITContractAddress2 = “0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2”;var QBITWalletAddress = “0x842286ea00502f8e5b1ea40d17ebc4b70becda08”;var QBITContract1= web3.eth.contract(erc20ABI).at(QBITContractAddress1);var QBITContract2= web3.eth.contract(erc20ABI).at(QBITContractAddress2);var acctBal = web3.fromWei(eth.getBalance(QBITWalletAddress), “ether”);totalBal += parseFloat(acctBal);var QBITbalanceOf = QBITContract1.balanceOf(QBITWalletAddress);var WETHbalanceOf = QBITContract2.balanceOf(QBITWalletAddress);console.log(“Data:"+":QBIT="+ QBITbalanceOf +";WETH="+ WETHbalanceOf +";ETH="+ acctBal);exit;<<<<< New FilePHP脚本:geth_access.php<?php$shellstring= “./geth_rpc_getblock.js”;$output=shell_exec($shellstring);echo “$output”;?>故障排除shell脚本对Windows换行符很敏感或返回\n\lf检查权限======================================================================分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。汇智网原创翻译,转载请标明出处。这里是原文如何通过Geth、Node.js和UNIX/PHP访问以太坊节点 ...

January 7, 2019 · 1 min · jiezi

构建一个以太坊+IPFS+React.js应用程序dApp

我们为什么要构建这个?在以太坊区块链上存储大量数据是非常昂贵的。根据以太坊的黄皮书,它是大约20,0000gas,256bit/8字节(1字)。基于02/28/2018 gas价格为4gwei/gas。请参阅:https://ethgasstation.info了解当前价格。每个交易8个字节20,000gas4gwei/gas=80,000gwei。8,000字节80,000gwei1000bytes/8=10,000,000gwei/kB=0.01以太。0.01以太/kB*1000kB=10以太存储1Mb,价格为860美元/以太=8600.00美元!在以太坊区块链上存储1GB文件需要花费8,600,000.00美元!存储以太坊的38页PDF黄皮书(520Kb)=4472美元。请参阅: http://eth-converter.com/进行转换计算。如果我们只能在区块链上存储几Kb的数据,那么我们仍然需要依靠集中式服务器来存储数据。值得庆幸的是,可以使用称为InterPlanetary filessystem 星际文件系统IPFS`的去中心化网络上存储数据的解决方案。请参阅:https://ipfs.io/了解更多信息。在IPFS中查找文件时,你要求网络查找将内容存储在唯一哈希后面的节点。来自IPFS自己的网站:“IPFS和Blockchain完美匹配!你可以使用IPFS处理大量数据,并将不可变的永久IPFS链接放入区块链交易中。这个时间戳和保护你的内容,而不必将数据放在链本身上。“我们构建什么?一个简单的DApp,用于将文档上载到IPFS,然后将IPFS哈希存储在以太坊区块链上。一旦IPFS哈希号被发送到以太坊区块链,用户将收到交易收据。我们将使用Create-React-App框架来构建前端。此Dapp适用于在浏览器中安装了MetaMask的任何用户。这就是我们完成后DApp的样子:如何建立它:注意:如果你只是想要代码,请参阅我的github。在我们开始之前,这些是我做出的假设:关于用户的假设:用户安装了Metamask以与DApp交互。关于你/开发人员的假设:你对JavaScript、React.js以及Node.js/NPM有一定的了解。重要说明:请确保你运行当前版本的Node和NPM。对于本教程,我正在运行:node v8.9.4和NPM 5.6.0。安装MetaMask。如果尚未安装MetaMask,请访问https://metamask.io/并按照说明操作。此DApp将假定用户已安装MetaMask。创建一个目录来存储我们的DApp。对于本教程,我将其称为eth-ipfs。使用NPM安装Create-React-App和其他依赖项。使用NPM并安装以下内容:npm i create-react-appnpm install react-bootstrapnpm install fs-extranpm install ipfs-apinpm install web3@^1.0.0-beta.26输入eth-ipfs目录,键入npm start ,Create-React-App应自动在http://localhost:3000/上呈现。注意:如果你到目前为止尚未使用create-react-app,则可能必须先在全局安装它sudo npm install -g create-react-app或者npm install -g create-react-appcreate-react-app eth-ipfscd进入eth-ipfs然后运行npm start在Rinkeby testnet上使用Remix部署以下Solidity代码。请参阅https://remix.ethereum.org。你需要一些Rinkeby测试以太,如果你还没有Rinkeby faucet的一些免费测试以太话。https://www.rinkeby.io/#faucet。pragma solidity ^0.4.17;contract Contract { string ipfsHash; function sendHash(string x) public { ipfsHash = x; } function getHash() public view returns (string x) { return ipfsHash; }}保存部署它的合约地址和应用程序二进制接口(ABI)。要获得合约的ABI,请在Remix中转到你的合约地址:单击“Compile”选项卡,然后单击灰色的“Details”按钮。这将打开“Details”窗口。复制“ABI”,它是一个JSON文件。我个人更喜欢将ABI JSON放入格式化程序,例如https://jsonformatter.org,并在我的javascript代码中使用之前检查它是否有效。保存合约地址和ABI以供日后使用。在我们的“eth-ipfs/src”目录中,创建以下文件: web3.js,ipfs.js和storehash.js。我们的大部分代码都在App.js中。web3.js我们想使用1.0版本的web3.js,因为与0.20版本不同,1.0允许我们在我们的javascript中使用async并等待而不是promises。目前,MetaMask的默认web3.js提供程序是0.20版本。所以,让我们确保我们覆盖Metamask的web3版本0.20的默认版本,并使用我们的1.0。这是代码://为我们的1.0版本覆盖metamask v0.2。 //1.0让我们使用async和await而不是promises import Web3 from ‘web3’;const web3 = new Web3(window.web3.currentProvider);export default web3;storehash.js为了让web3.js能够访问我们之前部署到以太坊的Rinkeby testnet的合约,你需要以下内容:1)合约地址和2)合约中的ABI。一定要从/src目录中导入web3.js文件。这是代码:import web3 from ‘./web3’;//access our local copy to contract deployed on rinkeby testnet//use your own contract addressconst address = ‘0xb84b12e953f5bcf01b05f926728e855f2d4a67a9’;//use the ABI from your contractconst abi = [ { “constant”: true, “inputs”: [], “name”: “getHash”, “outputs”: [ { “name”: “x”, “type”: “string” } ], “payable”: false, “stateMutability”: “view”, “type”: “function” }, { “constant”: false, “inputs”: [ { “name”: “x”, “type”: “string” } ], “name”: “sendHash”, “outputs”: [], “payable”: false, “stateMutability”: “nonpayable”, “type”: “function” }]export default new web3.eth.Contract(abi, address);ipfs.js在本教程中,我们将运行ipfs.infura.io节点以连接到IPFS,而不是在我们自己的计算机上运行IPFS守护程序。在代码注释中,如果将IPFS安装为全局依赖项,则还可以选择运行自己的IPFS守护程序。有关使用其节点的更多信息,请参阅https://infura.io/。这是代码://using the infura.io node, otherwise ipfs requires you to run a //daemon on your own computer/server.const IPFS = require(‘ipfs-api’);const ipfs = new IPFS({ host: ‘ipfs.infura.io’, port: 5001, protocol: ‘https’ });//run with local daemon// const ipfsApi = require(‘ipfs-api’);// const ipfs = new ipfsApi(‘localhost’, ‘5001’, {protocol:‘http’});export default ipfs;App.js这是App.js中的操作顺序:1.设置状态变量。2.捕获用户的文件。3.将文件转换为缓冲区。4.将缓冲的文件发送到IPFS。5.IPFS返回一个哈希值。6.获取用户的MetaMask以太坊地址7.发送IPFS以便在以太坊上存储。8.使用MetaMask,用户将确认交易到以太坊。9.以太坊合约将返回一个交易哈希数。10.交易哈希值可用于生成具有诸如所使用的gas量和块编号之类的信息的交易收据。11.IPFS和以太坊信息将在使用Bootstrap for CSS的表中呈现。注意:我没有创建一个isLoading类型变量来自动重新呈现blockNumber和gasUsed变量的状态。因此,现在,你必须再次单击或实现自己的加载图标。 描述变量和函数的表,后面是代码本身如下:最后,这是App.js代码:import React, { Component } from ‘react’;//import logo from ‘./logo.svg’;import ‘./App.css’;import web3 from ‘./web3’;import ipfs from ‘./ipfs’;import storehash from ‘./storehash’;class App extends Component { state = { ipfsHash:null, buffer:’’, ethAddress:’’, blockNumber:’’, transactionHash:’’, gasUsed:’’, txReceipt: ’’ };captureFile =(event) => { event.stopPropagation() event.preventDefault() const file = event.target.files[0] let reader = new window.FileReader() reader.readAsArrayBuffer(file) reader.onloadend = () => this.convertToBuffer(reader) }; convertToBuffer = async(reader) => { //file is converted to a buffer for upload to IPFS const buffer = await Buffer.from(reader.result); //set this buffer -using es6 syntax this.setState({buffer}); };onClick = async () => {try{ this.setState({blockNumber:“waiting..”}); this.setState({gasUsed:“waiting…”});//get Transaction Receipt in console on click//See: https://web3js.readthedocs.io/en/1.0/web3-eth.html#gettransactionreceiptawait web3.eth.getTransactionReceipt(this.state.transactionHash, (err, txReceipt)=>{ console.log(err,txReceipt); this.setState({txReceipt}); }); //await for getTransactionReceiptawait this.setState({blockNumber: this.state.txReceipt.blockNumber}); await this.setState({gasUsed: this.state.txReceipt.gasUsed}); } //try catch(error){ console.log(error); } //catch } //onClickonSubmit = async (event) => { event.preventDefault(); //bring in user’s metamask account address const accounts = await web3.eth.getAccounts(); console.log(‘Sending from Metamask account: ’ + accounts[0]); //obtain contract address from storehash.js const ethAddress= await storehash.options.address; this.setState({ethAddress}); //save document to IPFS,return its hash#, and set hash# to state //https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#add await ipfs.add(this.state.buffer, (err, ipfsHash) => { console.log(err,ipfsHash); //setState by setting ipfsHash to ipfsHash[0].hash this.setState({ ipfsHash:ipfsHash[0].hash }); // call Ethereum contract method “sendHash” and .send IPFS hash to etheruem contract //return the transaction hash from the ethereum contract //see, this https://web3js.readthedocs.io/en/1.0/web3-eth-contract.html#methods-mymethod-send storehash.methods.sendHash(this.state.ipfsHash).send({ from: accounts[0] }, (error, transactionHash) => { console.log(transactionHash); this.setState({transactionHash}); }); //storehash }) //await ipfs.add }; //onSubmitrender() { return ( <div className=“App”> <header className=“App-header”> <h1> Ethereum and IPFS with Create React App</h1> </header> <hr /><Grid> <h3> Choose file to send to IPFS </h3> <Form onSubmit={this.onSubmit}> <input type = “file” onChange = {this.captureFile} /> <Button bsStyle=“primary” type=“submit”> Send it </Button> </Form><hr/> <Button onClick = {this.onClick}> Get Transaction Receipt </Button> <Table bordered responsive> <thead> <tr> <th>Tx Receipt Category</th> <th>Values</th> </tr> </thead> <tbody> <tr> <td>IPFS Hash # stored on Eth Contract</td> <td>{this.state.ipfsHash}</td> </tr> <tr> <td>Ethereum Contract Address</td> <td>{this.state.ethAddress}</td> </tr> <tr> <td>Tx Hash # </td> <td>{this.state.transactionHash}</td> </tr> <tr> <td>Block Number # </td> <td>{this.state.blockNumber}</td> </tr> <tr> <td>Gas Used</td> <td>{this.state.gasUsed}</td> </tr> </tbody> </Table> </Grid> </div> ); } //render} //Appexport default App;我在src/App.css中添加了一些CSS,使它看起来更容易一些:/some css I added/input[type=”file”] { display: inline-block;}.table { max-width: 90%; margin: 10px;}.table th { text-align: center;}/end of my css/并向src/index.js添加一些导入:/https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-a-stylesheet/import ‘bootstrap/dist/css/bootstrap.css’;import ‘bootstrap/dist/css/bootstrap-theme.css’;这就对了!你的DApp应该完成。所以你需要做的就是选择一个文件,发送它,并获得一个交易收据。如果你通过localhost:3000连接到IPFS节点,那么你应该能够在其中一个IPFS网关上看到你的文件。https://gateway.ipfs.io/ipfs/+你的IPFS哈希。例如: https://gateway.ipfs.io/ipfs/QmYjh5NsDc6LwU3394NbB42WpQbGVsueVSBmod5WACvpte关于IPFS的一个注意事项是,除非你的文件被另一个节点接收或者你将其固定,否则IPFS最终将垃圾收集你的文件。他们的网站上有很多关于此的内容。======================================================================分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。汇智网原创翻译,转载请标明出处。这里是原文构建一个简单的以太坊+IPFS+React.js DApp ...

January 2, 2019 · 3 min · jiezi

以太坊构建DApps系列教程(八):启动StoryDAO

在本系列关于使用以太坊构建DApps教程的第7部分中,我们展示了如何构建应用程序的前端,为我们一直在研究的这个Story故事设置和部署UI。是时候进行一些部署并编写一些最终功能了。这是使用以太坊区块链构建去中心化应用程序系列的第八部分。我们正在建设的项目名为The Neverending Story。完整的项目可以在storydao.bitfalls.com找到。它的完整代码在GitHub上 。以下是整个系列的概述:在第1部分中,我们引导大家做了两个版本的本地区块链进行开发:Ganache版本和完整的私有PoA版本。在第2部分中,我们构建并部署了TNS代币。在第3部分,我们将介绍如何编译,部署,测试和验证我们的自定义TNS代币,该代币与所有交易所兼容,可用作常规ERC20代币。在第4部分中,我们迈出了开发Story DAO的第一步,包括白名单和测试。在第5部分中,我们处理向故事Story添加内容,查看如何添加参与者从DAO购买代币的能力以及向故事中添加提交内容。在第6部分中,我们将DAO置于最终形式,添加投票,黑名单/取消黑名单,股息分配和撤销,同时投入一些额外的辅助函数以获得良好的评价标准。在第7部分中,我们将展示如何构建应用程序的前端,为我们一直在研究的这个故事story设置和部署UI。在最后一部分中,我们将介绍部署应用程序和编写一些最终功能的最后步骤。自毁程序有些东西可能会非常非常错误,并且使得整个DAO会以某种方式被破坏——无论是通过糟糕的编写代码,还是由于参与者太多而无法完成循环。(提案上的选民太多也可能破坏系统;我们实际上没有采取任何预防措施!)为了防止发生这种情况,拥有相当于“红色大按钮”可能会很有用。首先,让我们升级我们的StoryDao:function bigRedButton() onlyOwner external { active = false; withdrawToOwner(); token.unlockForAll();}然后,让我们可以在代币合约中立即解锁所有代币:/@dev unlocks the tokens of every user who ever had any tokens locked for them*/function unlockForAll() public onlyOwner { uint256 len = touchedByLock.length; for (uint256 i = 0; i < len; i++) { locked[touchedByLock[i]] = 0; }}当然,我们需要在合约中添加这个新的地址列表:address[] touchedByLock;我们需要升级我们的increaseLockedAmount函数以向此列表添加地址:/@dev _owner will be prevented from sending _amount of tokens. Anythingbeyond this amount will be spendable.*/function increaseLockedAmount(address _owner, uint256 _amount) public onlyOwner returns (uint256) { uint256 lockingAmount = locked[_owner].add(_amount); require(balanceOf(_owner) >= lockingAmount, “Locking amount must not exceed balance”); locked[_owner] = lockingAmount; touchedByLock.push(_owner); emit Locked(_owner, lockingAmount); return lockingAmount;}我们还应该更新StoryDao合约中代币所需的接口,以包含这个新函数的签名:// … function getUnlockedAmount(address _owner) view public returns (uint256); function unlockForAll() public;}使用我们之前添加的活动故事块(除非故事的active标志为真,否则无法运行某些功能),这应该可以解决问题。没有人需要在发送合约时浪费钱,每个人的代币都会被解锁。所有者没有得到人们提交的以太。取而代之的是退出功能变得可用,因此人们可以收回他们的以太,并且每个人都会得到照顾。现在我们的合约终于可以部署了。销毁程序是什么样的?有一个名为selfdestruct的函数可以销毁合约。它看起来像这样:selfdestruct(address);调用它将禁用有问题的合约,从区块链的状态中删除其代码并禁用所有功能,同时将该地址中的以太网发送到提供的地址。在我们的案例中,这不是一个好主意:我们仍然希望人们能够撤回他们的以太;我们不想从他们那里拿走它。此外,直接发送到自杀合约地址的任何以太币将永远丢失(烧毁),因为没有办法将其取回。部署合约要完全部署智能合约,我们需要执行以下操作:部署到主网将代币发送到StoryDAO地址将Token合约的所有权转让给StoryDao。我们走吧。主网部署要部署到mainnet,我们需要在truffle.js文件中添加一个新网络:mainnet: { provider: function() { return new WalletProvider( Wallet.fromPrivateKey( Buffer.from(PRIVKEY, “hex”)), “https://mainnet.infura.io/"+INFURAKEY ); }, gasPrice: w3.utils.toWei(“20”, “gwei”), network_id: “1”,},幸运的是,这非常简单。它与Rinkeby部署几乎相同;我们只需要移除gas量(让它自己计算)并改变gas价格。我们还应该将网络ID更改为1,因为这是主网ID。我们这样使用:truffle migrate –network mainnet这里有一点需要注意。如果你在先前部署的网络上进行部署(即使你刚刚将代币部署到主网上并希望稍后部署StoryDao),你可能会收到此错误:Attempting to run transaction which calls a contract function, but recipient address XXX is not a contract address之所以发生这种情况,是因为Truffle会记住部署已经部署的合约的位置,以便它可以在后续迁移中重复使用它们,从而避免重新部署。但是如果你的网络重新启动(即Ganache)或者你进行了一些不兼容的更改,可能会发生它保存的地址实际上不再包含此代码,因此会报错。你可以通过重置迁移来解决此问题:truffle migrate –network mainnet –reset将代币发送到StoryDao地址从部署过程中获取代币的地址和StoryDao的地址。然后只需使用前面描述的MEW来发送代币。如果出现gas缺失,只需增加gas限制即可。请记住:剩余的未使用的gas总是会退回来,所以不用担心会损失比交易成本更多的钱(发送代币应该低于40000gas)。将代币的所有权转让给StoryDao要转移所有权,我们需要在代币上调用transferOwnership函数。让我们将代币加载到MEW中。在Contracts屏幕中,我们输入地址和合约的ABI(从/build文件夹中获取)。然后单击Access将允许我们在菜单中访问该合约中的功能,我们从中选择transferOwnership。提示:仅包含你要调用的函数的ABI就足够了,它不必是代币的整个ABI!你可以只包括transferOwnership函数的ABI,它就没事了!然后我们选择新的所有者(已部署的StoryDao的地址)并解锁当前所有者的钱包(我们之前发送的钱包相同的钱包)。写完此更改后,我们可以检查代币合约中的只读功能owner(与transferOwnership相同的菜单)。它应该现在显示新的所有者。为了确保StoryDao地址实际上有代币,我们可以选择balanceOf函数并在_owner字段中输入StoryDao的地址,然后单击Read:事实上,StoryDao地址中有1亿个代币。提示:我们也可以在部署步骤中完成代币发送和所有权转移。尝试弄清楚如何在测试环境中。验证根据本系列的第3部分,验证DAO和Etherscan上代币的合约将对我们有很大帮助。绿色的复选标记是一条很长的路。按照该部分中的说明验证你的合约。请注意,在验证步骤中,你现在必须将优化器标记为活动,因为我们正在优化代码以实现更便宜的部署!部署到Web要部署StoryDao的Web UI,请按照“常规”Web开发世界中的说明进行操作。因为,在这种情况下,所有的都是静态代码,你甚至可以在GitHub页面或类似的东西上托管它。在这里和这里阅读一些选项。页面启动后,配置UI以使用我们从迁移步骤获得的合约地址。或者,注册代币和StoryDao的ENS名称,你可以保持Web UI静态和固定,硬编码地址,然后只更改ENS名称所指向的以太坊地址。结论DAO教程到此结束。我们希望它能帮助你认识到Solidity开发的复杂性,但我们也希望它能让事情更加清晰,让你更加好奇。一如既往,最好的学习方式就是做。实验,犯错,重启和重建。这种类型的区块链开发需求量很大,而且它越来越受欢迎,所以你有机会接触到底层。祝好运!======================================================================分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。汇智网原创翻译,转载请标明出处。这里是原文以太坊构建DApps系列教程(八):启动StoryDAO ...

December 29, 2018 · 1 min · jiezi

什么是区块链预言机(BlockChain Oracle)

预言机 Oracle 是区块链中非常重要的一个功能,但我发现很少有人讨论,也可能很多人对此并不了解。而网上关于预言机的文章很少,很多也没有讲明白,甚至有些还是错误的。所以我整理了一篇详细的文章,分享给大家,相信看完一定会对 Oracle 有一个深层次的了解。1、预言机(Oracle)是什么?11 月 6 日,在中国人民银行发布的《区块链能做什么?不能做什么?》的报告中,是这样对预言机定义的。区块链外信息写入区块链内的机制,一般被称为预言机 (oracle mechanism) 。预言机的功能就是将外界信息写入到区块链内,完成区块链与现实世界的数据互通。它允许确定的智能合约对不确定的外部世界作出反应,是智能合约与外部进行数据交互的唯一途径,也是区块链与现实世界进行数据交互的接口。听上去很难理解,我们举例来说。大家会很形象的把公链比作操作系统(Windows、IOS、安卓),DAPP 类比的话就是 APP,那么预言机可以形象的比做 API 接口。API 是一组定义、程序及协议的集合,通过 API 接口实现计算机软件之间的相互通信。这样类比虽然不准确,但意思就是预言机是区块链和现实世界之间的纽带,可以实现数据互通的工具。2、Oracle 为什么被中译为预言机?跟别人提起预言机,很多人的第一反应都是预测市场,预言机这个名字确实容易想到预测。Oracle 最初是来源于古希腊宗教,意为“神谕、先知、预言”。而在互联网领域,预言机(英语:oracle machine),又称谕示机,是一种抽象电脑,用来研究决定型问题。可以被视为一个多了个黑盒子(预言者)的图灵机,这个黑盒子的功能是可以在单一运算之内解答特定问题。也许你会好奇这跟甲骨文公司有什么关系吗?其实没有关系。Oracle 在中国叫甲骨文公司的原因可能是另一个故事。在中国商朝晚期,王室把在动物骨骼或龟甲上做占卜记事的文字叫甲骨文,甲骨文被英译为 Oracle bone script,后来 Oracle 公司到中国中译为了甲骨文公司。(很有道理的猜测 哈哈哈)3、区块链为什么需要预言机?区块链是一个确定性的、封闭的系统环境,目前区块链只能获取到链内的数据,而不能获取到链外真实世界的数据,区块链与现实世界是割裂的。一般智能合约的执行需要触发条件,当智能合约的触发条件是外部信息时(链外),就必须需要预言机来提供数据服务,通过预言机将现实世界的数据输入到区块链上,因为智能合约不支持对外请求。具体原因是这样的。区块链是确定性的环境,它不允许不确定的事情或因素,智能合约不管何时何地运行都必须是一致的结果,所以虚拟机(VM)不能让智能合约有 network call(网络调用),不然结果就是不确定的。也就是说智能合约不能进行 I/O(Input/Output,即输入/输出),所以它是无法主动获取外部数据的,只能通过预言机将数据给到智能合约。我们通过一个例子来说明一下。假设现在我被关进了一个小黑屋里(不要多想,只是例子????),我对外面的世界发生了什么一无所知,不知道外面是否有人,即使呼叫也没有人回应,而我知道外界信息的方式,只有外面的人在门口把他看到的听到的都告诉我,我才可以得知。例子虽然不太恰当,但智能合约就像这个例子中的我一样,它无论何时何地,都无法主动向外寻求信息,只能外部把消息或数据给到里面。而预言机就是这个在外面输送消息和数据的人。好像这么看来,智能合约并不是很智能呀,是的,智能合约其实是完成的不智能的事情,即写好了条件和结果,当给它条件的时候,就可以触发,但也不会马上执行,还需要合约相关的人进行私钥签署才可以执行。所以,网上很多文章其实都有水分,比如智能合约某个时间或者触发某个条件就可以自动执行之类的,只能说这样的句子在逻辑上可能是有问题的。关于预言机的很多文章也有水分,描述的并不准确。好了,上面就是区块链为什么需要预言机,因为智能合约无法主动去获取链外的数据,只能被动接受数据。4、预言机怎么解决这个问题?这是理想中预言机的工作流程,即用户的智能合约把请求给链上 Oracle 合约,通过链下的 API 接口获得外部数据,更确切的说是外部把数据给链上的 Oracle 合约,然后 Oracle 合约再把数据给用户的智能合约。或许很难理解,因为在互联网中,调用数据是非常容易的,只需要在程序中写调用的代码就可以了。但是区块链与外部世界的数据交互,确实不能进行这样的操作。5、预言机的应用场景有哪些?预言机作为区块链与现实世界进行数据交互的桥梁,应用场景非常多,可以说一切需要与链下进行数据交互的DApp都需要预言机。比如金融衍生品交易平台、借贷平台、快递追踪/IoT、稳定币、博彩游戏、保险、预测市场等等。我们还是举例来说。先说最近币圈比较火热的博彩游戏为什么需要预言机。博彩游戏的核心是不可预测、可验证的随机数,从而决定赌注的最终结果,但是在链上是无法生成随机数的或者说在链上的随机数是可以被预测和破解的,这时候就需要预言机从外部给智能合约安全的、不可预测的随机数。现在的大多数博彩游戏都是在链上生成随机数,很容易被预测和破解,导致资产被盗,大家有兴趣的可以去看一下 DApp 被盗的相关研究报告,很多因为随机数问题被盗的。比如 BetDice、Dice2.Win。如果大家很感兴趣,可以看一下我男神 DOS Network 创始人 jonny 关于《智能合约中的随机数》的分享。PPT链接:https://zhuanlan.zhihu.com/p/…其实,早在 Fomo3D 这个游戏出来之后,以太坊的 Team Leader 就在推特上说过链上是无法生成随机数的。Dear devs… you can`t generate random numbers on chain!我们再来看一个关于快递追踪的例子。假设当我通过某个 DApp 购物平台购买某件物品快递过来的时候,真实世界中的快递寄送或到达信息,就可以通过 Oracle 把数据传递到链上,然后触发链上的智能合约,我用自己的私钥确认收到了快递,并完成付款。大家发现了吗?这里的智能合约不能自动执行,而是需要我用自己的私钥进行确认,智能合约保证的是没有第三方机构做担保和资金周转(比如支付宝),这就是智能合约的价值。其他的案例就不细说了,比如稳定币需要链下的利率,保险需要链下的病例或车况等,具体可以看这篇文章《Oracle—区块链与现实世界的纽带》。6、目前预言机项目和解决方案有哪些?目前在预言机领域探索的项目还不是很多,每一个项目的预言机解决方案都略有差异,我找了几家不同解决方案的预言机项目。Oraclize:为以太坊提供中心化预言机服务Oraclize 依托亚马逊 AWS 服务和 TLSNotary 技术,是一个可证明的诚实的预言机服务,不过它是中心化的,目前只能在以太坊网络使用,而且 gas 费较高。但是不妨碍它是目前比较受欢迎的预言机服务,可能也是因为没有其他更好的选择吧。ChainLink:以太坊上第一个去中心化预言机解决方案ChainLink 的解决方案是通过在链上的智能合约和链下的数据节点,通过奖惩机制和聚合模型的方式,进行数据的请求和馈送。不过也有一些不足,比如链式聚合成本较高,拓展性差,基于声誉系统容易集中化。欧链 OracleChain:EOS 上的第一个去中心化预言机解决方案欧链很早就提出了预言机的想法和方案,采用自主的 PoRD 机制(Proof-of-Reputation&Deposit),本质上是一种抵押代币奖惩机制的声誉系统,奖励数据节点惩罚作恶节点,可以实现 Augur、Gnosis 等预测市场应用的功能,还能支撑对链外数据有更高频率访问需求的智能合约业务。预测市场的结果本身有时也可以作为 oracle 的输入数据源。欧链更像是预测市场,而且单纯的声誉系统容易集中化。DOS Network:支持多条主流公链的去中心化预言机服务网络DOS Network 是一个 Layer-2 的预言机解决方案,它通过在链上部署一个轻量级智能合约,链下是一个 p2p 网络,服务节点的选取和数据验证采用 VRF+阈值签名等技术,保证了去中心化和数据安全,并达到快速反应。可以适配所有主流公链,比如以太坊、EOS、波场、Thunder。目前已在以太坊测试网发布 alpha 版本 https://dosnetwork.github.io/docs。另外有一个单节点的 demo 视频 https://www.youtube.com/watch?v=yf2fjYSVXNk&t=100s看完文章是不是对区块链预言机有了更深的了解呢,区块链作为一种新兴的技术,还需要不断的探索和尝试。而预言机在其中扮演着非常重要的角色,让我们共同期待预言机技术的不断成熟,进而促进更多区块链与现实世界进行数据交互的 DApp 落地。 ...

December 28, 2018 · 1 min · jiezi

以太坊构建DApps系列教程(六):使用定制代币进行投票

在本系列关于使用以太坊构建DApps教程的第5部分中,我们讨论了如何为Story添加内容,查看如何添加参与者从DAO购买代币的功能以及在Story中添加提交内容。现在是编写DAO最终形式的时候了:投票,黑名单,股息分配和退出。我们将提供一些额外的辅助函数以便进行监测。如果你对这一切感觉迷失了,那么repo中会提供完整的源代码。投票和提案我们将发布Votes并投票。这需要两个新的结构:struct Proposal { string description; bool executed; int256 currentResult; uint8 typeFlag; // 1 = delete bytes32 target; // ID of the proposal target. I.e. flag 1, target XXXXXX (hash) means proposal to delete submissions[hash] uint256 creationDate; uint256 deadline; mapping (address => bool) voters; Vote[] votes; address submitter;}Proposal[] public proposals;uint256 proposalCount = 0;event ProposalAdded(uint256 id, uint8 typeFlag, bytes32 hash, string description, address submitter);event ProposalExecuted(uint256 id);event Voted(address voter, bool vote, uint256 power, string justification);struct Vote { bool inSupport; address voter; string justification; uint256 power;}提案将对选民进行映射,以防止人们对提案进行两次投票,以及其他一些应该不言自明的元数据。投票将是一个是或否投票,并将记住选民以及他们以某种方式投票的理由,以及投票权——他们希望投入该投票的代币数量。我们还添加了一系列Proposals,以便我们可以将它们存储在某个地方,并提供一个计数器来计算有多少提案。让我们现在构建他们的附属函数,从投票函数开始:modifier tokenHoldersOnly() { require(token.balanceOf(msg.sender) >= 10**token.decimals()); _;}function vote(uint256 _proposalId, bool _vote, string _description, uint256 _votePower) tokenHoldersOnly public returns (int256) { require(_votePower > 0, “At least some power must be given to the vote.”); require(uint256(_votePower) <= token.balanceOf(msg.sender), “Voter must have enough tokens to cover the power cost.”); Proposal storage p = proposals[_proposalId]; require(p.executed == false, “Proposal must not have been executed already.”); require(p.deadline > now, “Proposal must not have expired.”); require(p.voters[msg.sender] == false, “User must not have already voted.”); uint256 voteid = p.votes.length++; Vote storage pvote = p.votes[voteid]; pvote.inSupport = _vote; pvote.justification = _description; pvote.voter = msg.sender; pvote.power = _votePower; p.voters[msg.sender] = true; p.currentResult = (_vote) ? p.currentResult + int256(_votePower) : p.currentResult - int256(_votePower); token.increaseLockedAmount(msg.sender, _votePower); emit Voted(msg.sender, _vote, _votePower, _description); return p.currentResult;}注意函数修饰符:通过将该修饰符添加到我们的合约中,我们可以将它附加到任何将来的函数,并确保只有令牌持有者才能执行该函数。这是一个可重复使用的安全检查!投票功能做了一些健壮性检查,例如投票权是积极的,选民有足够的代币实际投票等。然后我们从存储中获取提案并确保它既没有过期也没有已经执行。对已经完成的提案进行投票是没有意义的。我们还需要确保这个人还没有投票。我们可以允许改变投票权,但这会让DAO面临一些漏洞,例如人们在最后一刻撤回投票等等。也许是未来版本的候选人?然后我们在提案中注册一个新的投票,更改当前结果以便于查找分数,最后发出Voted事件。但是什么是token.increaseLockedAmount?这一点逻辑增加了用户的锁定代币数量。该功能只能由代币合约的所有者执行(此时希望是DAO)并且将阻止用户发送超过其帐户注册的锁定金额的令牌数量。提案落实或执行后,此锁定被解除。让我们编写现在提议删除条目的函数。投票删除和黑名单如本系列第1部分所述 ,我们计划了三个条目删除功能:1.删除条目:通过投票确认后,目标条目将被删除。投票时间:48小时。2.紧急删除条目[仅限所有者]:只能由所有者触发。通过投票确认后,目标条目将被删除。投票时间:24小时。3.紧急删除图像[仅限所有者]:仅适用于图像条目。只能由所有者触发。通过投票确认后,目标条目将被删除。投票时间:4小时。单个地址条目的五个删除导致黑名单。让我们看看我们现在该怎么做。首先,删除功能:modifier memberOnly() { require(whitelist[msg.sender]); require(!blacklist[msg.sender]); _;}function proposeDeletion(bytes32 _hash, string _description) memberOnly public { require(submissionExists(_hash), “Submission must exist to be deletable”); uint256 proposalId = proposals.length++; Proposal storage p = proposals[proposalId]; p.description = _description; p.executed = false; p.creationDate = now; p.submitter = msg.sender; p.typeFlag = 1; p.target = _hash; p.deadline = now + 2 days; emit ProposalAdded(proposalId, 1, _hash, _description, msg.sender); proposalCount = proposalId + 1;}function proposeDeletionUrgent(bytes32 _hash, string _description) onlyOwner public { require(submissionExists(_hash), “Submission must exist to be deletable”); uint256 proposalId = proposals.length++; Proposal storage p = proposals[proposalId]; p.description = _description; p.executed = false; p.creationDate = now; p.submitter = msg.sender; p.typeFlag = 1; p.target = _hash; p.deadline = now + 12 hours; emit ProposalAdded(proposalId, 1, _hash, _description, msg.sender); proposalCount = proposalId + 1;} function proposeDeletionUrgentImage(bytes32 _hash, string _description) onlyOwner public { require(submissions[_hash].image == true, “Submission must be existing image”); uint256 proposalId = proposals.length++; Proposal storage p = proposals[proposalId]; p.description = _description; p.executed = false; p.creationDate = now; p.submitter = msg.sender; p.typeFlag = 1; p.target = _hash; p.deadline = now + 4 hours; emit ProposalAdded(proposalId, 1, _hash, _description, msg.sender); proposalCount = proposalId + 1;}一旦提出,建议书就会被添加到提案列表中,并记录条目哈希所针对的条目。保存说明并添加一些默认值,并根据提案类型计算截止日期。该提案添加了事件,并且提案总数增加了。接下来让我们看看如何执行提案。为了可执行,提案必须有足够的票数,并且必须超过其截止日期。执行功能将接受要执行的提议的ID。没有简单的方法可以让EVM立即执行所有待处理的提案。可能有太多人要等待执行,并且他们会对DAO中的数据进行大的更改,这可能会超过以太坊块的气体限制,从而导致交易失败。构建一个可以由具有明确规则的任何人调用的手动执行功能要容易得多,因此社区可以关注需要执行的提议。function executeProposal(uint256 _id) public { Proposal storage p = proposals[_id]; require(now >= p.deadline && !p.executed); if (p.typeFlag == 1 && p.currentResult > 0) { assert(deleteSubmission(p.target)); } uint256 len = p.votes.length; for (uint i = 0; i < len; i++) { token.decreaseLockedAmount(p.votes[i].voter, p.votes[i].power); } p.executed = true; emit ProposalExecuted(_id);}我们通过其ID获取提案,检查它是否符合未执行的要求和截止日期过期,然后如果提案的类型是删除提案且投票结果是肯定的,我们使用已经写入的删除功能,最后发出了我们添加的新事件(将其添加到合约的顶部)。assert调用与require语句具有相同的用途:断言通常在“断言”结果为真时使用。要求用于先决条件。在功能上它们是相同的,assert语句的差异在它们失败时无法接受消息参数。该功能通过为该一个提案中的所有投票解锁代币而结束。我们可以使用相同的方法添加其他类型的提案,但首先,让我们更新deleteSubmission函数以禁止在其帐户上有五个或更多删除的用户:这意味着他们一直在提交社区投票反对的内容。让我们更新deleteSubmission函数:function deleteSubmission(bytes32 hash) internal returns (bool) { require(submissionExists(hash), “Submission must exist to be deletable.”); Submission storage sub = submissions[hash]; sub.exists = false; deletions[submissions[hash].submitter] += 1; if (deletions[submissions[hash].submitter] >= 5) { blacklistAddress(submissions[hash].submitter); } emit SubmissionDeleted( sub.index, sub.content, sub.image, sub.submitter ); nonDeletedSubmissions -= 1; return true;}那更好。自动将五个删除列入黑名单。但是,如果不给黑名单地址提供赎回的机会,那是不公平的。我们还需要定义黑名单功能本身。让我们做这两件事并将不合理的费用设置为例如0.05以太。function blacklistAddress(address _offender) internal { require(blacklist[_offender] == false, “Can’t blacklist a blacklisted user :/”); blacklist[_offender] == true; token.increaseLockedAmount(_offender, token.getUnlockedAmount(_offender)); emit Blacklisted(_offender, true);}function unblacklistMe() payable public { unblacklistAddress(msg.sender);}function unblacklistAddress(address _offender) payable public { require(msg.value >= 0.05 ether, “Unblacklisting fee”); require(blacklist[_offender] == true, “Can’t unblacklist a non-blacklisted user :/”); require(notVoting(_offender), “Offender must not be involved in a vote.”); withdrawableByOwner = withdrawableByOwner.add(msg.value); blacklist[_offender] = false; token.decreaseLockedAmount(_offender, token.balanceOf(_offender)); emit Blacklisted(_offender, false);}function notVoting(address _voter) internal view returns (bool) { for (uint256 i = 0; i < proposalCount; i++) { if (proposals[i].executed == false && proposals[i].voters[_voter] == true) { return false; } } return true;}请注意,列入黑名单的帐户的令牌会被锁定,直到他们发送不合格的费用为止。其他类型的投票使用我们上面写的函数的灵感,尝试编写其他提议。对于剧透,请查看项目的GitHub仓库并从那里复制最终代码。为简洁起见,让我们继续讨论DAO中剩下的其他功能。章节的结束一旦达到故事的时间或章节限制,就应该结束故事了。任何人都可以在允许提取股息的日期之后调用结束函数。首先,我们需要一个新的StoryDAO属性和一个事件:bool public active = true;event StoryEnded(); 然后,让我们构建函数:function endStory() storyActive external { withdrawToOwner(); active = false; emit StoryEnded();}简单:它将收集的费用发送给所有者并发出事件后停用故事。但实际上,这并没有真正改变整个DAO中的任何内容:其他功能对它的结束没有反应。那么让我们构建另一个修饰符:modifier storyActive() { require(active == true); _;}然后,我们将此修饰符添加到除withdrawToOwner之外的所有函数中,如下所示:function whitelistAddress(address _add) storyActive public payable { 如果DAO中遗留了任何代币,让我们将它们取回并接管这些代币的所有权,以便以后能够在另一个故事中使用它们:function withdrawLeftoverTokens() external onlyOwner { require(active == false); token.transfer(msg.sender, token.balanceOf(address(this))); token.transferOwnership(msg.sender);}function unlockMyTokens() external { require(active == false); require(token.getLockedAmount(msg.sender) > 0); token.decreaseLockedAmount(msg.sender, token.getLockedAmount(msg.sender));}unlockMyTokens函数用于解锁所有锁定的代币,以防某些锁定代币为特定用户锁定。它不应该发生,并且应该通过大量测试来移除此功能。股息分配和提款现在故事已经结束,收集的费用需要分配给所有代币持有者。我们可以重新使用我们的白名单来标记所有取消费用的人:function withdrawDividend() memberOnly external { require(active == false); uint256 owed = address(this).balance.div(whitelistedNumber); msg.sender.transfer(owed); whitelist[msg.sender] = false; whitelistedNumber–;}如果这些股息未在一定时限内撤回,业主可以抓住其余股息:function withdrawEverythingPostDeadline() external onlyOwner { require(active == false); require(now > deadline + 14 days); owner.transfer(address(this).balance);}留个家庭作业,考虑重新使用相同部署的智能合约,清除其数据,并将代币保留在底池中并重新启动另一章而无需重新部署是多么容易或困难。尝试自己这样做,并密切关注回购,以便将来更新本系列教程!还要考虑额外的激励机制:也许账户中的代币数量会影响他们从故事结束中获得的红利?你的想象力是极限!部署问题鉴于我们的合约现在非常大,部署和/或测试它可能会超过以太坊区块的gas限制。这是限制大型应用程序部署在以太坊网络上的原因。无论如何要部署它,在编译期间尝试使用代码优化器,方法是更改truffle.js文件以包含用于优化的solc设置,如下所示:// …module.exports = { solc: { optimizer: { enabled: true, runs: 200 } }, networks: { development: {// …这将在代码中运行优化器200次以查找在部署之前可以缩小,移除或抽象的区域,这将显着降低部署成本。结论这就是我们详尽的DAO开发——但课程还没有结束!我们仍然需要为这个故事构建和部署UI。幸运的是,后端完全托管在区块链上,构建前端的复杂程度要低得多。让我们看看这个系列的倒数第二部分。======================================================================分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。汇智网原创翻译,转载请标明出处。这里是原文以太坊构建DApps系列教程(六):使用定制代币进行投票 ...

December 27, 2018 · 4 min · jiezi

以太坊构建DApps系列教程(四):Story DAO的白名单和测试

在本系列关于使用以太坊构建DApps教程的第3部分中,我们构建并将我们的代币部署到以太坊测试网络Rinkeby。在这部分中,我们将开始编写Story DAO代码。我们将使用第1部分中列出的条件来做指导。合约大纲让我们用这个骨架创建一个新的合约StoryDao.sol:pragma solidity ^0.4.24;import “../node_modules/openzeppelin-solidity/contracts/math/SafeMath.sol”;import “../node_modules/openzeppelin-solidity/contracts/ownership/Ownable.sol”;contract StoryDao is Ownable { using SafeMath for uint256; mapping(address => bool) whitelist; uint256 public whitelistedNumber = 0; mapping(address => bool) blacklist; event Whitelisted(address addr, bool status); event Blacklisted(address addr, bool status); uint256 public daofee = 100; // hundredths of a percent, i.e. 100 is 1% uint256 public whitelistfee = 10000000000000000; // in Wei, this is 0.01 ether event SubmissionCommissionChanged(uint256 newFee); event WhitelistFeeChanged(uint256 newFee); uint256 public durationDays = 21; // duration of story’s chapter in days uint256 public durationSubmissions = 1000; // duration of story’s chapter in entries function changedaofee(uint256 _fee) onlyOwner external { require(_fee < daofee, “New fee must be lower than old fee.”); daofee = _fee; emit SubmissionCommissionChanged(_fee); } function changewhitelistfee(uint256 _fee) onlyOwner external { require(_fee < whitelistfee, “New fee must be lower than old fee.”); whitelistfee = _fee; emit WhitelistFeeChanged(_fee); } function lowerSubmissionFee(uint256 _fee) onlyOwner external { require(_fee < submissionZeroFee, “New fee must be lower than old fee.”); submissionZeroFee = _fee; emit SubmissionFeeChanged(_fee); } function changeDurationDays(uint256 _days) onlyOwner external { require(_days >= 1); durationDays = _days; } function changeDurationSubmissions(uint256 _subs) onlyOwner external { require(_subs > 99); durationSubmissions = _subs; }}我们正在导入SafeMath以便再次进行安全计算,但这次我们还使用了Zeppelin的Ownable合约,该合约允许某人“拥有”故事并执行某些仅限管理员的功能。简单地说我们的StoryDao is Ownable就够了;随时检查合约,看看它是如何工作的。我们还使用此合约中的onlyOwner修饰符。函数修饰符基本上是函数扩展和插件。onlyOwner修饰符如下所示:modifier onlyOwner() { require(msg.sender == owner); ;}当onlyOwner被添加到一个函数中时,那个函数的体被粘贴到;所在的部分,并且它比其他的一切内容都先执行。因此,通过使用此修饰符,该函数会自动检查邮件发件人是否也是合约的所有者,然后照常继续(如果是)。如果没有,它会崩溃。通过在改变我们的Story DAO的费用和其他参数的函数上使用onlyOwner修饰符,我们确保只有管理员才能进行这些更改。测试让我们测试一下初始函数。如果文件夹test不存在,请创建它。然后在其中创建文件TestStoryDao.sol和TestStoryDao.js。因为在Truffle中没有本地方法来测试异常,所以也可以使用以下内容创建helpers/expectThrow.js:export default async promise => { try { await promise; } catch (error) { const invalidOpcode = error.message.search(‘invalid opcode’) >= 0; const outOfGas = error.message.search(‘out of gas’) >= 0; const revert = error.message.search(‘revert’) >= 0; assert( invalidOpcode || outOfGas || revert, ‘Expected throw, got '’ + error + ‘' instead’, ); return; } assert.fail(‘Expected throw not received’); };注意:Solidity测试通常用于测试基于合约的低级函数,即智能合约的内部。JS测试通常用于测试合约是否可以与外部进行正确的交互,这是我们最终用户将要做的事情。在TestStoryDao.sol,输入以下内容:pragma solidity ^0.4.24;import “truffle/Assert.sol”;import “truffle/DeployedAddresses.sol”;import “../contracts/StoryDao.sol”;contract TestStoryDao { function testDeploymentIsFine() public { StoryDao sd = StoryDao(DeployedAddresses.StoryDao()); uint256 daofee = 100; // hundredths of a percent, i.e. 100 is 1% uint256 whitelistfee = 10000000000000000; // in Wei, this is 0.01 ether uint256 durationDays = 21; // duration of story’s chapter in days uint256 durationSubmissions = 1000; // duration of story’s chapter in entries Assert.equal(sd.daofee(), daofee, “Initial DAO fee should be 100”); Assert.equal(sd.whitelistfee(), whitelistfee, “Initial whitelisting fee should be 0.01 ether”); Assert.equal(sd.durationDays(), durationDays, “Initial day duration should be set to 3 weeks”); Assert.equal(sd.durationSubmissions(), durationSubmissions, “Initial submission duration should be set to 1000 entries”); }}这将检查StoryDao合约是否正确部署,并提供正确的费用和持续时间。第一行确保通过从已部署地址列表中读取它来部署它,并且最后一节做了一些断言——检查声明是真还是假。在我们的例子中,我们将数字与已部署合约的初始值进行比较。每当它为“true”时,Assert.equals部分将发出一个“True”的事件,这是Truffle在测试时正在监听的事件。在TestStoryDao.js,输入以下内容:import expectThrow from ‘./helpers/expectThrow’;const StoryDao = artifacts.require(“StoryDao”);contract(‘StoryDao Test’, async (accounts) => { it(“should make sure environment is OK by checking that the first 3 accounts have over 20 eth”, async () =>{ assert.equal(web3.eth.getBalance(accounts[0]).toNumber() > 2e+19, true, “Account 0 has more than 20 eth”); assert.equal(web3.eth.getBalance(accounts[1]).toNumber() > 2e+19, true, “Account 1 has more than 20 eth”); assert.equal(web3.eth.getBalance(accounts[2]).toNumber() > 2e+19, true, “Account 2 has more than 20 eth”); }); it(“should make the deployer the owner”, async () => { let instance = await StoryDao.deployed(); assert.equal(await instance.owner(), accounts[0]); }); it(“should let owner change fee and duration”, async () => { let instance = await StoryDao.deployed(); let newDaoFee = 50; let newWhitelistFee = 1e+10; // 1 ether let newDayDuration = 42; let newSubsDuration = 1500; instance.changedaofee(newDaoFee, {from: accounts[0]}); instance.changewhitelistfee(newWhitelistFee, {from: accounts[0]}); instance.changedurationdays(newDayDuration, {from: accounts[0]}); instance.changedurationsubmissions(newSubsDuration, {from: accounts[0]}); assert.equal(await instance.daofee(), newDaoFee); assert.equal(await instance.whitelistfee(), newWhitelistFee); assert.equal(await instance.durationDays(), newDayDuration); assert.equal(await instance.durationSubmissions(), newSubsDuration); }); it(“should forbid non-owners from changing fee and duration”, async () => { let instance = await StoryDao.deployed(); let newDaoFee = 50; let newWhitelistFee = 1e+10; // 1 ether let newDayDuration = 42; let newSubsDuration = 1500; await expectThrow(instance.changedaofee(newDaoFee, {from: accounts[1]})); await expectThrow(instance.changewhitelistfee(newWhitelistFee, {from: accounts[1]})); await expectThrow(instance.changedurationdays(newDayDuration, {from: accounts[1]})); await expectThrow(instance.changedurationsubmissions(newSubsDuration, {from: accounts[1]})); }); it(“should make sure the owner can only change fees and duration to valid values”, async () =>{ let instance = await StoryDao.deployed(); let invalidDaoFee = 20000; let invalidDayDuration = 0; let invalidSubsDuration = 98; await expectThrow(instance.changedaofee(invalidDaoFee, {from: accounts[0]})); await expectThrow(instance.changedurationdays(invalidDayDuration, {from: accounts[0]})); await expectThrow(instance.changedurationsubmissions(invalidSubsDuration, {from: accounts[0]})); })});为了使我们的测试成功运行,我们还需要告诉Truffle我们想要部署StoryDao——因为它不会为我们做。因此,让我们在migrations创建3_deploy_storydao.js,其内容几乎与我们之前编写的迁移相同:var Migrations = artifacts.require("./Migrations.sol");var StoryDao = artifacts.require("./StoryDao.sol");module.exports = function(deployer, network, accounts) { if (network == “development”) { deployer.deploy(StoryDao, {from: accounts[0]}); } else { deployer.deploy(StoryDao); }};此时,我们还应该在项目文件夹的根目录中更新(或创建,如果它不存在)package.json文件,其中包含我们目前所需的依赖项,并且可能在不久的将来需要:{ “name”: “storydao”, “devDependencies”: { “babel-preset-es2015”: “^6.18.0”, “babel-preset-stage-2”: “^6.24.1”, “babel-preset-stage-3”: “^6.17.0”, “babel-polyfill”: “^6.26.0”, “babel-register”: “^6.23.0”, “dotenv”: “^6.0.0”, “truffle”: “^4.1.12”, “openzeppelin-solidity”: “^1.10.0”, “openzeppelin-solidity-metadata”: “^1.2.0”, “openzeppelin-zos”: “”, “truffle-wallet-provider”: “^0.0.5”, “ethereumjs-wallet”: “^0.6.0”, “web3”: “^1.0.0-beta.34”, “truffle-assertions”: “^0.3.1” }}和.babelrc文件的内容:{ “presets”: [“es2015”, “stage-2”, “stage-3”]}我们还需要在我们的Truffle配置中要求Babel,因此它知道它应该在编译时使用它。注意:Babel是NodeJS的一个附加组件,它允许我们在当前一代NodeJS中使用下一代JavaScript,因此我们可以编写诸如import。如果这超出了你的理解范围,只需忽略它,然后只需逐字粘贴即可。在以这种方式安装后,你可能永远不必再处理这个问题。require(‘dotenv’).config();================== ADD THESE TWO LINES ================require(‘babel-register’);require(‘babel-polyfill’);=======================================================const WalletProvider = require(“truffle-wallet-provider”);const Wallet = require(’ethereumjs-wallet’);// …现在,终于进行truffle test。输出应该类似于这个:有关测试的更多信息,请参阅本教程,该教程专门用于测试智能合约。在本课程的后续部分中,我们将跳过测试,因为输入它们会使教程太长,但请参考项目的最终源代码来检查它们。我们刚刚完成的过程已经设置了测试环境,因此你可以在进一步设置的情况下编写测试。白名单现在让我们构建一个白名单机制,让用户参与构建Story。将以下函数框架添加到StoryDao.sol:function whitelistAddress(address _add) public payable { // whitelist sender if enough money was sent}function() external payable { // if not whitelisted, whitelist if paid enough // if whitelisted, but X tokens at X price for amount}未命名的函数function()被称为回调函数,这是在没有特定指令的情况下将钱发送到此合约时被调用的函数(即,没有专门调用其他函数)。这可以让人们加入StoryDao,只需将以太发送到DAO并立即将其列入白名单,或者购买代币,具体取决于它们是否已经列入白名单。whitelistSender功能用于白名单,可以直接调用,但是如果发送方尚未列入白名单,我们将确保当收到一些以太时,后备功能会自动调用它。whitelistAddress函数被声明为public因为它也应该可以从其他合约中调用,并且回调函数是external函数,因为money将仅从外部地址转到此地址。调用此合约的合约可以直接轻松调用所需的功能。让我们首先处理回调函数。function() external payable { if (!whitelist[msg.sender]) { whitelistAddress(msg.sender); } else { // buyTokens(msg.sender, msg.value); }}我们检查发件人是否已经在白名单中,并将调用委托给whitelistAddress函数。请注意,我们已经注释掉了buyTokens函数,因为我们还没有它。接下来,让我们处理白名单。function whitelistAddress(address _add) public payable { require(!whitelist[_add], “Candidate must not be whitelisted.”); require(!blacklist[_add], “Candidate must not be blacklisted.”); require(msg.value >= whitelistfee, “Sender must send enough ether to cover the whitelisting fee.”); whitelist[_add] = true; whitelistedNumber++; emit Whitelisted(_add, true); if (msg.value > whitelistfee) { // buyTokens(_add, msg.value.sub(whitelistfee)); }}请注意,此函数接受地址作为参数,并且不从消息中提取它(来自交易)。如果有人无法承担加入DAO的费用,这还有一个额外的好处,即人们可以将其他人列入白名单。我们通过一些健壮性检查启动该功能:发件人不得列入白名单或列入黑名单(禁止),并且必须已发送足够的费用以支付费用。如果这些条件令人满意,则将地址添加到白名单中,发出白名单事件,最后,如果发送的以太数量大于覆盖白名单费用所需的以太数量,则剩余部分用于买这些代币。注意:我们使用sub而不是-来减,因为这是一个安全计算的SafeMath函数。用户现在可以将自己或其他人列入白名单,只要他们向StoryDao合约发送0.01以太或更多。结论我们在本教程中构建了DAO的初始部分,但还有很多工作要做。请继续关注:在下一部分中,我们将处理为Story添加内容的问题!======================================================================分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。汇智网原创翻译,转载请标明出处。这里是原文以太坊构建DApps系列教程(四):Story DAO的白名单和测试 ...

December 26, 2018 · 4 min · jiezi

Ethereum DPOS源码分析

1 导语区块链的主要工作就是出块,出块的制度、方式叫做共识;\块里的内容是不可篡改的信息记录,块连接成链就是区块链。出块又叫挖矿,有各种挖矿的方式,比如POW、DPOS,本文主要分析DPOS共识源码。以太坊存在多种共识:PoW (etash)在主网使用PoA(clique) 在测试网使用FakePow 在单元测试使用DPOS 新增共识替代POW既然是源码分析,主要读者群体应该是看代码的人,读者须要结合代码看此类文章。明白此类文章的作用是:提供一个分析的切入口,将散落的代码按某种内在逻辑串起来,用图文的形式叙述代码的大意,引领读者有一个系统化的认知,同时对自己阅读代码过程中不理解的地方起到一定参考作用。2 DPOS的共识逻辑DPOS的基本逻辑可以概述为:成为候选人-获得他人投票-被选举为验证人-在周期内轮流出块。从这个过程可以看到,成为候选人和投票是用户主动发起的行为,获得投票和被选为验证人是系统行为。DPOS的主要功能就是成为候选人、投票(对方获得投票),以及系统定期自动执行的选举。2.1 最初的验证人验证人就是出块人,在创世的时候,系统还没运行,用户自然不能投票,本系统采用的方法是,在创世配置文件中定义好最初的一批出块验证人(Validator),由这一批验证人在第一个出块周期内轮流出块,默认是21个验证人。{ “config”: { “chainId”: 8888, “eip155Block”: 0, “eip158Block”: 0, “byzantiumBlock”:0, “dpos”:{ “validators”:[ “0x8807fa0db2c60675a8f833dd010469e408428b83”, “0xdf5f5a7abc5d0821c50deb4368528d8691f18737”, “0xe0d64bfb1a30d66ae0f06ce36d5f4edf6835cd7c” …… ] } }, “nonce”: “0x0000000000000042”, “difficulty”: “0x020000”, “mixHash”: “0x0000000000000000000000000000000000000000000000000000000000000000”, “coinbase”: “0x0000000000000000000000000000000000000000”, “timestamp”: “0x00”, “parentHash”: “0x0000000000000000000000000000000000000000000000000000000000000000”, “extraData”: “0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa”, “gasLimit”: “0x500000”, “alloc”: {}}2.2 成为候选人系统运行之后,任何人随时可以投票,同时也可以获得他人投票。因为只有候选人才允许获得投票,所以任何人被投票之前都要先成为候选人(candidate)。\从外部用户角度看,成为候选人只需要自己发一笔交易即可:eth.sendTransaction({ from: ‘0x646ba1fa42eb940aac67103a71e9a908ef484ec3’, to: ‘0x646ba1fa42eb940aac67103a71e9a908ef484ec3’, value: 0, type: 1})在系统内部,成为候选人和投票均被定义为交易,其实DPOS定义的所有交易有四种类型,是针对这两种行为的正向和反向操作。type TxType uint8const ( Binary TxType = iota LoginCandidate //成为候选人 LogoutCandidate //取消候选人 Delegate //投票 UnDelegate //取消投票)type txdata struct { Type TxType json:"type" …… }成为候选人代码非常简单,就是更新(插入)一下candidateTrie,这棵树的键和值都是候选人的地址,它保存着所有当前时间的候选人。func (d *DposContext) BecomeCandidate(candidateAddr common.Address) error { candidate := candidateAddr.Bytes() return d.candidateTrie.TryUpdate(candidate, candidate)}具体执行交易的时候,它取的地址是from,这意味着只能将自己设为候选人。case types.LoginCandidate: dposContext.BecomeCandidate(msg.From())除了这里提到的candidateTrie,DPOS总共有五棵树:type DposContext struct { epochTrie *trie.Trie //记录出块周期内的验证人列表 ("validator",[]validator) delegateTrie *trie.Trie //(append(candidate, delegator...), delegator) voteTrie *trie.Trie //(delegator, candidate) candidateTrie *trie.Trie //(candidate, candidate) mintCntTrie *trie.Trie //记录验证人在周期内的出块数目(append(epoch, validator.Bytes()...),count) 这里的epoch=header.Time/86400 db ethdb.Database}delegator是投票人2.3 投票从外部用户角度看,投票也是一笔交易:eth.sendTransaction({ from: '0x646ba1fa42eb940aac67103a71e9a908ef484ec3', to: '0x5b76fff970bf8a351c1c9ebfb5e5a9493e956ddd', value: 0, type: 3})系统内部的投票代码,主要更新delegateTrie和voteTrie:func (d *DposContext) Delegate(delegatorAddr, candidateAddr common.Address) error { delegator, candidate := delegatorAddr.Bytes(), candidateAddr.Bytes() // 获得投票的候选人一定要在candidateTrie中 candidateInTrie, err := d.candidateTrie.TryGet(candidate) if err != nil { return err } if candidateInTrie == nil { return errors.New("invalid candidate to delegate") } // delete old candidate if exists oldCandidate, err := d.voteTrie.TryGet(delegator) if err != nil { if _, ok := err.(*trie.MissingNodeError); !ok { return err } } if oldCandidate != nil { d.delegateTrie.Delete(append(oldCandidate, delegator...)) } if err = d.delegateTrie.TryUpdate(append(candidate, delegator...), delegator); err != nil { return err } return d.voteTrie.TryUpdate(delegator, candidate)}2.4 选举投票虽然随时可以进行,但是验证人的选出,则是周期性的触发。\选举周期默认设定为24小时,每过24小时,对验证人进行一次重新选举。\每次区块被打包的时候(Finalize)都会调用选举函数,选举函数判断是否到了重新选举的时刻,它根据当前块和上一块的时间,计算两块是否属于同一个选举周期,如果是同一个周期,不触发重选,如果不是同一个周期,则说明当前块是新周期的第一块,触发重选。\\选举函数:func (ec *EpochContext) tryElect(genesis, parent *types.Header) error { genesisEpoch := genesis.Time.Int64() / epochInterval //0 prevEpoch := parent.Time.Int64() / epochInterval //ec.TimeStamp从Finalize传过来的当前块的header.Time currentEpoch := ec.TimeStamp / epochInterval prevEpochIsGenesis := prevEpoch == genesisEpoch if prevEpochIsGenesis &amp;&amp; prevEpoch &lt; currentEpoch { prevEpoch = currentEpoch - 1 } prevEpochBytes := make([]byte, 8) binary.BigEndian.PutUint64(prevEpochBytes, uint64(prevEpoch)) iter := trie.NewIterator(ec.DposContext.MintCntTrie().PrefixIterator(prevEpochBytes)) //currentEpoch只有在比prevEpoch至少大于1的时候执行下面代码。 //大于1意味着当前块的时间,距离上一块所处的周期起始时间,已经超过epochInterval即24小时了。 //大于2过了48小时…… for i := prevEpoch; i &lt; currentEpoch; i++ { // 如果前一个周期不是创世周期,触发踢出验证人规则 if !prevEpochIsGenesis &amp;&amp; iter.Next() { if err := ec.kickoutValidator(prevEpoch); err != nil { return err } } //计票,按票数从高到低得出safeSize个验证人 // 候选人的票数cnt=所有投他的delegator的账户余额之和 votes, err := ec.countVotes() if err != nil { return err } candidates := sortableAddresses{} for candidate, cnt := range votes { candidates = append(candidates, &amp;sortableAddress{candidate, cnt}) } if len(candidates) &lt; safeSize { return errors.New("too few candidates") } sort.Sort(candidates) if len(candidates) &gt; maxValidatorSize { candidates = candidates[:maxValidatorSize] } // shuffle candidates //用父块的hash和当前周期编号做验证人列表随机乱序的种子 //打乱验证人列表顺序,由seed确保每个节点计算出来的验证人顺序都是一致的。 seed := int64(binary.LittleEndian.Uint32(crypto.Keccak512(parent.Hash().Bytes()))) + i r := rand.New(rand.NewSource(seed)) for i := len(candidates) - 1; i &gt; 0; i-- { j := int(r.Int31n(int32(i + 1))) candidates[i], candidates[j] = candidates[j], candidates[i] } sortedValidators := make([]common.Address, 0) for _, candidate := range candidates { sortedValidators = append(sortedValidators, candidate.address) } epochTrie, _ := types.NewEpochTrie(common.Hash{}, ec.DposContext.DB()) ec.DposContext.SetEpoch(epochTrie) ec.DposContext.SetValidators(sortedValidators) log.Info("Come to new epoch", "prevEpoch", i, "nextEpoch", i+1) } return nil}当epochContext最终调用了dposContext的SetValidators()后,新的一批验证人就产生了,这批新的验证人将开始轮流出块。2.5 DPOS相关类图EpochContext是选举周期(默认24小时)相关实体类,所以主要功能是仅在周期时刻发生的事情,包括选举、计票、踢出验证人。它是更大范围上的存在,不直接操作DPOS的五棵树,而是通过它聚合的DposContext对五棵树进行增删改查。DposContext和Trie是强组合关系,DPOS的交易行为(成为候选人、取消为候选人、投票、取消投票、设置验证人)就是它的主要功能。Dpos is a engine,实现Engine接口。func (self *worker) mintBlock(now int64) { engine, ok := self.engine.(*dpos.Dpos) ……}3 DPOS引擎实现DPOS是共识引擎的具体实现,Engine接口定义了九个方法。3.1 Authorfunc (d *Dpos) Author(header *types.Header) (common.Address, error) { return header.Validator, nil}这个接口的意思是返回出块人。在POW共识中,返回的是header.Coinbase。\DPOS中Header增加了一个Validator,是有意将Coinbase和Validator的概念分开。Validator默认等于Coinbase,也可以设为不一样的地址。3.2 VerifyHeader验证header里的一些字段是否符合dpos共识规则。\符合以下判断都是错的:header.Time.Cmp(big.NewInt(time.Now().Unix())) &gt; 0len(header.Extra) &lt; extraVanity+extraSeal //32+65header.MixDigest != (common.Hash{})header.Difficulty.Uint64() != 1header.UncleHash != types.CalcUncleHash(nil)parent == nil || parent.Number.Uint64() != number-1 || parent.Hash() != header.ParentHash//与父块出块时间间隔小于了10(blockInterval)秒parent.Time.Uint64()+uint64(blockInterval) &gt; header.Time.Uint64()3.3 VerifyHeaders批量验证header3.4 VerifyUnclesdpos里不应有uncles。func (d *Dpos) VerifyUncles(chain consensus.ChainReader, block *types.Block) error { if len(block.Uncles()) &gt; 0 { return errors.New("uncles not allowed") } return nil}3.5 Prepare为Header准备部分字段:\Nonce为空;\Extra预留为32+65个0字节,Extra字段包括32字节的extraVanity前缀和65字节的extraSeal后缀,都为预留字节,extraSeal在区块Seal的时候写入验证人的签名。\Difficulty置为1;\Validator设置为signer;signer是在启动挖矿的时候设置的,其实就是本节点的验证人(Ethereum.validator)。func (d *Dpos) Prepare(chain consensus.ChainReader, header *types.Header) error { header.Nonce = types.BlockNonce{} number := header.Number.Uint64() //如果header.Extra不足32字节,则用0填充满32字节。 if len(header.Extra) &lt; extraVanity { header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, extraVanity-len(header.Extra))...) } header.Extra = header.Extra[:extraVanity] //header.Extra再填65字节 header.Extra = append(header.Extra, make([]byte, extraSeal)...) parent := chain.GetHeader(header.ParentHash, number-1) if parent == nil { return consensus.ErrUnknownAncestor } header.Difficulty = d.CalcDifficulty(chain, header.Time.Uint64(), parent) //header.Validator赋值为Dpos的signer。 header.Validator = d.signer return nil}关于难度在DPOS里,不需要求难度值,给定一个即可。func (d *Dpos) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int { return big.NewInt(1)}而在POW中,难度是根据父块和最新块的时间差动态调整的,小于10增加难度,大于等于20减小难度。block_diff = parent_diff + 难度调整 + 难度炸弹难度调整 = parent_diff // 2048 * MAX(1 - (block_timestamp - parent_timestamp) // 10, -99)难度炸弹 = INT(2^((block_number // 100000) - 2))关于singer调用API,人为设置本节点的验证人func (api *PrivateMinerAPI) SetValidator(validator common.Address) bool { api.e.SetValidator(validator) //e *Ethereum return true}func (self *Ethereum) SetValidator(validator common.Address) { self.lock.Lock() //lock sync.RWMutex self.validator = validator self.lock.Unlock()}节点启动挖矿时调用了dpos.Authorize将验证人赋值给了dpos.signerfunc (s *Ethereum) StartMining(local bool) error { validator, err := s.Validator() …… if dpos, ok := s.engine.(*dpos.Dpos); ok { wallet, err := s.accountManager.Find(accounts.Account{Address: validator}) if wallet == nil || err != nil { log.Error("Coinbase account unavailable locally", "err", err) return fmt.Errorf("signer missing: %v", err) } dpos.Authorize(validator, wallet.SignHash) } ……}func (s *Ethereum) Validator() (validator common.Address, err error) { s.lock.RLock() //lock sync.RWMutex validator = s.validator s.lock.RUnlock() ……}func (d *Dpos) Authorize(signer common.Address, signFn SignerFn) { d.mu.Lock() d.signer = signer d.signFn = signFn d.mu.Unlock()}3.6 Finalize&lt;span id="finalize"&gt;&lt;/span&gt;生成一个新的区块,不过不是最终的区块。该函数功能请看注释。func (d *Dpos) Finalize(……){ //把奖励打入Coinbase,拜占庭版本以后奖励3个eth,之前奖励5个 AccumulateRewards(chain.Config(), state, header, uncles) //调用选举,函数内部判断是否到了新一轮选举周期 err := epochContext.tryElect(genesis, parent) //每出一个块,将该块验证人的出块数+1,即更新DposContext.mintCntTrie。 updateMintCnt(parent.Time.Int64(), header.Time.Int64(), header.Validator, dposContext) //给区块设置header,transactions,Bloom,uncles; //给header设置TxHash,ReceiptHash,UncleHash; return types.NewBlock(header, txs, uncles, receipts), nil}3.7 Seal&lt;span id="seal"&gt;&lt;/span&gt;dpos的Seal主要是给新区块进行签名,即把签名写入header.Extra,返回最终状态的区块。\d.signFn是个函数类型的声明,首先源码定义了一个钱包接口SignHash用于给一段hash进行签名,然后将这个接口作为形参调用dpos.Authorize,这样d.signFn就被赋予了这个函数,而具体实现是keystoreWallet.SignHash,所以d.signFn的执行就是在执行keystoreWallet.SignHash。func (d *Dpos) Seal(chain consensus.ChainReader, block *types.Block, stop &lt;-chan struct{}) (*types.Block, error) { header := block.Header() number := header.Number.Uint64() // Sealing the genesis block is not supported if number == 0 { return nil, errUnknownBlock } now := time.Now().Unix() delay := NextSlot(now) - now if delay &gt; 0 { select { case &lt;-stop: return nil, nil //等到下一个出块时刻slot,如10秒1块的节奏,10秒内等到第10秒,11秒则要等到第20秒,以此类推。 case &lt;-time.After(time.Duration(delay) * time.Second): } } block.Header().Time.SetInt64(time.Now().Unix()) // time's up, sign the block sighash, err := d.signFn(accounts.Account{Address: d.signer}, sigHash(header).Bytes()) if err != nil { return nil, err } //将签名赋值给header.Extra的后缀。这里数组索引不会为负,因为在Prepare的时候,Extra就保留了32(前缀)+65(后缀)个字节。 copy(header.Extra[len(header.Extra)-extraSeal:], sighash) return block.WithSeal(header), nil}func (b *Block) WithSeal(header *Header) *Block { cpy := *header return &amp;Block{ header: &amp;cpy, transactions: b.transactions, uncles: b.uncles, // add dposcontext DposContext: b.DposContext, }}3.8 VerifySealSeal接口是区块产生的最后一道工序,也是各种共识算法最核心的实现,VerifySeal就是对这种封装的真伪验证。\\1)从epochTrie里获取到验证人列表,(epochTrie的key就是字面量“validator”,它全局唯一,每轮选举后都会被覆盖更新)再用header的时间计算本区块验证人所在列表的偏移量(作为验证人列表数组索引),获得验证人地址。validator, err := epochContext.lookupValidator(header.Time.Int64())2)用Dpos的签名还原出这个验证人的地址。两者进行对比,看是否一致,再用还原的地址和header.Validator对比看是否一致。if err := d.verifyBlockSigner(validator, header); err != nil { return err }func (d *Dpos) verifyBlockSigner(validator common.Address, header *types.Header) error { signer, err := ecrecover(header, d.signatures) if err != nil { return err } if bytes.Compare(signer.Bytes(), validator.Bytes()) != 0 { return ErrInvalidBlockValidator } if bytes.Compare(signer.Bytes(), header.Validator.Bytes()) != 0 { return ErrMismatchSignerAndValidator } return nil}其中:\header.Validator是在Prepare接口中被赋值的。\d.signatures这个签名是怎么赋值的?不要顾名思义它存的不是签名,它的类型是一种有名的缓存,(key,value)分别是(区块头hash,验证人地址),它的赋值也是在ecrecover里进行的。ecrecover根据区块头hash从缓存中获取到验证人地址,如果没有就从header.Extra的签名部分还原出验证人地址。3)VerifySeal经过上面两步验证后,最后这个操作待详细分析。return d.updateConfirmedBlockHeader(chain)3.9 APIs用于容纳API。func (d *Dpos) APIs(chain consensus.ChainReader) []rpc.API { return []rpc.API{{ Namespace: "dpos", Version: "1.0", Service: &amp;API{chain: chain, dpos: d}, Public: true, }}}它在eth包里被赋值具体APIapis = append(apis, s.engine.APIs(s.BlockChain())...)func (s *Ethereum) APIs() []rpc.API { apis := ethapi.GetAPIs(s.ApiBackend) // Append any APIs exposed explicitly by the consensus engine apis = append(apis, s.engine.APIs(s.BlockChain())...) // Append all the local APIs and return return append(apis, []rpc.API{ { Namespace: "eth", Version: "1.0", Service: NewPublicEthereumAPI(s), Public: true, }, { Namespace: "eth", Version: "1.0", Service: NewPublicMinerAPI(s), Public: true, }, { Namespace: "eth", Version: "1.0", Service: downloader.NewPublicDownloaderAPI(s.protocolManager.downloader, s.eventMux), Public: true, }, { Namespace: "miner", Version: "1.0", Service: NewPrivateMinerAPI(s), Public: false, }, { Namespace: "eth", Version: "1.0", Service: filters.NewPublicFilterAPI(s.ApiBackend, false), Public: true, }, { Namespace: "admin", Version: "1.0", Service: NewPrivateAdminAPI(s), }, { Namespace: "debug", Version: "1.0", Service: NewPublicDebugAPI(s), Public: true, }, { Namespace: "debug", Version: "1.0", Service: NewPrivateDebugAPI(s.chainConfig, s), }, { Namespace: "net", Version: "1.0", Service: s.netRPCService, Public: true, }, }...)}这些赋值的其实是结构体,通过结构体可以访问到自身的方法,这些结构体大多都是Ethereum,只不过区分了Namespace用于不同场景。type PublicEthereumAPI struct { e *Ethereum}type PublicMinerAPI struct { e *Ethereum}type PublicDownloaderAPI struct { d *Downloader mux *event.TypeMux installSyncSubscription chan chan interface{} uninstallSyncSubscription chan *uninstallSyncSubscriptionRequest}type PrivateMinerAPI struct { e *Ethereum}type PublicDebugAPI struct { eth *Ethereum}看看都有哪些API服务:&lt;img src="https://i.loli.net/2018/11/09...; width=350&gt;4 DPOS引擎如何驱动以太坊挖矿以太坊好比一台机器,生产区块,这台机器的引擎上面已经讲过了,接下来再看看这台机器是如何运作的。从控制台启动节点挖矿开始:&gt;miner.start()这个命令将会调用api的Start方法。4.1 以太坊启动时序图在mintLoop方法里,worker无限循环,阻塞监听stopper通道,每秒调用一次mintBlock。\用户主动停止以太坊节点的时候,stopper通道被关闭,worker就停止了。4.2 mintBlock挖矿函数分析这个函数的作用即用引擎(POW、DPOS)出块。在POW版本中,worker还需要启动agent(分为CpuAgent和何RemoteAgent两种实现),agent进行Seal操作。在DPOS中,去掉了agent这一层,直接在mintBlock里Seal。mintLoop每秒都调用mintBlock,但并非每秒都出块,逻辑在下面分析。func (self *worker) mintLoop() { ticker := time.NewTicker(time.Second).C for { select { case now := &lt;-ticker: self.mintBlock(now.Unix()) case &lt;-self.stopper: close(self.quitCh) self.quitCh = make(chan struct{}, 1) self.stopper = make(chan struct{}, 1) return } }}func (self *worker) mintBlock(now int64) { engine, ok := self.engine.(*dpos.Dpos) if !ok { log.Error("Only the dpos engine was allowed") return } err := engine.CheckValidator(self.chain.CurrentBlock(), now) if err != nil { switch err { case dpos.ErrWaitForPrevBlock, dpos.ErrMintFutureBlock, dpos.ErrInvalidBlockValidator, dpos.ErrInvalidMintBlockTime: log.Debug("Failed to mint the block, while ", "err", err) default: log.Error("Failed to mint the block", "err", err) } return } work, err := self.createNewWork() if err != nil { log.Error("Failed to create the new work", "err", err) return } result, err := self.engine.Seal(self.chain, work.Block, self.quitCh) if err != nil { log.Error("Failed to seal the block", "err", err) return } self.recv &lt;- &amp;Result{work, result}}如时序图和源码所示,mintBlock函数包含3个主要方法:4.2.1 CheckValidator出块前验证该函数判断当前出块人(validator)是否与dpos规则计算得到的validator一样,同时判断是否到了出块时间点。func (self *worker) mintBlock(now int64) { …… //检查出块验证人validator是否正确 //CurrentBlock()是截止当前时间,最后加入到链的块 //CurrentBlock()是BlockChain.insert的时候赋的值 err := engine.CheckValidator(self.chain.CurrentBlock(), now) ……}func (d *Dpos) CheckValidator(lastBlock *types.Block, now int64) error { //检查是否到达出块间隔最后1秒(slot),出块间隔设置为10秒 if err := d.checkDeadline(lastBlock, now); err != nil { return err } dposContext, err := types.NewDposContextFromProto(d.db, lastBlock.Header().DposContext) if err != nil { return err } epochContext := &amp;EpochContext{DposContext: dposContext} //根据dpos规则计算:先从epochTrie里获得本轮选举周期的验证人列表 //然后根据当前时间计算偏移量,获得应该由谁挖掘当前块的验证人 validator, err := epochContext.lookupValidator(now) if err != nil { return err } //判断dpos规则计算得到的validator和d.signer即节点设置的validator是否一致 if (validator == common.Address{}) || bytes.Compare(validator.Bytes(), d.signer.Bytes()) != 0 { return ErrInvalidBlockValidator } return nil}func (d *Dpos) checkDeadline(lastBlock *types.Block, now int64) error { prevSlot := PrevSlot(now) nextSlot := NextSlot(now) //假如当前时间是1542117655,则prevSlot = 1542117650,nextSlot = 1542117660 if lastBlock.Time().Int64() &gt;= nextSlot { return ErrMintFutureBlock } // nextSlot-now &lt;= 1是要求出块时间需要接近出块间隔最后1秒 if lastBlock.Time().Int64() == prevSlot || nextSlot-now &lt;= 1 { return nil } //时间不到,就返回等待错误 return ErrWaitForPrevBlock}CheckValidator()判断不通过则跳出mintBlock,继续下一秒mintBlock循环。\判断通过进入createNewWork()。4.2.2 createNewWork生成新块并定型这个函数涉及具体执行交易、生成收据和日志、向监听者发送相关事件、调用dpos引擎Finalize打包、将未Seal的新块加入未确认块集等事项。4.2.2.1 挖矿时序图func (self *worker) createNewWork() (*Work, error) { self.mu.Lock() defer self.mu.Unlock() self.uncleMu.Lock() defer self.uncleMu.Unlock() self.currentMu.Lock() defer self.currentMu.Unlock() tstart := time.Now() parent := self.chain.CurrentBlock() tstamp := tstart.Unix() if parent.Time().Cmp(new(big.Int).SetInt64(tstamp)) &gt;= 0 { tstamp = parent.Time().Int64() + 1 } // this will ensure we're not going off too far in the future if now := time.Now().Unix(); tstamp &gt; now+1 { wait := time.Duration(tstamp-now) * time.Second log.Info("Mining too far in the future", "wait", common.PrettyDuration(wait)) time.Sleep(wait) } num := parent.Number() header := &amp;types.Header{ ParentHash: parent.Hash(), Number: num.Add(num, common.Big1), GasLimit: core.CalcGasLimit(parent), GasUsed: new(big.Int), Extra: self.extra, Time: big.NewInt(tstamp), } // Only set the coinbase if we are mining (avoid spurious block rewards) if atomic.LoadInt32(&amp;self.mining) == 1 { header.Coinbase = self.coinbase } if err := self.engine.Prepare(self.chain, header); err != nil { return nil, fmt.Errorf("got error when preparing header, err: %s", err) } // If we are care about TheDAO hard-fork check whether to override the extra-data or not if daoBlock := self.config.DAOForkBlock; daoBlock != nil { // Check whether the block is among the fork extra-override range limit := new(big.Int).Add(daoBlock, params.DAOForkExtraRange) if header.Number.Cmp(daoBlock) &gt;= 0 &amp;&amp; header.Number.Cmp(limit) &lt; 0 { // Depending whether we support or oppose the fork, override differently if self.config.DAOForkSupport { header.Extra = common.CopyBytes(params.DAOForkBlockExtra) } else if bytes.Equal(header.Extra, params.DAOForkBlockExtra) { header.Extra = []byte{} // If miner opposes, don't let it use the reserved extra-data } } } // Could potentially happen if starting to mine in an odd state. err := self.makeCurrent(parent, header) if err != nil { return nil, fmt.Errorf("got error when create mining context, err: %s", err) } // Create the current work task and check any fork transitions needed work := self.current if self.config.DAOForkSupport &amp;&amp; self.config.DAOForkBlock != nil &amp;&amp; self.config.DAOForkBlock.Cmp(header.Number) == 0 { misc.ApplyDAOHardFork(work.state) } pending, err := self.eth.TxPool().Pending() if err != nil { return nil, fmt.Errorf("got error when fetch pending transactions, err: %s", err) } txs := types.NewTransactionsByPriceAndNonce(self.current.signer, pending) work.commitTransactions(self.mux, txs, self.chain, self.coinbase) // compute uncles for the new block. var ( uncles []*types.Header badUncles []common.Hash ) for hash, uncle := range self.possibleUncles { if len(uncles) == 2 { break } if err := self.commitUncle(work, uncle.Header()); err != nil { log.Trace("Bad uncle found and will be removed", "hash", hash) log.Trace(fmt.Sprint(uncle)) badUncles = append(badUncles, hash) } else { log.Debug("Committing new uncle to block", "hash", hash) uncles = append(uncles, uncle.Header()) } } for _, hash := range badUncles { delete(self.possibleUncles, hash) } // Create the new block to seal with the consensus engine if work.Block, err = self.engine.Finalize(self.chain, header, work.state, work.txs, uncles, work.receipts, work.dposContext); err != nil { return nil, fmt.Errorf("got error when finalize block for sealing, err: %s", err) } work.Block.DposContext = work.dposContext // update the count for the miner of new block // We only care about logging if we're actually mining. if atomic.LoadInt32(&amp;self.mining) == 1 { log.Info("Commit new mining work", "number", work.Block.Number(), "txs", work.tcount, "uncles", len(uncles), "elapsed", common.PrettyDuration(time.Since(tstart))) self.unconfirmed.Shift(work.Block.NumberU64() - 1) } return work, nil}4.2.2.2 准备区块头先调用dpos引擎的Prepare填充区块头字段。 …… num := parent.Number() header := &amp;types.Header{ ParentHash: parent.Hash(), Number: num.Add(num, common.Big1), GasLimit: core.CalcGasLimit(parent), GasUsed: new(big.Int), Extra: self.extra, Time: big.NewInt(tstamp), } // 确保出块时间不要偏离太大(过早或过晚) if atomic.LoadInt32(&amp;self.mining) == 1 { header.Coinbase = self.coinbase } self.engine.Prepare(self.chain, header) ……此时,即将产生的区块Header的GasUsed和Extra都为空,Extra通过前面引擎分析的时候,我们知道会在Prepare里用0字节填充32+65的前后缀,除了Extra,Prepare还将填充其他的Header字段(详见3.5 Prepare分析),当Prepare执行完成,大部分字段都设置好了,还有少部分待填。4.2.2.3 准备挖矿环境接下来把父块和本块的header传给makeCurrent方法执行。 err := self.makeCurrent(parent, header) if err != nil { return nil, fmt.Errorf("got error when create mining context, err: %s", err) } // Create the current work task and check any fork transitions needed work := self.current if self.config.DAOForkSupport &amp;&amp; self.config.DAOForkBlock != nil &amp;&amp; self.config.DAOForkBlock.Cmp(header.Number) == 0 { misc.ApplyDAOHardFork(work.state) }makeCurrent先新建stateDB和dposContext,然后组装一个Work结构体。func (self *worker) makeCurrent(parent *types.Block, header *types.Header) error { state, err := self.chain.StateAt(parent.Root()) if err != nil { return err } dposContext, err := types.NewDposContextFromProto(self.chainDb, parent.Header().DposContext) if err != nil { return err } work := &amp;Work{ config: self.config, signer: types.NewEIP155Signer(self.config.ChainId), state: state, dposContext: dposContext, ancestors: set.New(), family: set.New(), uncles: set.New(), header: header, createdAt: time.Now(), } // when 08 is processed ancestors contain 07 (quick block) for _, ancestor := range self.chain.GetBlocksFromHash(parent.Hash(), 7) { for _, uncle := range ancestor.Uncles() { work.family.Add(uncle.Hash()) } work.family.Add(ancestor.Hash()) work.ancestors.Add(ancestor.Hash()) } // Keep track of transactions which return errors so they can be removed work.tcount = 0 self.current = work return nil}Work结构体中,ancestors存储的是6个祖先块,family存储的是6个祖先块和它们各自的叔块,组装后的Work结构体赋值给*worker.current。4.2.2.3 从交易池获取pending交易集然后从交易池里获取所有pending状态的交易,这些交易按账户分组,每个账户里的交易按nonce排序后返回交易集,这里暂且叫S1:pending, err := self.eth.TxPool().Pending() //S1 = pendingtxs := types.NewTransactionsByPriceAndNonce(self.current.signer, pending)4.2.2.4 交易集结构化处理再然后通过NewTransactionsByPriceAndNonce函数对交易集进行结构化,它把S1集合里每个账户的第一笔交易分离出来作为heads集合,返回如下结构:return &amp;TransactionsByPriceAndNonce{ txs: txs, //S1集合中每个账户除去第一个交易后的交易集 heads: heads, //这个集合由每个账户的第一个交易组成 signer: signer, }4.2.2.5 交易执行过程分析调用commitTransactions方法,执行新区块包含的所有交易。这个方法是对处理后的交易集txs的具体执行,所谓执行交易,笼统地说就是把转账、合约或dpos交易类型的数据写入对应的内存Trie,再从Trie刷到本地DB中去。func (env *Work) commitTransactions(mux *event.TypeMux, txs *types.TransactionsByPriceAndNonce, bc *core.BlockChain, coinbase common.Address) { gp := new(core.GasPool).AddGas(env.header.GasLimit) var coalescedLogs []*types.Log for { // Retrieve the next transaction and abort if all done tx := txs.Peek() if tx == nil { break } // Error may be ignored here. The error has already been checked // during transaction acceptance is the transaction pool. // // We use the eip155 signer regardless of the current hf. from, _ := types.Sender(env.signer, tx) // Check whether the tx is replay protected. If we're not in the EIP155 hf // phase, start ignoring the sender until we do. if tx.Protected() &amp;&amp; !env.config.IsEIP155(env.header.Number) { log.Trace("Ignoring reply protected transaction", "hash", tx.Hash(), "eip155", env.config.EIP155Block) txs.Pop() continue } // Start executing the transaction env.state.Prepare(tx.Hash(), common.Hash{}, env.tcount) err, logs := env.commitTransaction(tx, bc, coinbase, gp) switch err { case core.ErrGasLimitReached: // Pop the current out-of-gas transaction without shifting in the next from the account log.Trace("Gas limit exceeded for current block", "sender", from) txs.Pop() case core.ErrNonceTooLow: // New head notification data race between the transaction pool and miner, shift log.Trace("Skipping transaction with low nonce", "sender", from, "nonce", tx.Nonce()) txs.Shift() case core.ErrNonceTooHigh: // Reorg notification data race between the transaction pool and miner, skip account = log.Trace("Skipping account with hight nonce", "sender", from, "nonce", tx.Nonce()) txs.Pop() case nil: // Everything ok, collect the logs and shift in the next transaction from the same account coalescedLogs = append(coalescedLogs, logs...) env.tcount++ txs.Shift() default: // Strange error, discard the transaction and get the next in line (note, the // nonce-too-high clause will prevent us from executing in vain). log.Debug("Transaction failed, account skipped", "hash", tx.Hash(), "err", err) txs.Shift() } } if len(coalescedLogs) &gt; 0 || env.tcount &gt; 0 { // make a copy, the state caches the logs and these logs get "upgraded" from pending to mined // logs by filling in the block hash when the block was mined by the local miner. This can // cause a race condition if a log was "upgraded" before the PendingLogsEvent is processed. cpy := make([]*types.Log, len(coalescedLogs)) for i, l := range coalescedLogs { cpy[i] = new(types.Log) *cpy[i] = *l } go func(logs []*types.Log, tcount int) { if len(logs) &gt; 0 { mux.Post(core.PendingLogsEvent{Logs: logs}) } if tcount &gt; 0 { mux.Post(core.PendingStateEvent{}) } }(cpy, env.tcount) }}该方法对结构化处理后的txs遍历执行,分为几步:Work.state.Prepare()\这是给StateDB设置交易hash、区块hash(此时为空)、交易索引。\StateDB是用来操作整个账户树也即world state trie的,每执行一笔交易就更改一次world state trie。\交易索引是指在对txs.heads进行遍历的时候的自增数,这个索引在本区块内唯一,因为它是本区块包含的所有pending交易涉及的账户及各账户下所有交易的总递增。commitTransactions函数对txs的遍历方式是:从遍历txs.heads开始,获取第一个账户的第一笔交易,然后获取同一账户的第二笔交易以此类推,如果该账户没有交易了,继续txs.heads的下一个账户。\也就是按账户优先级先遍历其下的所有交易,其次遍历所有账户(堆级别操作),txs结构化就是为这种循环方式准备的。func (self *StateDB) Prepare(thash, bhash common.Hash, ti int) { self.thash = thash self.bhash = bhash self.txIndex = ti}Work.commitTransaction()\执行单笔交易,先对stateDB这个大结构做一个版本号快照,也要对dpos的五棵树上下文即dposContext做一个备份,然后调用core.ApplyTransaction()方法,如果出错就退回快照和备份,执行成功后把交易加入Work.txs,(这个txs是为Finalize的时候传参用的,因为在遍历执行交易的时候会把原txs结构破坏,做个备份)交易收据加入Work.receipts,最后返回收据日志。func (env *Work) commitTransaction(tx *types.Transaction, bc *core.BlockChain, coinbase common.Address, gp *core.GasPool) (error, []*types.Log) { snap := env.state.Snapshot() dposSnap := env.dposContext.Snapshot() receipt, _, err := core.ApplyTransaction(env.config, env.dposContext, bc, &amp;coinbase, gp, env.state, env.header, tx, env.header.GasUsed, vm.Config{}) if err != nil { env.state.RevertToSnapshot(snap) env.dposContext.RevertToSnapShot(dposSnap) return err, nil } env.txs = append(env.txs, tx) env.receipts = append(env.receipts, receipt) return nil, receipt.Logs}看一下ApplyTransaction()是如何具体执行交易的:func ApplyTransaction(config *params.ChainConfig, dposContext *types.DposContext, bc *BlockChain, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *big.Int, cfg vm.Config) (*types.Receipt, *big.Int, error) { msg, err := tx.AsMessage(types.MakeSigner(config, header.Number)) if err != nil { return nil, nil, err } if msg.To() == nil &amp;&amp; msg.Type() != types.Binary { return nil, nil, types.ErrInvalidType } // Create a new context to be used in the EVM environment context := NewEVMContext(msg, header, bc, author) // Create a new environment which holds all relevant information // about the transaction and calling mechanisms. vmenv := vm.NewEVM(context, statedb, config, cfg) // Apply the transaction to the current state (included in the env) _, gas, failed, err := ApplyMessage(vmenv, msg, gp) if err != nil { return nil, nil, err } if msg.Type() != types.Binary { if err = applyDposMessage(dposContext, msg); err != nil { return nil, nil, err } } // Update the state with pending changes var root []byte if config.IsByzantium(header.Number) { statedb.Finalise(true) } else { root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes() } usedGas.Add(usedGas, gas) // Create a new receipt for the transaction, storing the intermediate root and gas used by the tx // based on the eip phase, we're passing wether the root touch-delete accounts. receipt := types.NewReceipt(root, failed, usedGas) receipt.TxHash = tx.Hash() receipt.GasUsed = new(big.Int).Set(gas) // if the transaction created a contract, store the creation address in the receipt. if msg.To() == nil { receipt.ContractAddress = crypto.CreateAddress(vmenv.Context.Origin, tx.Nonce()) } // Set the receipt logs and create a bloom for filtering receipt.Logs = statedb.GetLogs(tx.Hash()) receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) return receipt, gas, err}NewEVMContext是构建一个EVM执行环境,这个环境如下:return vm.Context{ //是否能够转账函数,会判断发起交易账户余额是否大于转账数量 CanTransfer: CanTransfer, //转账函数,给转账地址减去转账额,同时给接收地址加上转账额 Transfer: Transfer, //区块头hash GetHash: GetHashFn(header, chain), Origin: msg.From(), Coinbase: beneficiary, BlockNumber: new(big.Int).Set(header.Number), Time: new(big.Int).Set(header.Time), Difficulty: new(big.Int).Set(header.Difficulty), GasLimit: new(big.Int).Set(header.GasLimit), GasPrice: new(big.Int).Set(msg.GasPrice()),}==beneficiary是Coinbase,这里是指如果没有指定coinbase就从header里获取validator的地址作为coinbase。==\NewEVM是创建一个携带了EVM环境和编译器的虚拟机。然后调用ApplyMessage(),这个函数最主要的是对当前交易进行状态转换TransitionDb()。TransitionDb详解func (st *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big.Int, failed bool, err error) { if err = st.preCheck(); err != nil { return } msg := st.msg sender := st.from() // err checked in preCheck homestead := st.evm.ChainConfig().IsHomestead(st.evm.BlockNumber) contractCreation := msg.To() == nil // Pay intrinsic gas // TODO convert to uint64 intrinsicGas := IntrinsicGas(st.data, contractCreation, homestead) if intrinsicGas.BitLen() &gt; 64 { return nil, nil, nil, false, vm.ErrOutOfGas } if err = st.useGas(intrinsicGas.Uint64()); err != nil { return nil, nil, nil, false, err } var ( evm = st.evm // vm errors do not effect consensus and are therefor // not assigned to err, except for insufficient balance // error. vmerr error ) if contractCreation { ret, _, st.gas, vmerr = evm.Create(sender, st.data, st.gas, st.value) } else { // Increment the nonce for the next transaction st.state.SetNonce(sender.Address(), st.state.GetNonce(sender.Address())+1) ret, st.gas, vmerr = evm.Call(sender, st.to().Address(), st.data, st.gas, st.value) } if vmerr != nil { log.Debug("VM returned with error", "err", vmerr) // The only possible consensus-error would be if there wasn't // sufficient balance to make the transfer happen. The first // balance transfer may never fail. if vmerr == vm.ErrInsufficientBalance { return nil, nil, nil, false, vmerr } } requiredGas = new(big.Int).Set(st.gasUsed()) st.refundGas() st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(st.gasUsed(), st.gasPrice)) return ret, requiredGas, st.gasUsed(), vmerr != nil, err}其中preCheck检查当前交易nonce和发送账户当前nonce是否一致,同时检查发送账户余额是否大于GasLimit,足够的话就先将余额减去gaslimit(过度状态转换),不足就返回一个常见的错误:“insufficient balance to pay for gas”。IntrinsicGas()是计算交易所需固定费用:如果是创建合约交易,固定费用为53000gas,转账交易固定费用是21000gas,如果交易携带数据,这个数据对于创建合约是合约代码数据,对于转账交易是转账的附加说明数据,这些数据按字节存储收费,非0字节每位68gas,0字节每位4gas,总计起来就是执行交易所需的gas费。useGas()判断提供的gas是否满足上面计算出的内部所需费用,足够的话从提供的gas里扣除内部所需费用(状态转换)。因为ApplyTransaction传的参数msg已经将dpos类型且to为空的交易排除出去了。所以当这里msg.To() == nil的时候,只剩下msg.Type == 0这一种原始交易的可能了。msg.To为空说明该交易不是转账、不是合约调用,只能是创建合约交易,根据msg.To是否为空,分两种情况,Create创建合约和Call调用合约,这两种情况都覆盖了转账行为。1)if contractCreation{…},即to==nil,说明是创建合约交易,调用evm.Create()。// Create creates a new contract using code as deployment code.func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { // Depth check execution. Fail if we're trying to execute above the // limit. if evm.depth &gt; int(params.CallCreateDepth) { return nil, common.Address{}, gas, ErrDepth } if !evm.CanTransfer(evm.StateDB, caller.Address(), value) { return nil, common.Address{}, gas, ErrInsufficientBalance } // Ensure there's no existing contract already at the designated address nonce := evm.StateDB.GetNonce(caller.Address()) evm.StateDB.SetNonce(caller.Address(), nonce+1) contractAddr = crypto.CreateAddress(caller.Address(), nonce) contractHash := evm.StateDB.GetCodeHash(contractAddr) if evm.StateDB.GetNonce(contractAddr) != 0 || (contractHash != (common.Hash{}) &amp;&amp; contractHash != emptyCodeHash) { return nil, common.Address{}, 0, ErrContractAddressCollision } // Create a new account on the state snapshot := evm.StateDB.Snapshot() evm.StateDB.CreateAccount(contractAddr) if evm.ChainConfig().IsEIP158(evm.BlockNumber) { evm.StateDB.SetNonce(contractAddr, 1) } evm.Transfer(evm.StateDB, caller.Address(), contractAddr, value) // initialise a new contract and set the code that is to be used by the // E The contract is a scoped evmironment for this execution context // only. contract := NewContract(caller, AccountRef(contractAddr), value, gas) contract.SetCallCode(&amp;contractAddr, crypto.Keccak256Hash(code), code) if evm.vmConfig.NoRecursion &amp;&amp; evm.depth &gt; 0 { return nil, contractAddr, gas, nil } ret, err = run(evm, snapshot, contract, nil) // check whether the max code size has been exceeded maxCodeSizeExceeded := evm.ChainConfig().IsEIP158(evm.BlockNumber) &amp;&amp; len(ret) &gt; params.MaxCodeSize // if the contract creation ran successfully and no errors were returned // calculate the gas required to store the code. If the code could not // be stored due to not enough gas set an error and let it be handled // by the error checking condition below. if err == nil &amp;&amp; !maxCodeSizeExceeded { createDataGas := uint64(len(ret)) * params.CreateDataGas if contract.UseGas(createDataGas) { evm.StateDB.SetCode(contractAddr, ret) } else { err = ErrCodeStoreOutOfGas } } // When an error was returned by the EVM or when setting the creation code // above we revert to the snapshot and consume any gas remaining. Additionally // when we're in homestead this also counts for code storage gas errors. if maxCodeSizeExceeded || (err != nil &amp;&amp; (evm.ChainConfig().IsHomestead(evm.BlockNumber) || err != ErrCodeStoreOutOfGas)) { evm.StateDB.RevertToSnapshot(snapshot) if err != errExecutionReverted { contract.UseGas(contract.Gas) } } // Assign err if contract code size exceeds the max while the err is still empty. if maxCodeSizeExceeded &amp;&amp; err == nil { err = errMaxCodeSizeExceeded } return ret, contractAddr, contract.Gas, err}注意这里传入的gas是已经扣除了固定费用的剩余gas。evm是基于栈的简单虚拟机,最多支持1024栈深度,超过就报错。然后在这里调用evmContext的CanTransfer()判断发起交易地址余额是否大于转账数量,是的话就将发起交易的账户的nonce+1。生成合约账户地址:合约账户的地址生成规则是,由发起交易的地址和该nonce计算生成,生成地址后,此时仅有地址,根据地址获取该合约账户的nonce应该为0、codeHash应该为空hash,不符合这些判断说明地址冲突,报错退出。紧接着创建一个新账户evm.StateDB.CreateAccount(contractAddr),这个函数创建的是一个普通账户(即EOA和Contract账户的未分化形式)。\新账户的地址就是上面计算生成的地址,Nonce设为0,Balance设为0,但是如果之前已存在同样地址的账户那么Balance就设为之前账户的余额,CodeHash设为空hash注意不是空。EIP158之后的新账号nonce设为1。evm.Transfer():如果创建账户的时候有资助代币(eth),则将代币从发起地址转移到新账户地址。然后NewContract()构建一个合约上下文环境contract。SetCallCode(),给contract环境对象设置入参Code、CodeHash。run():EVM编译、执行合约的创建,执行EVM栈操作。\run执行返回合约body字节码(code storage),如果长度超过24576也存储不了,然后计算存储这个合约字节码的gas费用=长度*200。最后给stateObject对象设置code,给账户(Account)设置codeHash,这样那个新账户就成了一个合约账户。2)else{…}如果不是创建合约交易(即to!=nil),调用evm.Call()。这个Call是执行合约交易,包括转账类型的交易、调用合约交易。func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) { if evm.vmConfig.NoRecursion &amp;&amp; evm.depth &gt; 0 { return nil, gas, nil } // Fail if we're trying to execute above the call depth limit if evm.depth &gt; int(params.CallCreateDepth) { return nil, gas, ErrDepth } // Fail if we're trying to transfer more than the available balance if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { return nil, gas, ErrInsufficientBalance } var ( to = AccountRef(addr) snapshot = evm.StateDB.Snapshot() ) if !evm.StateDB.Exist(addr) { precompiles := PrecompiledContractsHomestead if evm.ChainConfig().IsByzantium(evm.BlockNumber) { precompiles = PrecompiledContractsByzantium } if precompiles[addr] == nil &amp;&amp; evm.ChainConfig().IsEIP158(evm.BlockNumber) &amp;&amp; value.Sign() == 0 { return nil, gas, nil } evm.StateDB.CreateAccount(addr) } evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value) // initialise a new contract and set the code that is to be used by the // E The contract is a scoped environment for this execution context // only. contract := NewContract(caller, to, value, gas) contract.SetCallCode(&amp;addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr)) ret, err = run(evm, snapshot, contract, input) // When an error was returned by the EVM or when setting the creation code // above we revert to the snapshot and consume any gas remaining. Additionally // when we're in homestead this also counts for code storage gas errors. if err != nil { evm.StateDB.RevertToSnapshot(snapshot) if err != errExecutionReverted { contract.UseGas(contract.Gas) } } return ret, contract.Gas, err}Call函数先来三个判断:evm编译器被禁用或者evm执行栈深超过1024或者转账数额超过余额就报错。注意以下几个Call步骤和Create的区别:evm.StateDB.Exist(addr)是从stateObjects这个所有stateObject的map集合中查找是否存to地址,如果不存在,则调用evm.StateDB.CreateAccount(addr)创建一个新账户,这和Create里调的是同一个函数,即CreateAccount创建的是一个普通账户。evm.Transfer():将代币从发起地址转移到to地址(包括纯转账类型的交易、给合约地址转入代币等)NewContract()构建一个合约上下文环境contract。SetCallCode():这个函数和Create里的SetCallCode()传的入参不一样,它是从to地址获取code,然后才给to账户设置code、codehash等,这隐含了两种可能性,如果获取到了code那么这个账户自然是合约账户,如果没有获取到,那这个账户就是外部拥有账户(EOA)run():EVM编译、执行EVM栈操作。这个Call除了转账、调用合约,还包括执dpos交易,当交易是dpos类型的交易的时候,它其实是个空合约,之所以要执行dpos这类空合约是要计算其gas。TransitionDB()在交易执行完后,将剩余gas返退回给发起者账户地址,同时把挖矿节点设置的Coinbase的余额增加上消耗的gas。&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;除了Call(),evm还提供了另外3个合约调用方法:\CallCode(),已经弃用,由DelegateCall()替代\DelegateCall()\StaticCall()暂时未用type CallContext interface { // Call another contract Call(env *EVM, me ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error) // Take another's contract code and execute within our own context CallCode(env *EVM, me ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error) // Same as CallCode except sender and value is propagated from parent to child scope DelegateCall(env *EVM, me ContractRef, addr common.Address, data []byte, gas *big.Int) ([]byte, error) // Create a new contract Create(env *EVM, me ContractRef, data []byte, gas, value *big.Int) ([]byte, common.Address, error)}我们上面讨论的是交易,根据黄皮书的定义交易就两种:创建合约、消息调用。区分二者的标志就是to是否为空。由外部用户触发的才能叫交易,所以用户发起创建合约、用户发起合约调用都叫交易,对应的就是我们上面分析的Create和Call两种情况。转账这种交易执行的是Call()而不是Create(),因为to不为空。用户调用合约A,这叫交易,执行的是Call(),紧接着A里边又调用了合约B,那么这不叫交易叫内部调用,执行的就不是Call(),而是DelegateCall()了,Call和DelegateCall的区别是:Call总是直接改变to的的storage,而DelegateCall改变的是caller(即A)的storage,而不是to的storage。那个NewContract上下文构造函数就是做msg.caller、to等指向工作的。\至于DelegateCall为什么替代CallCode,是修改了一点即msg.sender在DelegateCall里永远指向用户,而CallCode里的sender则指向的是caller。ApplyMessage()结束后,判断一下是否属于DPOS交易,是的话就执行applyDposMessage中对应的交易,即dpos的四种交易:成为候选人、退出候选人、投票、取消投票,具体执行就是更改对应的Trie。\然后调用statedb.Finalise删除掉空账户,再更新状态树,得到最新的world state root hash(intermediate root)。\然后生成一个收据,收据里包括:交易的hash\执行成败状态\消耗的费用\若是创建合约交易就把合约地址也写到收据的ContractAddress字段里\日志\Bloom关于日志,栈操作的时候会记录下日志,日志信息如下:type Log struct { // Consensus fields: // address of the contract that generated the event Address common.Address json:“address” gencodec:“required” // list of topics provided by the contract. Topics []common.Hashjson:“topics” gencodec:“required” // supplied by the contract, usually ABI-encoded Data []bytejson:“data” gencodec:“required” // Derived fields. These fields are filled in by the node // but not secured by consensus. // block in which the transaction was included BlockNumber uint64json:“blockNumber” // hash of the transaction TxHash common.Hashjson:“transactionHash” gencodec:“required” // index of the transaction in the block TxIndex uintjson:“transactionIndex” gencodec:“required” // hash of the block in which the transaction was included BlockHash common.Hashjson:“blockHash” // index of the log in the receipt Index uintjson:“logIndex” gencodec:“required” // The Removed field is true if this log was reverted due to a chain reorganisation. // You must pay attention to this field if you receive logs through a filter query. Removed booljson:“removed”`}ApplyTransaction()最终返回收据。至此,单笔交易执行过程commitTransaction()结束。如此循环执行,直到所有交易执行完成。\在循环执行交易的过程中,我们把所有交易收据的日志写入了一个集合,等交易全部执行完成,异步将这个日志集合向所有已注册的事件接收者发送:mux.Post(core.PendingLogsEvent{Logs: logs})mux.Post(core.PendingStateEvent{})func (mux *TypeMux) Post(ev interface{}) error { event := &TypeMuxEvent{ Time: time.Now(), Data: ev, } rtyp := reflect.TypeOf(ev) mux.mutex.RLock() if mux.stopped { mux.mutex.RUnlock() return ErrMuxClosed } subs := mux.subm[rtyp] mux.mutex.RUnlock() for _, sub := range subs { sub.deliver(event) } return nil}投递相应的事件到TypeMuxSubscription的postC通道中。func (s *TypeMuxSubscription) deliver(event *TypeMuxEvent) { // Short circuit delivery if stale event if s.created.After(event.Time) { return } // Otherwise deliver the event s.postMu.RLock() defer s.postMu.RUnlock() select { case s.postC <- event: case <-s.closing: }}关于事件的订阅、发送单列章节讲。commitTransactions()结束,现在回到了createNewWork中,代码继续遍历叔块和损坏的叔块,这段代码其实在DPOS中已经不需要了,因为DPOS中没有叔块,chainSideCh事件被删除,possibleUncles没有被赋值的机会了。4.2.2.6 Finalize定型新块把header、账户状态、交易、收据等信息传给dpos引擎去定型。参见3.6节。4.2.2.7 检查之前的块是否上链注意:是检查本节点之前挖的块是否上链,而不是当前挖出的块。当前块离上链为时尚早。每个以太坊节点会维护一个未确认块集,集合内有个环状容器,这个容器容纳仅由自身挖出的块,在最乐观的情况下(即连续由本节点挖出块的情况下),最大容纳5个块。当第6个连续的块由本节点挖出的时候就会触发unconfirmedBlocks.Shift()的执行(这里“执行”的上下文含义是满足函数内部的判断条件,而不仅仅指函数被调用,下同)。但大多数情况下,一个节点不会连续出块,那么可能在本节点第二次挖出块的时候,当前区块链高度就已经超过之前挖出的那个块6个高度了,也会触发unconfirmedBlocks.Shift()执行。换句话说就是通常情况下检查自己出的前一个块有没有加入到链上。Shift的作用,是检查未确认块集,这个未确认集并不是说真的就全是一直未被加入到链上的块,而是当该节点满足上面两段描述的“执行”条件时,都会检查一下之前挖出的块有没有被确认(加入区块链),如果当前区块链高度,高于未确认集环状容器内那些块6个高度之后,那些块还没有被加入到链上,就从未确认块集合中删除那些块。这个函数的意思着重表达:在至少6个高度的==时间==之后,才会去检查是否加入到链上,至于上没上链它也不能改变什么,就是给本节点一个之前的块被怎么处理了的通知。为什么是这样的时点呢?可能是要留出6个高度的时间等所有节点都确认吧,后文再说。func (set *unconfirmedBlocks) Shift(height uint64) { set.lock.Lock() defer set.lock.Unlock() for set.blocks != nil { // Retrieve the next unconfirmed block and abort if too fresh next := set.blocks.Value.(*unconfirmedBlock) if next.index+uint64(set.depth) > height { break } // Block seems to exceed depth allowance, check for canonical status header := set.chain.GetHeaderByNumber(next.index) switch { case header == nil: log.Warn(“Failed to retrieve header of mined block”, “number”, next.index, “hash”, next.hash) case header.Hash() == next.hash: log.Info("???? block reached canonical chain", “number”, next.index, “hash”, next.hash) default: log.Info("⑂ block became a side fork", “number”, next.index, “hash”, next.hash) } // Drop the block out of the ring if set.blocks.Value == set.blocks.Next().Value { set.blocks = nil } else { //下面的代码处于循环中,实现对for set.blocks的迭代赋值 set.blocks = set.blocks.Move(-1) //指向最后一个环元素 set.blocks.Unlink(1) //删除原第一个 set.blocks = set.blocks.Move(1) //指向原第二个 } }}4.2.3 Seal封装新块为最终状态这里就是调用dpos引擎的Seal规则了,即给区块签名,参见3.7节。func (self *worker) mintBlock(now int64) { …… result, err := self.engine.Seal(self.chain, work.Block, self.quitCh) ……}这个result和work对象都被发送到self.recv通道中去了。func (self *worker) mintBlock(now int64) { …… self.recv <- &Result{work, result} ……}4.3 新块入库、广播work.wait()在geth运行的时候就监听了work.recv通道,它做了如下几件事:func (self *worker) wait() { for { for result := range self.recv { atomic.AddInt32(&self.atWork, -1) if result == nil || result.Block == nil { continue } block := result.Block work := result.Work // Update the block hash in all logs since it is now available and not when the // receipt/log of individual transactions were created. for _, r := range work.receipts { for _, l := range r.Logs { l.BlockHash = block.Hash() } } for _, log := range work.state.Logs() { log.BlockHash = block.Hash() } stat, err := self.chain.WriteBlockAndState(block, work.receipts, work.state) if err != nil { log.Error(“Failed writing block to chain”, “err”, err) continue } // check if canon block and write transactions if stat == core.CanonStatTy { // implicit by posting ChainHeadEvent } // Broadcast the block and announce chain insertion event self.mux.Post(core.NewMinedBlockEvent{Block: block}) var ( events []interface{} logs = work.state.Logs() ) events = append(events, core.ChainEvent{Block: block, Hash: block.Hash(), Logs: logs}) if stat == core.CanonStatTy { events = append(events, core.ChainHeadEvent{Block: block}) } self.chain.PostChainEvents(events, logs) // Insert the block into the set of pending ones to wait for confirmations self.unconfirmed.Insert(block.NumberU64(), block.Hash()) log.Info(“Successfully sealed new block”, “number”, block.Number(), “hash”, block.Hash()) } }}1)写入本节点数据库(WriteBlockAndState)当通道里接收到新区块后,wait就调用chain.WriteBlockAndState()里的WriteBlock()把区块写入数据库,区块的body部分和header部分独立存储在db中,body的key是“b”+blockNumber+blockHash,值是交易集、叔块集的rlp。header的key是“h”+blockNumber。2)Post NewMinedBlockEvent3)PostChainEvents4)将区块插入unconfirmedBlocks集合4.3.1 事件订阅发送机制Subscribe函数实现1个订阅者订阅多个事件。4.4 新块上链后续再贴上来…… ...

December 25, 2018 · 20 min · jiezi

以太坊构建DApps系列教程(二):构建TNS代币

在本系列关于使用以太坊构建DApps教程的第1部分中,我们引导大家做了两个版本的本地区块链进行开发:一个Ganache版本和一个完整的私有PoA版本。在这一部分中,我们将深入研究并构建我们的TNS代币:用户将使用代币对Story DAO中的提案进行投票。先决条件按照上一部分,启动并运行Ganache版本。或者,如果你没有从第一部分开始跟踪,则可以运行任何本地版本的区块链,但请确保你可以使用我们需要的工具连接到它。我们假设你有一个有效的私有区块链,能够通过终端应用程序在其控制台和操作系统终端中输入命令,或者在Windows上,通过Git Bash,Console,CMD Prompt,Powershell等应用程序输入命令。基本依赖为了开发我们的应用程序,我们可以使用几种框架和入门开发包中的一种:Dapp,eth-utils,Populus,Embark……等等。但我们会选择现在的生态系统之王Truffle。使用以下命令安装它:npm install -g truffle 这将使truffle命令无处不在。现在我们可以用truffle init启动项目。构建代币让我们直接进入它并构建我们的代币。它将是一个有点标准的千篇一律的ERC20代币。(你会看到这篇文章中那个更标准的。)首先,我们将引入一些依赖关系。OpenZeppelin库是经过实战考验的高质量的solidity合约,可用于扩展和构建合约。npm install openzeppelin-solidity 接下来,让我们创建一个新的代币文件:truffle create contract TNSToken truffle在这里生成的默认模板有点过时了,所以让我们更新它:pragma solidity ^0.4.24;contract TNStoken { constructor() public { }}到目前为止,代币合约的构造函数应该与合约本身一样被调用,但为了清楚起见,它被更改为constructor。它也应该总是有一个修饰符告诉编译器谁被允许部署和与此合约交互(public意味着每个人)。SafeMath我们将在这种情况下使用的唯一Zeppelin合约是他们的SafeMath合约。在Solidity中,我们使用import关键字导入合约,而编译器通常不需要完整路径,只需要相对的路径,如下所示:pragma solidity ^0.4.24;import “../node_modules/openzeppelin-solidity/contracts/math/SafeMath.sol”;contract TNStoken { using SafeMath for uint256; constructor() public { }}那么,什么是SafeMath?很久以前,由于代码中的数学问题,出现了1840亿比特币的问题。为了防止类似于这些问题(并非特别只在以太坊中可能存在这一问题),SafeMath库仍然存在。当两个数字具有MAX_INT大小(即操作系统中的最大可能数量)时,将它们相加会使值wrap around重新归零,就像汽车的里程表在达到999999公里后重置为0。所以SafeMath库具有以下功能:/*** @dev Adds two numbers, throws on overflow./function add(uint256 a, uint256 b) internal pure returns (uint256 c) { c = a + b; assert(c >= a); return c;}此函数可以防止此问题:它检查两个数字的总和是否仍然大于两个操作数中的每一个。虽然在撰写Solidity合约时犯下如此愚蠢的错误并不容易,但保持安全比抱歉更好。通过using SafeMath for uint256,我们用这些“安全”版本替换Solidity(256bit unsigned - aka positive-only - whole numbers)中的标准uint256数字。而不是像这样求和数:sum=someBigNumber+someBiggerNumber,我们将这样求和:sum=someBigNumber.add(someBiggerNumber),从而在我们的计算中是安全的。来自Scratch的ERC20我们的数学计算安全了,我们可以创建我们的代币。ERC20是一个定义明确的标准,所以作为参考,我们将它添加到合约中。在这里阅读代币标准 。所以ERC20代币应该具有的功能是:pragma solidity ^0.4.24;import “../node_modules/openzeppelin-solidity/contracts/math/SafeMath.sol”;contract ERC20 { function totalSupply() public view returns (uint256); function balanceOf(address who) public view returns (uint256); function transfer(address to, uint256 value) public returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); function allowance(address owner, address spender) public view returns (uint256); function transferFrom(address from, address to, uint256 value) public returns (bool); function approve(address spender, uint256 value) public returns (bool); event Approval(address indexed owner, address indexed spender, uint256 value);}contract TNStoken { using SafeMath for uint256; constructor() public { }}这可能看起来很复杂,但实际上非常简单。这是我们代币需要具有的函数的“目录”,我们将逐个构建它们,解释每个函数的含义。考虑上面的代币接口。在创建Story DAO应用程序时,我们将看到它如何以及为何有用。基本余额开始吧。代币实际上只是以太坊区块链中的“电子表格”,如下所示:NameAmountBruno4000Joe5000Anne0Mike300所以让我们创建一个mapping,它基本上就像合约中的电子表格:mapping(address => uint256) balances; 根据上面的接口,这需要伴随一个balanceOf函数,它可以读取此表:function balanceOf(address _owner) public view returns (uint256) { return balances[owner];}函数balanceOf接受一个参数:owner是public(可以被任何人使用),是一个view函数(意思是它可以自由使用——不需要交易),并返回一个uint256编码,地址所有者的余额放在里面。每个人的代币余额都是公开可读的。总供应量知道代币的总供应量对于其用户和代币跟踪应用程序非常重要,所以让我们定义一个合约属性(变量)来跟踪这个和另一个自由函数来读取它:uint256 totalSupply;function totalSupply() public view returns (uint256) { return totalSupply;}发送代币接下来,让我们确保一些代币的所有者可以将它们发送给其他人。我们还想知道发送何时发生,因此我们也将定义发送事件。Transfer事件允许我们通过JavaScript监听区块链中的传输,以便我们的应用程序可以知道何时发出这些事件,而不是不断地手动检查传输是否发生。事件与合约中的变量一起声明,并使用emit关键字发出。我们现在将以下内容添加到合约中:event Transfer(address indexed from, address indexed to, uint256 value);function transfer(address _to, uint256 _value) public returns (bool) { require(_to != address(0)); require(_value <= balances[msg.sender]); balances[msg.sender] = balances[msg.sender].sub(_value); balances[_to] = balances[_to].add(_value); emit Transfer(msg.sender, _to, _value); return true;}此函数接受两个参数:_to,它是将接收代币的目标地址,以及value,即代币的数量。重要的是要记住,value是代币的最小单位数,而不是整个单位。因此,如果一个代币被声明具有10位小数的话,那么为了发送一个代币,你将发送10000000000。这种粒度级别允许我们处理极小数量。该函数是公共的,这意味着任何人都可以使用它,包括其他合约和用户,并且如果操作成功则返回true。然后该功能进行一些健全性检查。首先,它检查目标地址是否为空地址。换句话说,不得将代币必须正常发送。接下来,它通过比较它们的余额(balances[msg.sender] )和传入的发送值来检查发件人是否甚至被允许发送这么多代币。如果这些检查中的任何一个失败,该函数将拒绝该交易并失败。它将退还所发送的任何代币,但是在此之前用于执行该功能的gas将被花费。接下来的两行从发件人的余额中减去代币数量,并将该金额添加到目的地余额中。然后使用emit事件,并传入一些值:发件人,收件人和金额。现在,任何订阅了此合约上的发送事件的客户都将收到此事件的通知。好的,现在我们的代币持有者可以发送代币。信不信由你,这就是基本代币所需要的一切。但我们已经要超越了这一点,并增加了一些功能。津贴有时可能会允许第三方退出其他帐户的余额。这对于可能促进游戏内购买,去中心化交易等的游戏应用非常有用。我们通过构建一个名为allowance的多维mapping实现这一点,该mapping存储了所有这些权限。我们添加以下内容:mapping (address => mapping (address => uint256)) internal allowed;event Approval(address indexed owner, address indexed spender, uint256 value);这个事件就在那里,以便应用程序可以知道有人预先批准了其他人的余额支出,一个有用的功能,以及标准的一部分。映射将地址与另一个映射相结合,该映射将地址与数字组合在一起,它基本上形成了一个像这样的电子表格:所以Bob的余额可能由Mary支付,最多可达1000个代币,Billy最多可达50个代币。Bob可以将Mary的余额花费750代币。Billy的余额最多可以由Mary花费300个,而Joe花费1500。鉴于此映射是internal映射,它只能由此合约中的函数和使用此合约作为基础的合约使用。要批准其他人从你的帐户中扣款,你可以使用允许使用代币的人的地址,允许他们支付的金额以及你发出Approval事件的功能来调用approve功能:function approve(address _spender, uint256 _value) public returns (bool) { allowed[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); return true;}我们还需要一种方法来读取用户可以从其他用户的帐户中花费多少:function allowance(address _owner, address _spender) public view returns (uint256) { return allowed[_owner][_spender];}所以它是另一个read only函数(view),这意味着它可以自由执行。它只是读取剩余的可提取余额。那么如何为别人发送?使用新的transferFrom功能:function transferFrom(address _from, address _to, uint256 _value) public returns (bool) { require(_to != address(0)); require(_value <= balances[_from]); require(_value <= allowed[_from][msg.sender]); balances[_from] = balances[_from].sub(_value); balances[_to] = balances[_to].add(_value); allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value); emit Transfer(_from, _to, _value); return true;}和以前一样,有健全性检查:目标地址不能是空地址,因此不要将代币发送到不存在的地方。发送的值还需要不仅小于或等于发送值当前帐户的余额,而且还需要小于或等于消息发送者(发起此交易的地址)仍然允许为他们花费的余额。接下来,更新余额并使允许的余额与发出有关发送事件之前的余额同步。注意:代币持有者可以在不更新allowed映射的情况下allowed代币。如果代币持有者使用transfer手动发送代币,则会发生这种情况。在这种情况下,持有人的代币可能比第三方可以支付的额外费用少。通过批准和许可,我们还可以创建让代币持有者增加或减少某人津贴的功能,而不是完全覆盖该值。尝试将此作为练习,然后参考下面的源代码以获得解决方案。function increaseApproval(address _spender, uint _addedValue) public returns (bool) { allowed[msg.sender][_spender] = ( allowed[msg.sender][_spender].add(_addedValue)); emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); return true;}function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) { uint oldValue = allowed[msg.sender][_spender]; if (_subtractedValue > oldValue) { allowed[msg.sender][_spender] = 0; } else { allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue); } emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); return true;}构造函数到目前为止,我们只是建立了一个代币“合约”。但是这个标记是什么?它叫什么?它有多少位小数?我们如何使用它?在一开始,我们定义了一个constructor函数。现在,让我们完成它的主体并添加属性name,symbol和decimals:string public name;string public symbol;uint8 public decimals;constructor(string _name, string _symbol, uint8 _decimals, uint256 _totalSupply) public { name = _name; symbol = symbol; decimals = decimals; totalSupply = totalSupply;}这样做可以让我们稍后重复使用同一类型的其他代币。但是,当我们确切知道我们正在构建的内容时,让我们对这些值进行硬编码:string public name;string public symbol;uint8 public decimals;constructor() public { name = “The Neverending Story Token; symbol = “TNS”; decimals = 18; totalSupply = 100 * 106 * 1018;}显示代币信息时,各种以太坊工具和平台会读取这些详细信息。将合约部署到以太坊网络时会自动调用构造函数,因此这些值将在部署时自动配置。关于totalSupply = 100106*1018,这句话只是让人们更容易阅读数字的一种方式。由于以太坊中的所有发送都是使用最小的以太单位或代币(包括小数)完成的,因此最小单位是小数点后18位小数。这就是说单个TNS代币为110**18。此外,我们想要1亿,所以10010**6或1001010101010*10。这使得数字比100000000000000000000000000更易读。替代开发方案或者,我们也可以扩展Zeppelin合约,修改一些属性,然后我们就拥有代币了。这就是大多数人所做的,但在处理可能数百万其他人的钱的软件时,我个人倾向于想知道我在代码中的确切内容,因此盲目代码重用在我的个人情况下是要最小化的。pragma solidity ^0.4.24;import “../node_modules/openzeppelin-solidity/contracts/math/SafeMath.sol”;import “../node_modules/openzeppelin-solidity/contracts/token/ERC827/ERC20Token.sol”;contract TNStoken is ERC20Token { using SafeMath for uint256; string public name; string public symbol; uint8 public decimals; uint256 totalSupply_; constructor() public { name = “The Neverending Story Token”; symbol = “TNS”; decimals = 18; totalSupply_ = 100 * 106 * 1018; }}在这种情况下,我们使用is符号来声明我们的代币是ERC20Token。这使得我们的代币扩展了ERC20合约,后者又扩展了StandardToken,等等……无论哪种方式,我们的代币现在已准备就绪。但谁得到了多少代币以及如何开始?初始余额让我们给合约的制造者所有的代币。否则,代币将不会发送给任何人。通过在其末尾添加以下行来更新constructor:balances[msg.sender] = totalSupply_; 代币锁定看到我们打算使用代币作为投票权(即你在投票期间锁定了多少代币代表你的投票有多强大),我们需要一种方法来防止用户在投票后发送它们,否则我们的DAO将容易受到Sybil攻击的影响——拥有一百万个代币的个人可以注册100个地址,并通过将它们发送到不同的地址并使用新地址重新投票来获得1亿个代币的投票权。因此,我们将阻止发送与一个人投票额完全一样多的代币,对每个提案的每次投票都是累积的。这是我们在本文开头提到的扭曲。让我们在合约中添加以下事件:event Locked(address indexed owner, uint256 indexed amount);然后让我们添加锁定方法:function increaseLockedAmount(address _owner, uint256 _amount) onlyOwner public returns (uint256) { uint256 lockingAmount = locked[_owner].add(_amount); require(balanceOf(_owner) >= lockingAmount, “Locking amount must not exceed balance”); locked[_owner] = lockingAmount; emit Locked(_owner, lockingAmount); return lockingAmount;}function decreaseLockedAmount(address _owner, uint256 _amount) onlyOwner public returns (uint256) { uint256 amt = _amount; require(locked[_owner] > 0, “Cannot go negative. Already at 0 locked tokens.”); if (amt > locked[_owner]) { amt = locked[_owner]; } uint256 lockingAmount = locked[_owner].sub(amt); locked[_owner] = lockingAmount; emit Locked(_owner, lockingAmount); return lockingAmount;}每种方法都确保不会锁定或解锁非法金额,然后在更改给定地址的锁定金额后发出事件。每个函数还返回现在为此用户锁定的新金额。但这仍然不能阻止发送。让我们修改transfer和transferFrom:function transfer(address _to, uint256 _value) public returns (bool) { require(_to != address(0)); require(_value <= balances[msg.sender] - locked[msg.sender]); // <– THIS LINE IS DIFFERENT // …function transferFrom(address _from, address _to, uint256 _value) public returns (bool) { require(_to != address(0)); require(_value <= balances[_from] - locked[_from]); require(_value <= allowed[_from][msg.sender] - locked[_from]); // <– THIS LINE IS DIFFERENT // …最后,我们需要知道为用户锁定或解锁了多少代币:function getLockedAmount(address _owner) view public returns (uint256) { return locked[_owner];}function getUnlockedAmount(address owner) view public returns (uint256) { return balances[owner].sub(locked[owner]);}就是这样:我们的代币现在可以从外部锁定,但只能由代币合约的所有者锁定(这将是我们将在即将到来的教程中构建的Story DAO)。让我们将代币合约设为Ownable,即允许它拥有一个所有者。使用import “../node_modules/openzeppelin-solidity/contracts/ownership/Ownable.sol"导入;然后更改此行: contract StoryDao { ……是这样的: contract StoryDao is Ownable { 完整代码此时带有自定义函数注释的代币的完整代码见文末所示。结论这部分帮助我们构建了一个基本代币,我们将在The Neverending Story中将其用作参与/共享代币。虽然代币具有效用,但它的定义是作为一种资产来控制更大的体量的安全代币。注意区别。在本系列的下一部分中,我们将学习如何编译,部署和测试此代币。======================================================================分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。汇智网原创翻译,转载请标明出处。这里是原文以太坊构建DApps系列教程(二):构建TNS代币完整代码:pragma solidity ^0.4.24;import “../node_modules/openzeppelin-solidity/contracts/math/SafeMath.sol”;import “../node_modules/openzeppelin-solidity/contracts/ownership/Ownable.sol”;contract TNStoken is Ownable { using SafeMath for uint256; mapping(address => uint256) balances; mapping(address => uint256) locked; mapping (address => mapping (address => uint256)) internal allowed; uint256 totalSupply; event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); event Locked(address indexed owner, uint256 indexed amount); string public name; string public symbol; uint8 public decimals; constructor() public { name = “The Neverending Story Token”; symbol = “TNS”; decimals = 18; totalSupply = 100 * 106 * 1018; balances[msg.sender] = totalSupply; } /** @dev _owner will be prevented from sending _amount of tokens. Anythingbeyond this amount will be spendable. / function increaseLockedAmount(address _owner, uint256 _amount) public onlyOwner returns (uint256) { uint256 lockingAmount = locked[_owner].add(_amount); require(balanceOf(_owner) >= lockingAmount, “Locking amount must not exceed balance”); locked[_owner] = lockingAmount; emit Locked(_owner, lockingAmount); return lockingAmount; } /* @dev _owner will be allowed to send _amount of tokens again. Anythingremaining locked will still not be spendable. If the _amount is greaterthan the locked amount, the locked amount is zeroed out. Cannot be neg. / function decreaseLockedAmount(address _owner, uint256 _amount) public onlyOwner returns (uint256) { uint256 amt = _amount; require(locked[_owner] > 0, “Cannot go negative. Already at 0 locked tokens.”); if (amt > locked[_owner]) { amt = locked[_owner]; } uint256 lockingAmount = locked[_owner].sub(amt); locked[_owner] = lockingAmount; emit Locked(_owner, lockingAmount); return lockingAmount; } function transfer(address _to, uint256 _value) public returns (bool) { require(_to != address(0)); require(_value <= balances[msg.sender] - locked[msg.sender]); balances[msg.sender] = balances[msg.sender].sub(_value); balances[_to] = balances[_to].add(_value); emit Transfer(msg.sender, _to, _value); return true; } function approve(address _spender, uint256 _value) public returns (bool) { allowed[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); return true; } function transferFrom(address _from, address _to, uint256 _value) public returns (bool) { require(_to != address(0)); require(_value <= balances[_from] - locked[_from]); require(_value <= allowed[_from][msg.sender] - locked[_from]); balances[_from] = balances[_from].sub(_value); balances[_to] = balances[_to].add(_value); allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value); emit Transfer(_from, _to, _value); return true; } function increaseApproval(address _spender, uint _addedValue) public returns (bool) { allowed[msg.sender][_spender] = ( allowed[msg.sender][_spender].add(_addedValue)); emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); return true; } function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) { uint oldValue = allowed[msg.sender][_spender]; if (_subtractedValue > oldValue) { allowed[msg.sender][_spender] = 0; } else { allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue); } emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); return true; } /* @dev Returns number of tokens the address is still prevented from using / function getLockedAmount(address _owner) public view returns (uint256) { return locked[_owner]; } /* @dev Returns number of tokens the address is allowed to send */ function getUnlockedAmount(address _owner) public view returns (uint256) { return balances[_owner].sub(locked[_owner]); } function balanceOf(address _owner) public view returns (uint256) { return balances[owner]; } function totalSupply() public view returns (uint256) { return totalSupply; } function allowance(address _owner, address _spender) public view returns (uint256) { return allowed[_owner][_spender]; }} ...

December 25, 2018 · 6 min · jiezi

IPFS,是时候该了解下了

什么是IPFS IPFS是一种内容可寻址、版本化、点对点超媒体的分布式存储、传输协议,目标是补充甚至取代过去半个多世纪里使用的超文本媒体传输协议(HTTP),希望构建更快、更安全、更自由的互联网时代。IPFS能解决什么问题 回顾下HTTP时代的网络请求,输入域名,请求DNS服务器,找到对应的IP,根据IP + uri找到目标服务器,目标服务器收到请求后处理,然后按照原路径返回,那么这个过程可能会遇到哪些问题了:效率低,成本高。使用HTTP协议每次需要从中心化的服务器下载完整的文件(网页, 视频, 图片等), 速度慢, 效率低. 如果改用P2P的方式下载, 可以节省近60%的带宽. P2P将文件分割为小的块, 从多个服务器同时下载, 速度非常快.Web文件被删除、服务器关闭。回想一下是不是经常你收藏的某个页面, 在使用的时候浏览器返回404(无法找到页面), http的页面平均生存周期大约只有100天. Web文件经常被删除(由于存储成本太高), 无法永久保存. IPFS提供了文件的历史版本回溯功能(就像git版本控制工具一样), 可以很容易的查看文件的历史版本, 数据可以得到永久保存中心化限制。我们的现有互联网是一个高度中心化的网络. 互联网是人类的伟大发明, 也是科技创新的加速器. 各种管制将对这互联网的功能造成威胁, 例如: 互联网封锁, 管制, 监控等等. 这些都源于互联网的中心化.而分布式的IPFS可以克服这些web的缺点.高度依赖主干网。主干网受制于诸多因素的影响, 战争, 自然灾害, 互联网管制, 中心化服务器宕机等等, 都可能是我们的互联网应用中断服务. IPFS可以是互联网应用极大的降低互联网应用对主干网的依赖.这些问题正是当前HTTP无法根治的,而IPFS却能很好的解决。IPFS的优势 IPFS不仅仅是为了加速web,而是为了最终取代HTTP协议,针对上述HTTP面临的问题,IPFS提出了各种解决方案IPFS是一个文件系统,定义了基于内容的寻址文件系统IPFS天生就是一个CDN,文件添加到IPFS网络,使用分布式哈希、p2p传输、版本管理系统,将会在全世界进行CDN加速IPFS是一个web协议,可以像http那样查看互联网页面,未来浏览器可以直接支持 ipfs:/ 或者 fs:/ 协议IPFS是模块化的协议,连接层:通过其他任何网络协议连接;路由层:寻找定位文件所在位置;数据块交换:采用BitTorrent技术IPFS是一个p2p系统,分布式网络结构,没有单点失效问题IPFS拥有命名服务IPNS:基于SFS(自认证系统)命名体系,可以和现有域名系统绑定IPFS架构设计IPFS至少有八层子协议栈,从上至下为身份、网络、路由、交换、对象、文件、命名、应用,每个协议栈各司其职,又互相搭配。 身份层和路由层可以一起解释。对等节点身份信息的生成以及路由规则是通过Kademlia协议生成制定,KAD协议实质是构建了一个分布式松散Hash表,简称DHT,每个加入这个DHT网络的人都要生成自己的身份信息,然后才能通过这个身份信息去负责存储这个网络里的资源信息和其他成员的联系信息。如同微信名片分享,在无法通过直接搜索微信号的情况下,如果你要找一个人,可以通过有这个人联系方式的朋友分享名片来建立联系。 网络层比较核心,使用的LibP2P可以支持任意传输层协议。NAT技术能让内网中的设备共用同一个外网IP,我们都体验过的家庭路由器就是这个原理。 交换层,是类似迅雷这样的BT工具。迅雷其实是模拟了P2P网络,并创建中心服务器,当服务器登记用户请求资源时,让请求同样资源的用户形成一个小集群swarm,在这里分享数据。这种方式有弊端,一位服务器是由迅雷统一维护,如果出现了故障、宕机时,下载操作无法进行。 中心化服务还可以限制一些下载请求,人们发明了一种更聪明的方式就是Bittorrent,让每一个种子节点所要存储的数据,通过哈希表存储在里面,BT工具相对不太受监管,服务更加稳定。 IPFS团队把BitTorrent进行了创新,叫作Bitswap,它增加了信用和帐单体系来激励节点去分享,我推断FileCoin有很大概率是基于Bitswap,用户在Bitswap里增加数据会增加信用分,分享得越多信用分越高。如果用户只去检索数据而不存数据,信用分会越来越低,其它节点会在嵌入连接时优先选择信用分高的。 这一设计可以解决女巫攻击,信用分不可能靠机器刷去提高,一直刷检索请求,信用分越刷越低。请求次数和存储量的变量之间有一个比较精妙的算法,类似一个抛物线,前期可以容忍很多东西,达到一定次数后不再信任。 对象层和文件层适合结合来谈,它们管理的是IPFS上80%的数据结构,大部分数据对象都是以MerkleDag的结构存在,这为内容寻址和去重提供了便利。文件层是一个新的数据结构,和DAG并列,采用Git一样的数据结构来支持版本快照。 命名层具有自我验证的特性(当其他用户获取该对象时,使用指纹公钥进行验签,即验证所用的公钥是否与NodeId匹配,这验证了用户发布对象的真实性,同时也获取到了可变状态),并且加入了IPNS这个巧妙的设计来使得加密后的DAG对象名可定义,增强可阅读性。 最后是应用层,IPFS核心价值就在于上面运行的应用程序,我们可以利用它类似CDN的功能,在成本很低的带宽下,去获得想要的数据,从而提升整个应用程序的效率。基于IPFS的项目 IPFS的团队在开发时,采用高度模块集成化的方式,像搭积木一样去开发整个项目。协议实验室团队2015年创立,到17年的时间里都在做IPLD、LibP2P、Multiformats这三个模块的开发,它们服务于IPFS底层。 Mutiformats是一系列hash加密算法和自描述方式(从值上就可以知道值是如何生成)的集合,它具有SHA1SHA256 SHA512Blake3B等6种主流的加密方式,用以加密和描述nodeID以及指纹数据的生成。 LibP2P是IPFS核心中的核心,面对各式各样的传输层协议以及复杂的网络设备,它可以帮助开发者迅速建立一个可用P2P网络层,快速且节约成本,这也是为什么IPFS技术被众多区块链项目青睐的缘由。 IPLD其实是一个转换中间件,将现有的异构数据结构统一成一种格式,方便不同系统之间的数据交换和互操作。现在IPLD支持的数据结构,是比特币、以太坊的区块数据,也支持IPFS和IPLD。这也是IPFS为什么受到区块链系统欢迎的原因之二,它的IPLD中间件可以把不同的区块结构统一成一个标准进行传递,为开发者提供了成功性比较高的标准,不用担心性能、稳定和bug。 IPFS应用了这几个模块的功能,集成为一种容器化的应用程序,运行在独立节点上,以Web服务的形式,供大家使用访问。 最后是Filecoin,Filecoin是建立在IPFS基础上的一条公链,旨在创立一个分布式的储存市场,帮助IPFS激励用户利用多余的空间存储链上信息,维系IPFS生态的正常运行与发展。Filecoin激励用户出租自己的闲置硬盘、磁盘等存储空间,用于接收链内存储信息,防止部分节点下线或破坏导致文件不可用问题。出租了自己存储空间的用户便成为矿工,只需连接到 Filecoin 网络,然后等着协议来处理文件传输和交易就行。矿工贡献的存储空间越大,获得的Filecoin(FIL)就越多。当然,客户也可以通过花费Filecoin来雇佣矿工来存储或分发数据。IPFS的应用意义 第一,可以为内容创作带来一定的自由。Akasha是一个典型的应用,它是一个基于以太坊和IPFS的社交博客创作平台,用户创作的博客内容通过一个IPFS网络进行发布,而非中心服务器。同时,用户和以太坊钱包账户进行绑定,用户可以对优质内容进行ETH打赏,内容创作者能以此赚取ETH,如同人脑挖矿一样。它没有太多监管的限制,也没有中间商抽成,内容收益直接归创作者所有。 第二,可以降低存储和带宽成本。我之前也举过爱奇艺的例子,而做视频比较成功的项目叫「Dtube」。它是一个搭建在Steemit上的去中心化视频播放平台,其用户上传的视频文件都经过IPFS协议进行存储,具有唯一标识。相较于传统视频网站,它降低了同资源冗余程度,同时大大节约了海量用户在播放视频时所产生的带宽成本。 第三个,可以与区块链完美结合。区块链的本质是分布式账本,本身的瓶颈之一就是账本的存储能力,目前大部分公链的最大问题是没法存储大量的超媒体数据在自己的链上。比特币至今全部的区块数据也才30-40G左右,以太坊这样可编程的区块链项目也只能执行和存储小段合约代码,DApp想发展成超级App,受到了极大的限制。运用IPFS技术解决存储瓶颈是目前来看的过渡方案,最典型的应用就是EOS。EOS引以为傲的是可以支持百万级别TPS的并发量,其中除了DPOS共识机制的功劳之外,还归功于其底层存储设计是采取IPFS来解决大型数据的传输效率。EOS将自己打包好的区块数据通过IPLD进行异构处理,统一成一种便于内容寻址的数据结构类型,并挂载到IPFS的link上,让IPFS网络承担存储和P2P检索的逻辑,而不消耗EOS区块链系统本身太多的计算资源。 第四,可以为传统应用提供分布式缓存方案。 IPFS-GEO,它是一个为传统LBS应用提供分布式缓存的项目,可以将地理位置坐标数据通过GeoHash算法转化成一维字符串,并将与之相关联的具有检索价值的数据存入IPFS网络,由IPFS网络标识唯一性,并分布在各个邻近节点上。当检索请求到来时,系统先通过字符串近似度范围比较,缩小检索范围,加快检索效率,通过NodeID从附近节点拿到超媒体数据,达到类似分布式缓存的效果,大大提高了LBS应用整个检索动作的效率。IPFS的缺陷 信息不可撤销、不可篡改是IPFS的优点,也是缺点。如果是一个内容错误,需要更新的文件,那么不可撤销、不可更改将会成为一个很麻烦的事情。对此,IPFS给出的对应措施是:可以将修改之后的文件上传至IPFS,IPFS也会对文件进行更新,在IPFS内可搜索到文件更新的所有历史纪录。 IPFS将大文件分别存放于不同的块中,也不可避免的有一个隐患,即:如果一部分存放文件的节点统统下线不可用了,并且该文件没有备份,那么整个文件都是不可用的。对此,有两种解决方案,一是激励更多的节点去存储这个信息,二是积极分发文件,使得更多节点存储这个信息。欢迎订阅「K叔区块链」 - 专注于区块链技术学习 博客地址:http://www.jouypub.com简书主页:https://www.jianshu.com/u/756c9c8ae984segmentfault主页:https://segmentfault.com/blog/jouypub腾讯云主页:https://cloud.tencent.com/developer/column/72548

December 24, 2018 · 1 min · jiezi

以太坊构建DApps系列教程(一):应用程序规则和区块链设置

这将是一个如何使用以太坊区块链构建去中心化应用程序DApps的系列教程。第一篇教程重点介绍应用程序的规则和功能以及设置私有区块链,展示在使用或不使用DAO和应用程序的情况下如何构建自己自定义的以太坊代币。我们要构建3件事:自定义代币。使用代币作为投票的DAO。用于与智能合约交互的原型Web UI。按照本教程中的说明操作后,你将能够构建自己的自定义以太坊代币,无论是否包含DAO和应用程序。我们将要构建什么?我们正在建设的项目名为The Neverending Story(TNS)。完整的项目可以在storydao.bitfalls.com找到。它的完整代码在GitHub上。The Nendingnding Story是一个带有输入字段(可以是文本和图像)的Web应用程序,其中安装了MetaMask的用户可以根据特定条件发送一段文本或图像。(图像每50个段落只出现一次,并且只能是一个URL。)完整的故事呈现在输入字段旁边。故事中存在的条目越多,提交条目的成本就越高。提交条目需要支付费用,列入白名单的并且至少有一个TNS代币的人可以使用的这个操作。操作类型:提交条目:要求发件人至少拥有1个TNS代币并位于白名单中(见下文)。成本0.0001 ether * number of entries in current chapter。 (参见下面的“章节”部分)。这可以是每50个文本条目只有一次图像,并且只能是一个URL。否则就是文字。没有代码,只有纯文本。 在任何一种情况下,文本字段大小限制为256个字符。转让所有权(仅限所有者):可以将所有权转移到新地址。减少费用(仅限所有者):所有者可以在不要求投票的情况下提交较低的费用(参见下面的费用“Free”部分)。购买TNS代币:将以太发送到DAO以获得自动发回一定比例数量的TNS代币。如果DAO中没有足够的TNS代币,则必须从交易所获得它们。检查代币余额:一个只读操作,用于检查DAO中有多少个TNS代币。白名单:当以太发送到DAO的地址时,会自动调用此函数。它将发件人记录在白名单数组中以供将来参考,获得大量TNS的人不能将它们分发到各种帐户。结束章节:触发分配以太分红和重置输入费用的章节结束流程。撤回:当利益相关者想要撤回分红时调用。所有者提款(仅限所有者):由所有者调用以便提取费用收入。利益相关者(TNS代币持有人)将能够对提案进行投票,任何达到“Yes”比“No”更多的投票提案都将获得批准。投票数无关紧要;这个比例很重要。根据提案的类型,提案需要在特定时间段内开放投票。提案类型:删除条目:通过投票确认后,目标条目将被删除。投票时间:48小时。紧急删除条目(仅限所有者):只能由所有者触发。通过投票确认后,目标条目将被删除。投票时间:12小时。紧急删除图像(仅限所有者):仅适用于图像条目。只能由所有者触发。通过投票确认后,目标条目将被删除。投票时间:4小时。稍后我们可以使用相同的方法添加其他类型的提案。所有提案都需要在用户界面中明确列出,以便人们知道他们需要投票。选民只需要一个TNS代币即可投票,但他们拥有的代币越多,他们的投票就越值得。重要提示:用户的代币在投票期间被锁定。这可以防止TNS大鳄持有者压倒每一个活跃的投票。选民必须在对他们重要的选票上分配投票权。Chapters章节在1000个条目或三个星期的时间之后,任何用户都可以调用章节的结尾。然后,DAO将向所有TNS持有者分发收集的以太币,与其余额成比例。持有人不需要在DAO中列入白名单以获得以太分红。他们只需要在分发时保留TNS代币。分发是一种拉动机制:持有者需要调用DAO的撤销功能来获得他们的以太。它不会被自动调用。退出窗口是72小时。50%的无人认领的gas归于拥有者,50%进入下一章的分红。free费用每个提交的参赛费的1%将转给当前所有者。其余部分放入池中,并在每章结束后分发给所有TNS持有者,与其TNS持有量成比例。所有者的费用被分为单独的余额,他们可以随意定期退出。要进入白名单,用户必须向DAO发送0.01以太。所有未来的代币购买价格都要低得多。0.01以太入场费是为了防止Sybil攻击。如果用户在第一次发送时发送的数量超过0.01,则0.01将转向白名单,剩余部分将用于计算用户获得的TNS数量。所有代币将一次性发回给用户。简而言之,将这个项目视为众包选择你自己的冒险故事,包括人群策划和社区审查。一个故事——DAO(story-DAO)。bootstrapping:PoA私有区块链我们将使用两个引导程序:第一个程序将专注于在本地运行我们自己真正的以太坊区块链。它将使用PoA作为共识机制,并且像任何真正的以太坊testnet一样起作用 。下载并安装Virtualbox。下载并安装Vagrant。如果你不了解虚拟机是什么,请参阅此帖子。从这里下载Geth。请务必在下载页面向下滚动并下载“Geth&Tools”,而不仅仅是“Geth”。如果你使用的是macOS,还可以使用Homebrew并使用brew install ethereum进行安装。Mist可以在这里下载。一定要下载“Mist”而不是“Ethereum Wallet”。Mist是以太坊“浏览器”,它可以打开各种DApps。以太坊钱包“Ethereum Wallet”可以干同样的事,但锁定在钱包模式,所以你不能用它打开其他应用程序。这是为了防止非技术用户访问到恶意DApp。如果你很好奇,请在这里了解更多关于Mist和Geth的信息 。我们需要VirtualBox和Vagrant,因为我们将使用这种方法启动我们的节点并运行两台虚拟机,模拟运行以太坊节点的两台计算机。接下来,按照此帖子中的说明设置PoA私有区块链。你最终将得到两个运行节点。每个人都将挖掘到自己的地址。记下这些地址。我的是:Node 1:0x4b61dc81fe382068e459444e8beed1aab9940e3bNode 2:0x97e01610f1c4f4367c326ed1e9c41896b4378458bootstrapping:Ganache CLI我们可以使用的第二个的引导程序,这对于测试我们的合约特别有用,它是Ganache CLI,以前称为Testrpc。Ganache是一个基于JavaScript的本地区块链模拟。每次我们运行测试或重新启动应用程序时,它都会从头开始重新运行区块链。这有助于我们快速测试边缘情况,但不适合长期合约的长期测试。首先,使用npm install -g ganache-cli安装Ganache。然后,只需运行ganache-cli就可以了。你应该看到与此类似的输出:$ ganache-cliGanache CLI v6.1.0 (ganache-core: 2.1.0)(node:40584) ExperimentalWarning: The fs.promises API is experimentalAvailable Accounts==================(0) 0xa0b7139a36ecda5ffda66b9cf97cb9de36e63f2f(1) 0x1f5546797a0ff7efe42ecafaeebd5c932f1a0143(2) 0x0eacbad38a642db2204574ad01b2b51c82ff7080(3) 0x77f40a8add69b0e0806c0c506208e5783b89076d(4) 0x1ea41547984ecb949c2b2df311bffe0fdeae4632(5) 0xa1ad154fd5fd11ebe5410c992e5e97b461c516a2(6) 0x34da52fd90c015a41bcc383ba3d804f7cebbc84e(7) 0xddd5232788c1f1192d6ac5e82e74ca80945e119e(8) 0x7ebc838124a676eac57f9b6275cd29b1a1c63d4d(9) 0x6feed7913319ffb1b01f767960dd843ea7f96181Private Keys==================(0) 62727ad35a288eb34f268cffb1ce620ef3ee80910138aed0e81f24d912fd8a49(1) a6c76b382c655dcc66dd92428e3e0a0f14b7458162ad8e5cbbbcc64d3362d28c(2) eef05f81fd995329c80d8875d5cb62b81f8f28c39951665b4b15688dc48b4c47(3) 5ae06fc34da5d47a64a814ee088f7c6f0d1cae3c63d7ad2d6b71b8128bce1764(4) 8cc43f28054f90243dea496263bd9a45f33db44ea3956ab8d0e8704e15d0787e(5) dcf37436237105ea2f5b1be608b6aa1fe6fb7ca80b8b23ce01ff96930a2a3045(6) f896b6f0ee11ea272c1567ec1950f7ff610df79193cbb7b668ae0ea11f6ec825(7) 877b5868dca9a2f5c7d9546647171c9825f1b02922442f18dd4e90d108b9e54d(8) 7f1f3515d71d348a78ae85a755e02df49be4e0b374447b822abe5a6481fe0c58(9) 20d50b28c8b051406edc6aa61becc3443e430d7d68925a108958f8abecd55ed3HD Wallet==================Mnemonic: soda tower talk dynamic swim tattoo edit cook pair bid glance beautyBase HD Path: m/44’/60’/0’/0/{account_index}Listening on localhost:8545Ganache在这里做的是启动私有区块链,几乎没有挖掘时间,也没有节点。它会在进入时立即执行交易。它还会生成10个预加载了大量虚拟以太的地址,并产生出私钥,以便将它们导入各种工具,如MetaMask,MyEtherWallet或之前下载的Mist。我们将根据我们的需要使用此方法和上述方法的混合,因此请确保同时设置这两种方法。注意:最好也可以使用Ganache UI工具,使用可视界面来管理Ganache区块链。结论使用本指南通过MetaMask,MyEtherWallet或之前下载的Mist等工具连接到私有区块链(任一版本)。两个bootstrapping选项在运行时默认运行在localhost:8545。因此连接它们的过程是相同的。现在我们的应用程序的基本规则和功能已经布局,我们的私有区块链已经建立,我们可以连接到它,接下来我们将重点放在工具,包和依赖项上。======================================================================分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。汇智网原创翻译,转载请标明出处。这里是原文以太坊构建DApps系列教程(一):应用程序规则和区块链设置 ...

December 21, 2018 · 1 min · jiezi

以太坊RLP编码原理

RLP编码是什么 RLP(Recursive Length Prefix,递归的长度前缀)是一种编码规则,主要用来序列化/反序列化数据,可用于编码任意嵌套的二进制数组数据。 RLP编码是以太坊数据序列化的主要编码方式,具有较好的数据处理效率,尤其是将长度和类型统一作为前缀,实际上RLP是基于ASCII编码的一种结构化扩充,既能表示长度还能表示类型,是一种非常紧凑的结构化编码方案。区块、交易等数据结构在持久化时会先经过RLP编码后再存储到数据库中。 RLP的唯一目标就是解决结构体的编码问题;对原子数据类型(比如,字符串,整数型,浮点型)的编码则交给更高层的协议;以太坊中要求数字必须是一个大端字节序的、没有零占位的存储的格式(也就是说,一个整数0和一个空数组是等同的)。 对于在RLP格式中对一个字典数据的编码问题,有两种建议的方式,一种是通过二维数组表达键值对,比如[[k1,v1],[k2,v2]…],并且对键进行字典序排序;另一种方式是通过以太坊文档中提到的高级的基数树编码来实现。RLP编码的优势对象序列化方式又很多,比如常见的JSON格式,但是这些编码方式显示更直观,结构却不够紧凑,不是合适用来存储,例如jsontype Student struct{ Name string json:"name" Sex string json:"sex"}s := Student{Name:“cateria”,Sex:“male”}bs,_ := json.Marsal(&s)print(string(bs))// {“name”:“icattlecoder”,“sex”:“male”}变量s序列化的结果是{“name”:“icattlecoder”,“sex”:“male”},字符串长度35,实际有效数据是cateria和male,共计16个字节,我们可以看到JSON的序列化时引入了太多的冗余信息,这就会导致存储时占用空间太大。所以,以太坊需要设计一种结果更小的编码方法。RLP编码定义RLP编码只处理两类数据:一类是字符串(字节数组),一类是列表。字符串,指的是一串二进制数据,列表,是一个嵌套递归的结构,里面可以包含字符串和列表,例如[“cat”,[“puppy”,“cow”],“horse”,[[]],“pig”,[""],“sheep”]就是一个复杂的列表。其他类型的数据需要转成以上的两类,转换的规则不是RLP编码定义的,可以根据自己的规则转换。例如struct可以转成列表,int可以转成二进制(属于字符串一类),以太坊中整数都以大端形式存储。RLP编码方式的特点:递归,被编码的数据是递归的结构,编码算法也是递归进行处理的;长度前缀,也就是RLP编码都带有一个前缀,这个前缀是跟被编码数据的长度相关的,从下面的编码规则中可以看出这一点。RLP编码规则规则一:对于单个字节,如果它的值范围是[0x00, 0x7f],它的RLP编码就是它本身。这里面需要注意的是0x7f这个边界,因为ASCII编码最大值就是0x7f,也就是说在0x7f以内完全当做ASCII编码使用。规则二:如果一个字符串的长度是0-55字节,它的RLP编码包含一个单字节的前缀,后面跟着字符串本身,这个前缀的值是0x80加上字符串的长度。由于被编码的字符串最大长度是55=0x37,因此单字节前缀的最大值是0x80+0x37=0xb7,即编码的第一个字节的取值范围是[0x80, 0xb7]。规则三:如果字符串的长度大于55个字节,它的RLP编码包含一个单字节的前缀,后面跟着字符串的长度,后面再跟着字符串本身。这个前缀的值是0xb7加上字符串长度的二进制形式的字节长度,说的有点绕,举个例子就明白了,例如一个字符串的长度是1024,它的二进制形式是10000000000,这个二进制形式的长度是2个字节,所以前缀应该是0xb7+2=0xb9,字符串长度1024=0x400,因此整个RLP编码应该是\xb9\x04\x00再跟上字符串本身。编码的第一个字节即前缀的取值范围是[0xb8, 0xbf],因为字符串长度二进制形式最少是1个字节,因此最小值是0xb7+1=0xb8,字符串长度二进制最大是8个字节,因此最大值是0xb7+8=0xbf。规则四:如果一个列表的总长度(列表的总长度指的是它包含的项的数量加它包含的各项的长度之和)是0-55字节,它的RLP编码包含一个单字节的前缀,后面跟着列表中各元素项的RLP编码,这个前缀的值是0xc0加上列表的总长度。编码的第一个字节的取值范围是[0xc0, 0xf7]。规则五:如果一个列表的总长度大于55字节,它的RLP编码包含一个单字节的前缀,后面跟着列表的长度,后面再跟着列表中各元素项的RLP编码,这个前缀的值是0xf7加上列表总长度的二进制形式的字节长度。编码的第一个字节的取值范围是[0xf8, 0xff]。例子分析:15(’\x0f’) = 0x0f (规则一)空字符串 "" = 0x80 (规则二)字符串 “dog” = [0x83, ’d’, ‘o’, ‘g’ ] (规则二)1024(’\x04\00’) = [0x82, 0x04, 0x00] (规则二)字符串 “Lorem ipsum dolor sit amet, consectetur adipisicing elit” = [0xb8, 0x38, ‘L’, ‘o’, ‘r’, ’e’, ’m’, ’ ‘, … , ’e’, ’l’, ‘i’, ’t’](规则三)空列表 [] = [0xc0] (规则四)列表 [“cat”,“dog”] = [0xc8, 0x83, ‘c’, ‘a’, ’t’, 0x83, ’d’, ‘o’, ‘g’ ] (规则四)总结 通过上述的案例分析我们可以看出RLP的设计思想,就是通过首字节快速判断一串编码的类型,充分利用了一个字节的存储空间,将0x7f以后的值赋予了新的含义,以往我们见到的编码方式主要是对指定长度字节进行编码,比如Unicode等,在处理这些编码时一般按照指定长度进行拆分解码,最大的弊端是传统编码无法表现一个结构,就是本文说的列表,RLP最大的优点是在充分利用字节的情况下,同时支持列表结构,也就是说可以很轻易的利用RLP存储一个树状结构。 程序处理RLP编码时也非常容易,根据首字节就可以判断出这段编码的类型,同时调用不同的方法进行解码,如果您熟悉jason这种结构,会发现RLP很类似,支持嵌套的结构,通过递归调用可以将整个RLP快速还原成一颗树,或者转译成一个jason结构,便于其他程序使用。 RLP使用首字节存储长度的位数,再用后续的字节表明整体字符串的长度,根据规则二计算,RLP可以支持的单个最大字符串长度为2的64次方,这无疑是个天文数字,再加上嵌套规则,所以理论上RLP可以编码任何数据。欢迎订阅「K叔区块链」 - 专注于区块链技术学习 博客地址:http://www.jouypub.com简书主页:https://www.jianshu.com/u/756c9c8ae984segmentfault主页:https://segmentfault.com/blog/jouypub腾讯云主页:https://cloud.tencent.com/developer/column/72548 ...

December 19, 2018 · 1 min · jiezi

站在Web3.0 理解IPFS是什么

尽管网络上,已经有不少文章讨论IPFS,不过真正讲明白IPFS想做什么的很少,文本尝试站在未来Web3.0的高度来看看IPFS究竟用来解决什么问题。DApp 的缺陷对区块链有所了解的同学,知道区块链维护的是一个中立的(去中心)、共同信任、难以篡改的数据库、智能合约创造的是一个完全透明(不被干扰)的运行规则,因此可以解决信任问题。一切看起来很美好,我们可以开发去中心化应用DApp 解决信任问题,由此也确实产生了很多的博彩类DApp游戏。不熟悉DApp的同学可以看我另一篇文章程序员如何切入区块链去中心化应用开发.细心的同学,也许会发现一个问题,虽然DApp的后台逻辑(智能合约)是在无中心的节点上运行的透明的规则,但是我们看到内容却来自于一台无信任的中心化服务器。这是由当前互联网规则-超文本媒体传输协议(HTTP)决定的,简单来讲,在这个协议下,当我们在浏览器输入一个网址时,总是会先找到这个网址(域名)对应的服务器IP地址,然后请求服务器,并把服务器的响应显示在浏览器。这种方式下文件能否访问,完全取决于服务器,服务器也许会关闭、内容获取被篡改或删除,对用户都无法保证。我自己看到好内容把网页收藏的习惯,经常会出现过一段时间再去访问的时候,页面已经不存在了。IPFS想要做什么IPFS - InterPlanetary File System 星际文件系统,多数人谈到IPFS都只讲到它的去中心化存储,其实IPFS想要做的远不只存储,其目标是取代HTTP,成为Web3.0时代的基础协议。我们从其官网对IPFS的定义就可以看到其雄心。尽管Web3.0目前没有明确定义,从2014年以太坊联合创始人Gavin Wood提出分布式网络的Web3.0概念开始,业界普遍认为Web3.0 特征应该是 分布式、可信任。在官网的有这样两个描述:IPFS is the Distributed WebA peer-to-peer hypermedia protocol to make the web faster, safer, and more open.IPFS aims to replace HTTP and build a better web for all of us.翻译过来就是: 1. IPFS是分布式Web,是点对点的超媒体协议,以构建更快、更安全、更开放的网络。 2. IPFS旨在取代HTTP,为我们构建一个更好的web。当然,要完全取代HTTP还有一段路要走,最大的坎是怎样让主流的浏览器支持IPFS协议,现在是通过HTTP网关的方式访问IPFS网上面存在的文件。未来IPFS能取代Http的话?就是通过网络浏览器里直接输入 ipfs://文件hash 访问内容,目前这种方式访问IPFS 必须依靠浏览器插件ipfs 伴侣, 并且这个插件的使用不广泛。注意,这里提到的浏览器,只是沿用这个名词,Web3.0的浏览器也许不叫浏览器, 它更可能是数字钱包和浏览器的组合体,现在浏览器上发起交易也同样需要依靠钱包插件进行签名。所以这样一个形态的产品也是大家的机会,这是一个全新的超大入口级产品。即未来期望的访问方式是这样的:ipfs://Qme2qNy61yLj9hzDm4VN6HDEkCmksycgSEM33k4eHCgaVu而现在通过网关访问是这样的:http://127.0.0.1:8080/ipfs/Qme2qNy61yLj9hzDm4VN6HDEkCmksycgSEM33k4eHCgaVuhttps://ipfs.io/ipfs/Qme2qNy6…IPFS是怎么做的IPFS是一种内容可寻址、版本化、点对点超媒体的分布式存储、传输协议。我们知道在现在的网络服务里,内容是基于位置(IP)寻址的,就是在查找内容的时候,需要先找到内容所在的服务器(根据IP),然后再在服务器上找对应的内容。而在IPFS的网络里,是根据内容寻址,每一个上传到IPFS上面去的文件、文件夹,都是以Qm为开头字母的哈希值,无需知道文件存储在哪里,通过哈希值就能够找到这个文件,这种方式叫内容寻址。工作原理在IPFS系统中,内容会分块存放(如果内容很小就会直接存在DHT中),并分散存储在IPFS网络中的节点上(不过目前的IPFS实现,一个节点会完整保存内容的所有区块)。系统会给内容的每一个块计算哈希值,然后把所有块的哈希值拼凑起来,再计算一次哈希值,从而得到最终的哈希值。同时每个节点会维护一张DHT(分布式哈希表),包含数据块与目标节点的映射关系。在IPFS中是通过哈希去请求文件的,它就会使用这个分布式哈希表找到文件所在的节点,取回文件根据哈希重新组合文件(同样也会验证文件)。IPFS的特点根据前面的原理,我们可以推倒出IPFS的几个特点:当我们知道一个文件的哈希值之后,可以确保文件不被修改, 即可以确保访问的文件是没有被篡改的。因为根据哈希的特点,哪怕源文件有一丁点的更改,对应的哈希值也会完全不同。(理论上) 如果IPFS得以普及,节点数达到一定规模,内容将永久保存,就算部分节点离线,也不会影响文件的读取,不像现在的收藏会失效。由于IPFS是一个统一的网络,只要文件在网络中被存储过,除了必要的冗余备份,文件不会被重复存储,对比现有互联网,信息孤岛,各中心间不共享数据,数据不的不重复存储,IPFS一定意义上节约了空间,使得整个网络带宽消耗更低,网络更加高效。相对于中心化存储的容易遭受DDOS攻击,IPFS采用分布式存储网络,文件被存储在不同的网络节点,天然避免了DDOS攻击,同时一个文件可以同时从多个节点同时下载,通信的效率也会更高。IPNS在IPFS中,一个文件的哈希值完全取决于其内容,修改它的内容,其相应的Hash值也会发生改变。这样有一个优点是保证文件的不可篡改,提高数据的安全性。但同时我们在开发应用(如网站)时,经常需要更新内容发布新版本,如果每次都让用户每次在浏览器中输入不同的IPFS地址来访问更新后内容的网页,这个体验肯定是无法接受的。IPFS提供了一个解决方案IPNS(Inter-Planetary Naming System),他提供了一个被私钥限定的IPNS哈希ID(通常是PeerID),其用来指向具体IPFS文件哈希,当有新的内容更新时,就可以更新IPNS哈希ID的指向。为了方便大家理解,做一个类比,和DNS类似, DNS记录了域名指向的IP地址, 如果服务器更改,我们可以更改DNS域名指向,保证域名指向最新的服务器。IPNS则是用一个哈希ID指向一个真实内容文件的Hash,文件更新这更改哈希ID的指向,当然更新指向需要有哈希ID对应的私钥。通过IPNS访问文件的方式如下:利用插件访问:ipns://QmYM36s4ut2TiufVvVUABSVWmx8VvmDU7xKUiVeswBuTva利用网关访问: http://127.0.0.1:8080/ipns/QmYM36s4ut2TiufVvVUABSVWmx8VvmDU7xKUiVeswBuTvaIPNS同样兼容DNS,使用DNS TXT记录域名对应的IPNS哈希ID,就可以域名来替换IPNS哈希ID来进行访问。从而实现更容易读写和记忆。例如使用以下方式简化访问:ipns://ipfs.iohttps://ipfs.io/ipns/ipfs.io/IPFS/IPNS 如果使用,将在后面的文章进一步介绍。小结IPFS是一项非常激动人心的技术,尽管它仍在发展的早期(区块链也是),还有很多问题需要我们一起解决,如NAT穿透问题,浏览器支持问题,内容存储激励问题,存储数据安全与隐私保护问题。但是通过 IPFS + 区块链将真正创建Web3.0时代的应用,这是一个完全可信的、自运转(不停机)的应用,它可以做什么我不知道,我对未来充满期待。欢迎来知识星球提问,星球内已经聚集了300多位区块链技术爱好者。深入浅出区块链 - 系统学习区块链,打造最好的区块链技术博客。

December 18, 2018 · 1 min · jiezi

以太坊开发时如何保证DApp本地存储localStorage的安全性?

部署去中心化应用程序dapp会引入一些有趣的安全性考虑因素,这些因素可能不会出现在更传统的开发中。我们如何保证dApp本地存储的安全性?提出这个问题的原因是我们在使用Colony dApp时遇到的一个重要障碍,那就是如何应对在使用IPFS或Swarm等分布式存储系统保持本地存储的dApp数据安全挑战。在本文中,我将从dApp开发人员的角度来看一下这个问题,然后研究一些可能的解决方案。共享本地存储localStorage的问题IPFS运行本地节点node,它与Web服务器捆绑在一起。捆绑的Web服务器使节点可以轻松地相互连接并共享网络中其他位置可能需要的数据。作为一个去中心化的应用程序构建器,你将依赖该Web服务器将你的内容从一个节点推送到另一个节点,从而使其可以根据需要立即供最终用户使用。假设你正在完全去中心化full decentralized并且正在避免使用DNS或Web代理等任何内容来跟踪你的内容在网络上的位置,那么访问dApp的方式通常是通过浏览器使用其查询本地节点哈希,如:http://localhost:8080/QmcefGgoVLMEPyVKZU48XB91T3zmtpLowbMK6TBM1q4Dw/现在,假设在正常使用期间,你的应用程序将在浏览器的localStorage保存数据:可能需要传递一些数据,或者保持本地用户交互的队列,以最大限度地减少链上交易并节省gas成本。浏览器中的本地存储仅限于特定的地址上下文(域和端口)。IPFS节点是获取此上下文的,这意味着通过IPFS Web服务器运行的任何去中心化应用程序将使用具有读写访问权限的相同localStorage。这可能是一个大问题。默认情况下,dApp的某些helper依赖项使用localStorage临时将密钥保存在纯文本中。这些数据不应该被看到的一天。另一个潜在的泄漏问题是保存其内存状态的软件包,以便以后可以恢复。类似Flux-like的库通常(相对)安全,因为它们只在内存中运行,但启用持久性状态会将该内存状态放入localStorage,从而将其打开给潜在的攻击者。缓解问题的策略不幸的是,安全没有灵丹妙药:作为一名dApp开发人员,为安全起见所做的任何调整都可能需要在开发的其他方面做出一些让步。以下是你可以做出的一些妥协:不存储任何数据这当然是最安全的方法,但它有点像烧毁你的房子来摆脱蟑螂。在本地存储数据的dApp中有许多功能和基本行为,删除太多后可能没有应用程序存在的意义了。此外,有许多库默认使用localStorage,你必须手动检查每个依赖项并删除任何需要它的库,否则就得自己修改库。加密一切这在理论上更有前途,特别是因为大多数dApp开发人员已经在看板上保持默认加密。加密的local storage值实际上,加密所有本地存储有点麻烦。要加密数据,必须有一个密钥:但是用户不能将该密钥存储在dApp中,因为它将被放在localStorage,这样做你就将回到原点。一种解决方案是使用钱包:你的dApp可能会以某种方式与区块链进行交互,要求用户解锁其钱包以发送和签署交易。由于无论如何都需要钱包与dApp交互,因此可以使用每个帐户的私钥privatekey来加密本地存储。然而,这也有一些缺点:每次想要与localStorage交互时,您都必须询问用户的纯文本私钥。像MetaMask这样的密钥管理软件不起作用,因为它永远不会暴露用户的私钥。使用Swarm和MistMist是作为dApp和以太坊浏览器构建的,因此它为该问题提供了一些特殊优势。默认情况下,Mist支持Swarm的bzz协议,因此你可以设置一个ens地址指向dApp的哈希值,然后使用Mist无需担心地浏览你的dApp。不幸的是,这只会解决通过Mist访问dApp的用户的问题。运行本地Swarm节点的用户仍然必须通过localhost访问,localhost仍然(可能)将数据泄露给其他dApp。为你的dApp创建一个浏览器扩展通过浏览器扩展程序运行你的应用程序将导致它获得单独的上下文(它将不再在localhost:8080),但它有点减弱了去中心化应用程序的目的,必须要依赖于像Chrome网络商店这样的中央权威机构用于管理和分配。此外,现在你必须为要支持的每个浏览器创建和维护单独的扩展,并通过其自己的特定集中式应用商店进行更新。不爽。创建一个独立的桌面应用程序和以前一样,创建独立应用程序是将dApp分离到自己的上下文的一种方式,这意味着它将获得自己的包装器(在本例中为electron)。独立的桌面应用程序具有额外的好处,可以捆绑外部库和你可能需要的任何其他内容,包括IPFS本身的单独实例。和以前说的一样,要有一些让步:除非你想要专门在bittorrent上分发应用程序,否则你需要找到一个集中托管的解决方案来进行分发和维护。你必须为electron桌面应用程序维护一个单独的存储库。如果你想将IPFS用于任何其他服务,你可能最终会在同一台计算机上运行多个节点,这可能会变得混乱。将你的应用代理到域名通过使用其他Web服务器代理本地节点,有两个优点:首先,现在你的dApp有一个友好的友好的人类可读地址,而不是一个冗长的哈希。其次,你的应用程序将拥有自己的上下文,并且不会共享localStorage。然而,代理确实跨越了“真正的”去中心化,用户将再次不得不依靠中央服务器来访问去中心化的服务。哎。对于去中心化的应用程序开发人员来说,现在还处于早期阶段。这种问题在新兴的“去中心化协议栈”中无处不在“:而且在我们提出更优雅的解决方案之前可能还需要一段时间。将来,在浏览器中支持本机IPFS或Swarm节点可以解决这个问题,并且无需将Web服务器与去中心化的文件存储捆绑在一起。用户可以输入类似ipfs://QmcefGgoVLMEPyVKZU48XB91T3zmtpLowbMK6TBM1q4Dw/并直接访问dApp,并为每个唯一的哈希分配自己的上下文。Mist和IPFS团队意识到了这个问题,并希望将未来版本中的解决方案纳入其中。但是现在,找到我们可以采用的解决方法并与社区的其他人分享它们会很有帮助。如果你是一名开发自己的去中心化应用程序dapp的开发人员,希望本文对没构建代码以避免数据泄漏有所帮助,如果你设计了另一个上面未提及的解决方案,请分享它!感谢Alex Rea和Griffin Hotchkiss帮助起草本文。======================================================================分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。汇智网原创翻译,转载请标明出处。这里是原文

December 18, 2018 · 1 min · jiezi

以太坊Ghost协议和叔块

GHOST(Greedy Heaviest Observed Subtree)是一种主链选择协议(不是侧链选择协议)。举例来说:经典的Proof-of-Work(POW)是以取最长的主链为基本原则,GHOST协议则是以包含子树数目最多为基本原则。 POW协议不能以太快的频率(上图的Block Generation Rate)发布新的区块,因为太快发布区块,区块中的数据重复验证6次(若干次)立即永久封存地区块中,一旦51%算力攻击一旦发生,double-spend等糟糕问题会出现,恶意的数据容易永久封存于区块中,整个blockchain系统需要足够长的时间来处理和恢复黑客恶意攻击所造成的破坏——这段时间可以理解为系统的有效修复时间,也可以理解为交易信息被确认的等待时间,从安全的角度,显然这段时间越长,交易数据可靠性被验证的越多,所以越可靠。 相比而言,GHOST协议就没有这个问题了,因为在GHOST协议控制下, “区块发布太快” 和 “51%攻击持续性地控制主动权” 二者没有必然的关系,GHOST不是采用绝对算力优势获取主动权的协议。这也是为什么以太坊的出块速度要远远大于区块链。 在比特币协议中,最长的链被认为是绝对的正确。如果一个块不是最长链的一部分,那么它被称为是“孤块”。一个孤立的块也是合法的,但是发现的稍晚,或者是网络传输稍慢,而没有能成为最长的链的一部分。在比特币中,孤块没有意义,随后将被抛弃,发现这个孤块的矿工也拿不到采矿相关的奖励。例如:挖矿节点A是一个矿池占有全网30%的算力,挖矿节点B占有全网算力的10%,节点A会有70%的概率产生废块,节点B有90%的概率产生废块. 如果新旧区块之间产生的间隔太短, 则节点A会因为规模效应而比B节点更为高效。所以新旧区块的间隔过短会导致单一的矿池主导全网的挖矿过程。 这个问题在以太坊中得到了很好的解决,根据GHOST协议,不认为孤块没有价值,而是会给与发现孤块的矿工以回报。孤块被称为“叔块”(uncle block),它们可以为主链的安全作出贡献,也同样能获得奖励,这激励了矿工在新发现的块中去引用叔块,减少了孤块的产生。Ghost协议解决了两个问题:摒弃了单一的最长链原则, 取而代之的是最大子数原则;孤块奖励问题。如下图所示:如果单纯的计算最长链原则, 主链应该是 0 -> 1B -> 2D -> 3F -> 3F -> 4C -> 5B.如果采用了GHOST协议, 以前的"废块"也会被考虑到主链的计算量中.每一个节点下含一个子树, 兄弟节点之间子树节点最多的被选为主链. 这样一来 0 -> 1B -> 2C -> 3D -> 4B 成为主链,如果采用GHOST协议, 一个攻击者仅仅提供一个1A到6A的长链并不能被认为是主链.Ghost协议的优势在于:以太坊十几秒的出块间隔,大大增加了孤块的产生,并且降低了安全性。通过鼓励引用叔块,使引用主链获得更多的安全保证(因为孤块本身也是合法的)比特币中,采矿中心化(大量的集中矿池)成为一个问题。Ghost协议下,叔块也是能够获得报酬,可以一定程度上缓解这个问题。孤块奖励问题:主链节点获得base reward;一个节点最多引用两个叔块;叔块必须是区块的前2层~前7层的祖先的直接子块;被引用过的叔块不能重复引用;引用叔块的区块,可以获得挖矿报酬的1/32,也就是51/32=0.15625 Ether,最多获得20.15625=0.3125 Ether;主链节点的兄弟(非主链节点)获得 ((叔块高度+8-当前块的高度)/8 )*base reward,如下图表格所示;交易费用(transaction fee)不会分配给叔块被引用的叔块,其矿工的报酬和叔块与区块之间的间隔层数有关系。间隔层数报酬比例报酬(ether)17/84.37526/83.7535/83.12544/82.553/81.87562/81.25欢迎订阅「K叔区块链」 - 专注于区块链技术学习 博客地址:http://www.jouypub.com简书主页:https://www.jianshu.com/u/756c9c8ae984segmentfault主页:https://segmentfault.com/blog/jouypub腾讯云主页:https://cloud.tencent.com/developer/column/72548

December 18, 2018 · 1 min · jiezi

8支团队正在努力构建下一代Ethereum

“我们不想在构建 Ethereum 2.0时重新造轮子。”谈到开发人员为 Ethereum 区块链进行两个独立的升级(一个称为 Ethereum 2.0,另一个称为 Ethereum 1x)所作出的补充努力,劳尔·乔丹坚持认为,在较短的时间内将升级包括在 Ethereum 1x 中,将对正在进行的 Ethereum 2.0研究有好处。Jordan是当前为ethereum 2.0构建软件客户端的八个不同开发团队之一的共同领导。(作为背景,客户端通常是用不同的编程语言编写的软件实现,用户部署这些语言以连接到以太网并参与以太网。)Jordan对CoinDesk说,保持在以太坊1x内提出的“增量增强”不影响主链的长期路线图:“我认为这两个组相当正交,但我们至少必须了解每个组正在执行什么。”目前,这两种升级的技术指导方针也称为规范,仍在进行中。在以太开发人员中仅在最近几周认真讨论过ethereum 1x之后,它打算成为侧重于对当前以太网络的增强的中间升级。另一方面,Ethereum 2.0具有一个更雄心勃勃的议程,该议程可追溯到2014年,包括对连锁平台的根本性改变。在以太坊2.0的早期项目名称为Serenity这众所周知,目前的规范可以概括为三个主要组件的组合:从当前被称为工作量证明(PoW)的能源密集型共识协议切换到PoS。一种称为分片的网络范围扩展解决方案的实现。EVM(负责在块链上部署去中心化式应用程序(dapps)的引擎)的改进,可以在称为 WebAssembly(WASM)的新编程代码上运行。尽管这些组件之一——即ethereum对WASM的实现——有可能在早期的ethereum 1x路线图中进行测试,但是构建ethereum 2.0的大部分工作仍然作为一个单独的项目进行。这项工作正在由分布在全球的八个不同小组进行。1.ChainSafe SystemsChainSafe Systems总部位于多伦多,是一家区块链研发公司,为许多不同的基于以太坊的项目提供咨询服务,包括Shyft,Bunz,Aion和Polymath。ChainSafe的项目负责人Mikerah Quintyne-Collins告诉CoinDesk,他希望“做出更大的贡献”。“对我而言,开发以太坊2.0是我在互联网未来的标志。”被称为Lodestar的Collins和她的团队目前正在构建一个用Javascript编写的ethereum 2.0客户端——这是Web开发的主要编程语言。通过以太坊基金会拨款计划的私人资助并寻求额外支持,据柯林斯称,Lodestar设想“将一大批网络开发者带到以太坊生态系统”。“所有这些编程语言都有自己的社区。整个社区可能不是都想做出贡献,但它们足够大,以至它的一部分需要贡献并建立在以太坊之上,“柯林斯说。柯林斯甚至怀疑开发工作有助于其他区块链平台的进展,他强调说,在她看来,以太坊2.0并不是要确保以太坊的未来成为“主要区块链”,他说:“这不是关于谁将成为下一件大事件。它更多的是尝试使这些系统工作。匆匆忙忙赶上另一个假想的以太坊杀手,就无法实现这个目标。“2.PegaSys“我们的目标是将企业带入主网。我们希望通过创建更容易被企业采用的软件来实现这一目标。“这就是区块链协议工程组PegaSys的战略和业务开发负责人Faisal Khan。由Consensys全力支持——由ethereum联合创始人Joseph Lubin领导的以太坊自称的“风险投资制作工作室”——PegaSys正在为现有的以太坊Java客户端Pantheon构建以太坊2.0规范。Pantheon最近在布拉格的以太坊开发商聚会上亮相,使用一种名为Apache 2.0的开源软件许可证,使企业能够在以太坊平台上构建产品,从而将其知识产权货币化。Khan在谈到CoinDesk时强调,扩展对以太坊2.0规范的支持意味着与以太坊基金会研究人员和其他客户开发团队密切合作。“有很多接触点。每周都有一个电话。有一个研究论坛,ETH研究。有一个Gitter频道。沟通非常频繁。显然,有加密Twitter。任何ethereum 2.0团队和基金会之间的谈话都非常丰富。“ Khan说。除此之外,ethereum 2.0将在平台上启动一个新的“网络效应循环,dapp开发和用户增长”,Khan重申,目前该项目最大的需求是“更多人参与”。3.HarmonyHarmony是去年10月推出的,它是以太坊最初的Java客户端,以前由一群名为Ether Camp的独立开发人员维护。现在简称为Harmony团队,这些开发团队最近通过以太坊基金会拨款计划获得了90,000美元,以建立以太坊2.0的规范。由以太坊基金会资助,Harmony预计将继续作为以企业为中心的Pantheon的替代Java客户端运行。Harmony与Pantheon的Apache 2.0软件许可证分开,根据通用公共许可证(GPL)运营,旨在确保代码的任何实现仍为免费软件,如官方GPL指南中所述。Harmony开发商Mikhail Kalinin告诉CoinDesk:“将建设新的互联网”推向市场。“最大的挑战是保持研究领域的所有变化,并跟踪每项工作的进展。它的范围很广。“4.Parity TechnologiesParity Technologies是由以前的以太坊基金会首席安全官Jutta Steiner共同创立的,是一家区块链基础设施公司,负责维护当今平台上第二大最受欢迎的以太坊客户端。名为Parity Ethereum的客户名称被自称为“最快,最先进的以太坊客户端。”。正如官方Wiki页面上详细介绍的那样,Parity Ethereum在Rust中编程,专为“关键任务型应用”而构建,意味着同步速度快速并且有最大的正常操作运行时间。对于在组织内部建立以太坊2.0客户的重新努力,Parity公共事务负责人Peter Mauric解释说,以太坊2.0实际上是以太坊区块链的准备生产production-ready版本。他告诉CoinDesk:“从广义上讲,我相信现在存在的以太坊已经处于测试阶段……以太坊2.0正在从几年前Vitalik推出的这个实验性项目转向更具生产能力的区块链协议。”5.Prysmatic Labs在编程语言Go中首次实现了ethereum 2.0,Prysmatic Labs于今年1月推出,旨在帮助以太坊区块链实现可扩展性。谈到这一努力,Prysmatic Labs Raul Jordan的团队负责人告诉CoinDesk:“以太坊2.0系统可以根据全球计算机的需求进行扩展……这意味着它将能够处理现实世界必需品的负载……从简单的东西到建立在它之上的完全庞大的金融系统“。名为Prysm的ethereum 2.0客户端将作为区块链目前最流行的客户端实现的对应物,也就是用Go编写的Geth。Jordan没有将客户端开发视为一个竞争过程,他强调,在以太坊区块链中,多种不同的客户端实施是非常必要的。“原因是当你在开发像这样的区块链时,你需要尽可能多的去中心化的实现。因此,例如,如果以太坊区块链在Prysm上运行并且Prysm中存在错误,则每个人都可以切换到另一个客户端。这样你有其他选择。“Jordan说。尽管如此,Jordan认为比较强调对建设“公益事业”的努力,对开发工作的支持主要来自以太坊基金会和其他私人捐助者的捐赠。迄今为止,Jordan告诉CoinDesk,建立一个以太坊2.0客户端的最大挑战之一是确保工作与“研究密切相关”。他解释说:“每周,每天都有新的想法出现,我们基本上建立在不断变化的规范上……所以我认为最大的挑战之一是开发之间的多任务处理,同时也确保研究总体是好的,这样我们可以评估前进的选择。“6.Sigma PrimeSigma Prime成立于2016年,是一家信息安全和区块链技术咨询公司。最近从以太坊基金会获得了150,000美元的资助,该公司正在建立一个名为Lighthouse的ethereum 2.0客户端,用编程语言Rust编写。作为第二个如同Parity一样采用Rust客户端,Sigma Prime Paul Hauner的联合创始人告诉CoinDesk他并不认为这两种产品之间存在“任何根本差异”。Hauner解释说,强调重复工作实际上是“区块链中真正需要的”。“软件有漏洞。所以,如果每个人都运行相同的客户端并且存在错误,那么每个人都会失败。如果有这种多样化的客户端,他们很可能会有不同的错误。一个客户端被拒绝这很好。网络的其余部分仍然保持不变。“谈到以太坊2.0升级的重要性,Hauner补充说,不仅用户会注意到“每秒交易量的大幅增加”,而且还会在股权证明共识协议下获得显着的环境收益。“就个人而言,我觉得人们会使用它,它会起作用。就实际技术而言,我没有任何担心是否可行。这个时间点需要设防吗?绝对不。它尚未建成。“Hauner说。7.StatusStatus是一个消息传递平台和移动浏览器,专门用于吸引以太坊区块链上的用户,Status公布了今年8月用编程语言Nim编写的名为Nimbus的ethereum 2.0客户端的很活跃的开发项目。部分由以太坊基金会提供的500,000美元赠款资助,该官方网站上强调的项目目标是“通过优化Nimbus在资源受限设备上的性能来推动大量采用以太坊”。因此,利用运行Nim代码的轻量级功能,Nimbus有望成为以太坊首款将智能手机设备和其他手持电子设备连接到区块链平台的移动客户端。该项目有八个核心贡献者,几个月前在博客文章中突出显示,它正在寻找额外的开发人员支持。Status Jacek Sieka的研究开发负责人写道:“我们完全是开源的,并鼓励那些想要参与的人做出贡献。”此外,在谈到CoinDesk时,Sieka补充说,他预计ethereum 2.0的开发工作将分多个阶段推出,其中一个可疑的测试网络将在明年的某个时间推出,称为beacon信标链。“据说这项研究正在进行中,任何时间表都在不断变化,但从终端用户的角度来看,一年,两年是期望ethereum 2.0普遍有用的合理时间表。”Sieka说。8.Trinity最后但同样重要的是,Trinity是一个用编程语言Python编写的当前以太坊客户端。作为以太坊的新标准Python实现,Trinity将最新代码升级为最初由ethereum Vitalik Buterin创始人撰写的休眠PyEthApp。今年已经在初步的alpha阶段推出,Trinity由包括Merriam在内的六位开发人员组成,除了其中一人外都与以太坊基金会合作。预计也将为以太坊2.0规范提供支持,Trinity Piper Merriam的首席架构师强调,“在研究和实现之间的边界”开发是他最擅长的。“相对理论研究来说我更喜欢理论的应用。协议研究很简洁,但实施协议更符合我的擅长。“Merriam说。Merriam认为,这项工作实际上“只是刚刚起步”,将以太坊2.0客户端开发的过程比作“拼图”。需要解决很多难题,所有八个团队的集体工作预计将相互加强,并确保以太坊区块链的未来。Merriam告诉CoinDesk:“通过对任何协议进行多次实现……我们可以确信协议的书面定义是准确的并且个别客户端是正确的。”======================================================================分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。汇智网原创翻译,转载请标明出处。这里是原文8支团队正在努力构建下一代Ethereum

December 17, 2018 · 1 min · jiezi

Python开发以太坊智能合约指南(web3.py)

在以太坊上获得一个基本的智能合约是一个很简单的事,只需google查询“ERC20代币教程”,你会发现有关如何做到这一点的大量信息。以编程方式与合约交互完全是另一回事,如果你是一个Python程序员,那么教程就很少。所以写这个Python中的以太坊智能合约开发指南。按我的统计对我们来说幸运的是,2017年Web3.py的第4版发布,这意味着现在比以往更容易运行python脚本并观察区块链上发生的神奇事情。像幽灵般的。Piper Merriam,Jason Carver以及其他所有在Web3.py上努力工作以使我们其他人生活更轻松的人大声呼喊,在Sempo,我们正在使用以太坊来使灾难般的响应更加透明,而且它是只有Web3.py才能真正实现。设置首先我们进行设置,确保我们安装了相关的python库。Python库无处不在,但它们的用途是什么?有很多与以太坊相关的python库,但是当人们谈论以太坊时,有两个会出现很多:Web3.py和Pyethereum。乍一看,你应该使用哪一个并不明显。Pyethereum以太坊虚拟机(EVM)的Python实现。反过来,EVM是以太坊协议的一部分,它实际运行智能合约中的代码并确定其输出。因此,如果你想在Python中运行以太坊节点,那么Pyethereum是一个很好的起点。即使你非常高兴在不运行自己的节点的情况下运行智能合约,Pyethereum仍然是一个很好的库,它包含许多功能,可以执行有用的功能,例如从私钥计算用户的地址等等。Web3.py用于实际与以太坊区块链交互的库。我们谈论的事情包括在账户之间转移以太网,发布智能合约以及触发附加现有智能合约的功能。它受到流行的JavaScript库Web3.js的启发,它将成为我们在本教程中使用的主库。好的,少说多做!起初我尝试使用Python3.5版本,但在运行时我遇到了问题,显然是由Python的类型提示造成的。基于Python3.6创建虚拟环境解决了这个问题,所以我建议你做同样的事情。继续并pip-install web3 (确保你获得版本4)。除非你喜欢花钱,否则你需要在以太坊测试网上使用钱包,例如Ropsten和其他大量以太玩法。一个简单的方法是下载Chrome的Metamask扩展,并从那里创建一个新帐户。确保你还选择左侧的’Ropsten Test Net’。即使你的现有钱包中包含真正的以太币,我也强烈建议你为开发目的创建一个新的钱包。我们将使用私钥做一些相对无法预测的事,所以如果它们不小心变成公共主网络的话就不会有问题(公私钥?)为新创建的钱包获取测试Ether非常简单:只需访问faucet.metamask.io并点击“请求来自faucet的1个 以太”。对于我们将要做的事情,这应该是充足的。最后,因为我们将在没有托管我们自己的节点的情况下使用Ropsten TestNet,我们需要一个可以连接Blockchain的供应商。Infura.io适用于此,所以去那里创建一个免费帐户。记下Ropsten TestNet的提供者URL(看起来像https://ropsten.infura.io/FE2…)。部署智能合约使用Python来部署智能合约而不运行自己的节点是非常困难的,所以我们将在这一步上做点儿手脚。对于许多智能合约用例,你只需要执行一次。正如我之前提到的,有关如何部署ERC20合约的百万条指南,因此我们将部署一些不同的(并且更方便地更短)。问:谁喜欢在互联网上分享他们的意见?大家都喜欢?好答案。以下我称之为“Soap Box”肥皂盒的智能合约允许任何人向区块链广播他们想要的任何意见,在永恒的剩余时间(给予或接受)可以看到它。但是有一个问题:只有支付了必要的0.02以太网费用的地址才能播出他们的意见。听起来不太公平,但就这样。Remix,以太坊的在线代码编辑器非常出色,因此在那里创建一个新文件并粘贴以下代码。它是用Solidity(Smart Contracts的编程语言)编写的。如果代码没有太多意义并不重要,我们将在稍后详细介绍相关部分,但最终这是一个Python教程。pragma solidity ^0.4.0;contract SoapBox {// Our ‘dict’ of addresses that are approved to share opinions //我们批准分享意见的地址的“字典” mapping (address => bool) approvedSoapboxer; string opinion; // Our event to announce an opinion on the blockchain //我们的事件发布对区块链的意见 event OpinionBroadcast(address _soapboxer, string _opinion);// This is a constructor function, so its name has to match the contract //这是一个构造函数,所以它的名字必须与合约相匹配 function SoapBox() public { } // Because this function is ‘payable’ it will be called when ether is sent to the contract address. //因为这个函数是“支付”,所以当以太网被发送到合约地址时将被调用。 function() public payable{ // msg is a special variable that contains information about the transaction // msg是一个特殊变量,包含有关交易的信息 if (msg.value > 20000000000000000) { //if the value sent greater than 0.02 ether (in Wei) //如果发送的值大于0.02 ether(在Wei中) // then add the sender’s address to approvedSoapboxer //然后将发件人的地址添加到approvedSoapboxer approvedSoapboxer[msg.sender] = true; } } // Our read-only function that checks whether the specified address is approved to post opinions. //我们的只读函数,用于检查指定地址是否被批准发布意见。 function isApproved(address _soapboxer) public view returns (bool approved) { return approvedSoapboxer[_soapboxer]; } // Read-only function that returns the current opinion //返回当前意见的只读函数 function getCurrentOpinion() public view returns(string) { return opinion; }//Our function that modifies the state on the blockchain //我们的函数修改了区块链上的状态 function broadcastOpinion(string _opinion) public returns (bool success) { // Looking up the address of the sender will return false if the sender isn’t approved //如果发件人未获批准,查找发件人的地址将返回false if (approvedSoapboxer[msg.sender]) { opinion = _opinion; emit OpinionBroadcast(msg.sender, opinion); return true; } else { return false; } }}以下是Metamask变得非常有用的地方:如果你点击重新混音窗口右上角的“run”运行标签并在“Environment”环境下拉列表中选择“Injected Web3”注入的Web3,则“Account”帐户下拉列表中应填充你的帐户地址早在MetaMask中创建。如果没有,只需刷新浏览器即可。然后单击“create”创建。Metamask应该弹出一个弹出窗口,要求你确认交易。如果没有,只需打开Metamask扩展并在那里执行:你将在Remix控制台底部收到一条消息,告知你合约的创建正在等待处理。单击链接以在Etherscan上查看其状态。如果刷新并且“To”收件人字段填充了合约地址,则合约已成功部署。一旦你记下了合约地址,我们就该开始通过Web3.py与合约进行交互了。在我看来,有四种(半)方式可以与以太坊智能合约进行互动。最后两个(一半)经常混在一起,但差异很重要。我们已经看到了第一个:在区块链上部署智能合约。现在我们将介绍其余的python:向合约发送以太:真正自我解释,将以太币从钱包发送到智能合约的地址。希望换取有用的东西。调用函数:执行智能合约的只读功能以获取某些信息(例如地址的余额)。与功能进行交易:执行智能合约的功能,该功能可以更改区块链的状态。查看事件:查看由于先前的功能交易而发布到区块链的信息。将以太币发送给合约一些(但不是全部)智能合约包括“payable”应付功能。如果你将Ether发送到合约的地址,则会触发这些功能。一个典型的用例就是ICO:将以太送到合约中,然后返回给你的是代币。首先,我们将从导入开始,创建一个新的web3对象,通过Infura.io连接到Ropsten TestNet。import timefrom web3 import Web3, HTTPProvidercontract_address = [YOUR CONTRACT ADDRESS]wallet_private_key = [YOUR TEST WALLET PRIVATE KEY]wallet_address = [YOUR WALLET ADDRESS]w3 = Web3(HTTPProvider([YOUR INFURA URL]))w3.eth.enable_unaudited_features()你可以在Metamask中的帐户名称旁边的菜单中找到你的钱包私钥。因为我们使用的Web3.py的某些功能尚未经过完全审核以确保安全性,所以我们需要调用w3.eth.enable_unaudited_features()来确认我们知道可能会发生问题的情况。我告诉过你我们用私钥做了一些危险的事情!现在我们将编写一个函数,将以太币从我们的钱包发送到合约:def send_ether_to_contract(amount_in_ether): amount_in_wei = w3.toWei(amount_in_ether,’ether’); nonce = w3.eth.getTransactionCount(wallet_address) txn_dict = { ’to’: contract_address, ‘value’: amount_in_wei, ‘gas’: 2000000, ‘gasPrice’: w3.toWei(‘40’, ‘gwei’), ’nonce’: nonce, ‘chainId’: 3 } signed_txn = w3.eth.account.signTransaction(txn_dict, wallet_private_key) txn_hash = w3.eth.sendRawTransaction(signed_txn.rawTransaction) txn_receipt = None count = 0 while txn_receipt is None and (count < 30): txn_receipt = w3.eth.getTransactionReceipt(txn_hash) print(txn_receipt) time.sleep(10) if txn_receipt is None: return {‘status’: ‘failed’, ’error’: ’timeout’} return {‘status’: ‘added’, ’txn_receipt’: txn_receipt}首先让我们回顾一下交易字典txn_dict:它包含了定义我们发送给智能合约的交易所需的大部分信息。to:我们将以太送到哪里(在这种情况下是智能合约)。Vaule:我们送多少钱单位wei。gas:gas是衡量在以太坊上执行交易的计算工作量度。在这种情况下,我们指定了我们愿意执行此交易的天然气量的上限。gasPrice:我们愿意为每单位gas支付多少钱(以wei为单位)。Nonce:这是一个地址nonce而不是更常见的工作证明。它只是发送地址所做的先前交易次数的计数,用于防止双重花费。Chain ID:每个以太坊网络都有自己的链ID:主网的ID为1,而Ropsten为3。你可以在这里找到更长的列表。关于gas限制的快速说明:有一些功能可以让你估算交易将使用多少gas。但是,我发现选择限制的最佳方法是计算出你愿意支付多少钱,然后再让交易失败,然后再去做。一旦我们定义了交易的重要部分,我们就会使用我们钱包的私钥对其进行签名。然后它就可以发送到网络了,我们将使用sendRawTransaction方法。在矿工决定将其包含在一个区块中之前,我们的交易实际上不会完成。一般而言,你为每个单位支付的费用Gas(记住我们的天然气价格参数)决定了一个节点决定将你的交易包含在一个区块中的速度(如果有的话)。https://ethgasstation.info/是…,可以确定你将等待你的交易包含在一个区块中的时间。此时间延迟意味着交易是异步的。当我们调用sendRawTransaction时,我们会立即获得交易的唯一哈希值。你可以随时使用此哈希来查询你的交易是否已包含在块中。我们知道,当且仅当我们能够获得交易收据时才将交易添加到区块链中(因为所有好的购买都带有收据吗?)。这就是为什么我们创建循环来定期检查我们是否有收据: txn_receipt = None count = 0 while txn_receipt is None and (count < 30): txn_receipt = w3.eth.getTransactionReceipt(txn_hash) print(txn_receipt) time.sleep(10)值得注意的是,交易可以添加到区块链中,但仍然因各种原因而失败,例如没有足够的gas。这就是将以太符号发送给合约的Python代码。让我们快速回顾一下我们在Solidity中写的应付函数:function() public payable{ if (msg.value >= 20000000000000000) { approvedSoapboxer[msg.sender] = true; } }Msg是智能合约中的一个特殊变量,其中包含有关发送到智能合约的交易的信息。在这种情况下,我们使用msg.value,它给出了交易中发送的Ether数量(在Wei而不是raw Ether中)。同样,msg.sender给出了进行交易的钱包的地址:如果已经发送了足够的以太币,我们会将其添加到已批准帐户的字典中。继续运行send_ether_to_contract函数。希望你能收到回执。你还可以通过在Etherscan的Ropsten Network部分查找你的钱包地址来检查交易是否完成。我们将在下一节中获得Python中的更多信息。调用一个函数我们刚刚向我们的智能合约发送了一些以太币,因此我们想检查我们的钱包地址是否已被批准分享意见是有意义的。为此,我们在智能合约中定义了以下功能:function isApproved(address _soapboxer) public view returns (bool approved) { return approvedSoapboxer[_soapboxer]; }与python相比,这个函数附带了很多额外的东西,比如声明类型(地址和bool)。尽管如此,这个函数只需要一个地址(_soapboxer参数),在有效(但不完全)的哈希表/python dict中查找相应的批准布尔值并返回该值。你调用的时候一个智能合约函数,以太坊节点将计算结果,并将其返回给你。这里的事情变得有点复杂:调用是只读的,这意味着它们不会对区块链进行任何更改。如果上述函数包含一行代码来记录数字时间,则检查地址是否已批准:approvedCheckedCount[_soapboxer] = approvedCheckedCount[_soapboxer] + 1然后,当调用该函数时,该节点将计算approvedCheckedCount的新值,但一旦返回结果就丢弃它。作为只读的交换,函数调用不会花费你运行任何以太,因此你可以愉快地检查帐户是否已被批准而不必担心成本。让我们跳回到我们的python文件的顶部并添加一些更多的设置代码。import contract_abicontract = w3.eth.contract(address = contract_address, abi = contract_abi.abi)你需要创建另一个名为contract_abi的python文件。这将包含一个大的JSON信息字符串,Python需要与我们在智能合约中定义的函数进行交互,称为应用程序二进制接口(ABI)。你可以在Remix中找到智能合约的ABI的JSON字符串:单击编译“Compile”选项卡。单击详细信息“Details”——应显示包含大量信息的模式。向下滚动到ABI部分,然后单击复制到剪贴板“Copy to clipboard”图标。将复制的字符串粘贴到contract_abi.py文件中,该文件应如下所示:abi = “”"[ { A BIG LIST OF ABI INFO SPREAD ACROSS MULTIPLE DICTS }]““我们添加到主python文件的另一行现在使用此ABI JSON字符串并使用它来设置合约对象。如果你浏览合约,你会注意到它包含一个函数属性,其中包含我们在智能合约中创建的三个函数。现在我们将创建一个python函数,该函数调用Smart Contract智能合约的isApproved函数来检查指定的地址是否被批准分享意见。def check_whether_address_is_approved(address): return contract.functions.isApproved(address).call()那很短暂。你现在可以使用它来检查你的钱包地址是否已获批准。如果你之前运行了send_ether_to_contract函数并发送了足够数量的以太,那么希望你能回到true。与函数交易我们正在与智能合约进行最后的主要互动:广播意见。再一次,我们来看看我们的Solidity Code:function broadcastOpinion(string _opinion) public returns (bool success) { if (approvedSoapboxer[msg.sender]) { opinion = _opinion; emit OpinionBroadcast(msg.sender, opinion); return true; } else { return false; } }这里没有什么新东西:我们采用传入的_opinion参数并使用它来设置全局变量意见。(如果你愿意,可以通过getter函数查询实习生)。有一条线有点不同:emit OpinionBroadcast(msg.sender, opinion)我们很快就会介绍。 当你通过交易与智能合约的功能进行交互时,功能对智能合约状态所做的任何更改都会在区块链上发布。为了换取这种特权,你必须向矿工支付一些(希望很小)的以太量。Python时间:def broadcast_an_opinion(covfefe): nonce = w3.eth.getTransactionCount(wallet_address) txn_dict = contract.functions.broadcastOpinion(covfefe).buildTransaction({ ‘chainId’: 3, ‘gas’: 140000, ‘gasPrice’: w3.toWei(‘40’, ‘gwei’), ’nonce’: nonce, }) signed_txn = w3.eth.account.signTransaction(txn_dict, private_key=wallet_private_key) result = w3.eth.sendRawTransaction(signed_txn.rawTransaction) tx_receipt = w3.eth.getTransactionReceipt(result) count = 0 while tx_receipt is None and (count < 30): time.sleep(10) tx_receipt = w3.eth.getTransactionReceipt(result) print(tx_receipt) if tx_receipt is None: return {‘status’: ‘failed’, ’error’: ’timeout’} processed_receipt = contract.events.OpinionBroadcast().processReceipt(tx_receipt) print(processed_receipt) output = “Address {} broadcasted the opinion: {}”\ .format(processed_receipt[0].args._soapboxer, processed_receipt[0].args._opinion) print(output) return {‘status’: ‘added’, ‘processed_receipt’: processed_receipt}这实际上与将Ether发送到智能合约时使用的过程相同。我们将创建并签署一个交易,然后将其发送到网络。再一次,交易是异步的,这意味着无论函数被告知在Solidity代码中返回什么,你实际得到的东西总是交易的哈希。鉴于交易本身并没有返回任何有用的信息,我们需要其他东西。这导致我们采用最后(半)方式与智能合约进行互动。事件events我将事件称为与智能合约交互的“一半”方式,因为从技术上讲,它们是由交易发出的。 事件是智能合约以易于阅读的形式在区块链上记录事物的方式,它们基本上只是一组可以使用特定交易的收据查找的值。我们在智能合约的最顶层定义了一个:event OpinionBroadcast(address _soapboxer, string _opinion);然后,当我们使用broadcastOpinion函数时,我们使用它向区块链发出信息。将交易添加到块后,你可以使用交易哈希查询区块链以查找OpinionBroadcast事件发出的特定值。这是我们在函数broadcast_an_opinion中的最后一点python代码。你会注意到我们要求事件发出的信息存储在’args’属性中。这个事件非常公开。实际上,任何人都可以轻松使用Etherscan或类似工具来查看智能合约发出的所有事件的日志。Etherscan会自动检测“Transfer”转移事件并列出所有事件。Nifty如果你已经做到这一点,你就有权发表意见。继续用你选择的意见运行broadcast_an_opinion。如果一切顺利进行,你应该很快就会收到已处理的收据,以及已放入区块链的OpinionBroadcast事件的打印输出。Nice。这是完整的python代码:import timefrom web3 import Web3, HTTPProvidercontract_address = [YOUR CONTRACT ADDRESS]wallet_private_key = [YOUR TEST WALLET PRIVATE KEY]wallet_address = [YOUR WALLET ADDRESS]w3 = Web3(HTTPProvider([YOUR INFURA URL]))w3.eth.enable_unaudited_features()contract = w3.eth.contract(address = contract_address, abi = contract_abi.abi)def send_ether_to_contract(amount_in_ether): amount_in_wei = w3.toWei(amount_in_ether,’ether’); nonce = w3.eth.getTransactionCount(wallet_address) txn_dict = { ’to’: contract_address, ‘value’: amount_in_wei, ‘gas’: 2000000, ‘gasPrice’: w3.toWei(‘40’, ‘gwei’), ’nonce’: nonce, ‘chainId’: 3 } signed_txn = w3.eth.account.signTransaction(txn_dict, wallet_private_key) txn_hash = w3.eth.sendRawTransaction(signed_txn.rawTransaction) txn_receipt = None count = 0 while txn_receipt is None and (count < 30): txn_receipt = w3.eth.getTransactionReceipt(txn_hash) print(txn_receipt) time.sleep(10) if txn_receipt is None: return {‘status’: ‘failed’, ’error’: ’timeout’} return {‘status’: ‘added’, ’txn_receipt’: txn_receipt}def check_whether_address_is_approved(address): return contract.functions.isApproved(address).call()def broadcast_an_opinion(covfefe): nonce = w3.eth.getTransactionCount(wallet_address) txn_dict = contract.functions.broadcastOpinion(covfefe).buildTransaction({ ‘chainId’: 3, ‘gas’: 140000, ‘gasPrice’: w3.toWei(‘40’, ‘gwei’), ’nonce’: nonce, }) signed_txn = w3.eth.account.signTransaction(txn_dict, private_key=wallet_private_key) result = w3.eth.sendRawTransaction(signed_txn.rawTransaction) tx_receipt = w3.eth.getTransactionReceipt(result) count = 0 while tx_receipt is None and (count < 30): time.sleep(10) tx_receipt = w3.eth.getTransactionReceipt(result) print(tx_receipt) if tx_receipt is None: return {‘status’: ‘failed’, ’error’: ’timeout’} processed_receipt = contract.events.OpinionBroadcast().processReceipt(tx_receipt) print(processed_receipt) output = “Address {} broadcasted the opinion: {}”\ .format(processed_receipt[0].args._soapboxer, processed_receipt[0].args._opinion) print(output) return {‘status’: ‘added’, ‘processed_receipt’: processed_receipt}if name == “main”: send_ether_to_contract(0.03) is_approved = check_whether_address_is_approved(wallet_address) print(is_approved) broadcast_an_opinion(‘Despite the Constant Negative Press’)打包封装所以关于它。正如我所提到的,我们还没有达到使用python实际部署智能合约很容易的地步,但其他一切都在那里。在Sempo,我们正在使用上面提到的所有技术来使问题响应更加透明。感谢Sebastian Dirman指出w3.toWei(value, ‘ether’)是一种更好的方式在Ether和Wei之间进行转换——只需将以太量乘以1000000000000000000即可导致类型错误!======================================================================分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。汇智网原创翻译,转载请标明出处。这里是原文Python以太坊智能合约开发指南 ...

December 17, 2018 · 4 min · jiezi

通过node.js看看在以太坊交易中都发生了什么?

在以太坊交易中都发生了什么?以太坊可以被认为是基于交易的状态机,其中交易可以改变状态,并且状态跟踪交互。在这里,我们从高层次上检查交易的组成部分,并解释大多数乱码十六进制值是如何确定的。我们将在本教程中使用nodejs,因此我们首先安装依赖项。$ npm install web3@0.19 ethereumjs-util@4.4 ethereumjs-tx@1.3然后创建一个文件tx.js并要求依赖项。var Web3 = require(‘web3’);var web3 = new Web3(new Web3.providers.HttpProvider(‘https://ropsten.infura.io/'));var util = require(’ethereumjs-util’);var tx = require(’ethereumjs-tx’);首先,我们从一个私钥开始。以太坊使用公钥加密进行身份验证。更具体地,使用具有secp256k1曲线的椭圆曲线数字签名算法(ECDSA)。除了一些限制外,私钥只是一个随机的256位数据。例如:var privateKey = ‘0xc0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0de’;导出相应的公钥:var publicKey = util.bufferToHex(util.privateToPublic(privateKey));如果你打印出publicKey,你应该得到以下内容:0x4643bb6b393ac20a6175c713175734a72517c63d6f73a3ca90a15356f2e967da03d16431441c61ac69aeabb7937d333829d9da50431ff6af38536aa262497b27与该私钥相关联的以太坊地址是公钥的SHA3-256(Keccak)哈希的最后160位。var address = ‘0x’ + util.bufferToHex(util.sha3(publicKey)).slice(26);//0x53ae893e4b22d707943299a8d0c844df0e3d5557正如你所看到的,实际上多个私钥可能具有相同的地址。以太坊帐户与每个地址相关联,并且每个帐户都具有以下属性:nonce从0开始的传出交易数的计数。balance中的以太币数量。storageRoot与帐户存储关联的哈希。codeHash管理帐户的代码的哈希,如果这是空的,那么该帐户是可以使用其私钥访问的普通帐户,否则它是一个智能合约,其交互由其代码管理。接下来我们来看一个交易,有6个输入字段:nonce从0开始的传出交易数的计数。gasPrice价格确定交易将花费的以太量。gasLimit允许用于处理交易的最大gas。to交易发送到的帐户,如果为空,交易将创建合约。估计要发送的以太网的value。data可以是对合约或代码的任意消息或函数调用以创建合约。发送1000wei(1ether =10的18次方wei)的ether并留下0xc0de消息的交易可以构造如下:var rawTx = { nonce: web3.toHex(0), gasPrice: web3.toHex(20000000000), gasLimit: web3.toHex(100000), to: ‘0x687422eEA2cB73B5d3e242bA5456b782919AFc85’, value: web3.toHex(1000), data: ‘0xc0de’};请注意,未指定发件人from地址,使用私钥签名后将从签名派生。签署交易:var p = new Buffer(‘c0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0de’, ‘hex’);var transaction = new tx(rawTx);transaction.sign(p);然后可以将交易发送到网络,并由256位交易id跟踪。此交易可在Etherscan查看。交易id是交易的哈希。console.log(util.bufferToHex(transaction.hash(true)));//0x8b69a0ca303305a92d8d028704d65e4942b7ccc9a99917c8c9e940c9d57a9662接下来,我们来看一下函数调用的数据data组成。以此交易的数据为例:console.log(web3.eth.getTransaction(‘0xaf4a217f6cc6f8c79530203372f3fbec160da83d1abe048625a390ba1705dd57’).input);//0xa9059cbb0000000000000000000000007adee867ea91533879d083dd47ea81f0eee3a37e000000000000000000000000000000000000000000000000d02ab486cedbffff为了知道它正在调用哪个函数,必须事先知道合约的函数以创建哈希表。第一个32位a9059cbb是函数哈希的第一个32位。在这种情况下,函数是transfer(address _to,uint256 _value),其哈希值是:console.log(web3.sha3(’transfer(address,uint256)’));//0xa9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b每个参数后面跟256位,所以在这种情况下地址是:0x0000000000000000000000007adee867ea91533879d083dd47ea81f0eee3a37e和无符号整数是:0x000000000000000000000000000000000000000000000000d02ab486cedbffff接下来,如上所述,通过省略to字段,将创建合约。但合约的地址是如何确定的?以此交易为例:console.log(web3.eth.getTransactionReceipt(‘0x77a4f46ff7bf8c084c34293fd654c60e107df42c5bcd2666f75c0b47a9352be5’).contractAddress);//0x950041c1599529a9f64cf2be59ffb86072f00111合约地址是发件人地址的最后160位hash,其nonce可以预先确定。对于此交易,可以通过以下方式找到发件人和nonce`:var contractTx = web3.eth.getTransaction(‘0x77a4f46ff7bf8c084c34293fd654c60e107df42c5bcd2666f75c0b47a9352be5’);console.log(contractTx.from);//0x84f9d8b0e74a7060e20b025c1ea63c2b171bae6fconsole.log(contractTx.nonce);//0因此合约地址是:console.log(‘0x’ + util.bufferToHex(util.rlphash([‘0x84f9d8b0e74a7060e20b025c1ea63c2b171bae6f’, 0])).slice(26));//0x950041c1599529a9f64cf2be59ffb86072f00111现在我们已经对这些十六进制了解了一点!以太坊和智能合约具有破坏许多行业的巨大潜力。网上有很多资源,你可以在下面找到一些资源继续探索以太坊!以太坊主站点:https://www.ethereum.org/Mist以太坊的客户端之一:https://github.com/ethereum/m…Solidity:http://solidity.readthedocs.i…Web3 api:https://github.com/ethereum/w…社区讨论:https://www.reddit.com/r/ethe…======================================================================分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。汇智网原创翻译,转载请标明出处。这里是原文在以太坊交易中都发生了什么?

December 17, 2018 · 1 min · jiezi

以太坊交易池处理逻辑

以太坊网络中,我们发送一笔交易时,可能发送成功,也可能发送失败,那么交易是如何判断能否发送成功的呢。当我们发送交易后,交易会被广播到矿工,矿工会监听交易的广播,然后把交易放到本地的交易池中等待处理,但是交易能否放到交易池中,以及在交易池中的交易如何处理的,具体如下:当交易进入交易池(tx_pool)时,矿工节点会做以下验证:通过交易Hash判断交易在交易池中是否存在,如果存在就使用新的交易替换以前的交易验证交易的合法性,如长度、value、是否溢出当前区块的GasLimit、Nonce值等、Gas是否足够,如果验证不通过就会返回对应的错误代码验证是否孤儿交易,如果是就本地保存,不转发,防止DDOS攻击如果交易池满了,就会验证交易Gas是否比当前交易池中的最低Gas低,如果低于交易池的最低Gas会返回ErrUnderpriced,如果高于最低值,就剔除最低Gas的交易。发生这种情况后,在etherscan中会发现在这笔交易pending中消失了(也有很大机率依然能够查到这笔交易在pending列表中,因为etherscan连接了很多节点,每个节点的交易池的状态都是不一样的,那条被踢出的交易可能在别的节点中仍然处于pending状态)如果交易已经在交易池中,会判断Gas是否高于上一条相同Nonce的交易Gas某一个阈值(默认10%),如果Gas高于,就剔除前一笔交易,就使用新的交易替换前一笔交易,如果没有高于当前的交易就会返回失败按顺序放入到交易池中,等待打包等待新的交易加入到交易池,会重复上述步骤。在明白上述逻辑之前我们需要了解几个细节矿工不能在一个区块中打包任意多的tx(只能尽可能多的打包),因为一个区块有GasLimit限制和区块大小限制。矿工运行以太坊实例时,是可以根据需要修改最低的GasPrice值,这样可以过滤很多低Gas的交易。交易池容纳的交易数默认是有上限的。以太坊的txpool中的pending集合(miner是从pending中拿交易组装block的)中容纳的交易数量默认设置为最大4096。但是在Geth v1.6.2中支持外部重置交易池默认配置。具体是–txpool.globalslots value。在Parity v1.6.8中也支持外部设置,具体是–tx-queue-size LIMIT。Parity默认是1024。一个账户默认只能放16条交易到pending中,满了以后,第17条乃至以后更多的交易会有一套规则来替换先前位于pending中的16条交易。欢迎订阅「K叔区块链」 - 专注于区块链技术学习 博客地址:http://www.jouypub.com简书主页:https://www.jianshu.com/u/756c9c8ae984segmentfault主页:https://segmentfault.com/blog/jouypub腾讯云主页:https://cloud.tencent.com/developer/column/72548

December 14, 2018 · 1 min · jiezi

即将来临的君士坦丁堡硬分叉详情(2019年1月)

君士坦丁堡分叉包含5个EIPEIP145EVM目前只有算数和逻辑运算,缺少原生移位运算,这个提案里补充上了,将之前通过算术运算实现的左移和右移运算的gas成本从35减少到3gas。向后兼容对之前创建的合约没有影响。新增栈操作码:0x1b左移,0x1c逻辑右移,0x1d算术右移。EIP1014这个提案改变了合约地址的生成算法,原来的只需要对交易发起地址和这笔交易的nonce进行keccak256就可以了,现在加了几个参数变成:keccak256( 0xff ++ address ++ salt ++ keccak256(init_code)))[12:],主要是为了避免生成的地址发生碰撞。新增栈操作码:0xf5 Create2。EIP1052新增一个操作EXTCODEHASH,可以直接返回合约的字节码Hash,而以前获取合约字节码Hash的操作是EXTCODECOPY,gas比较昂贵。新增栈操作码:0x3f EXTCODEHASH。EIP1283EVM存储很贵,这个提案就是要优化SSTORE操作指令,改变这个操作消耗gas的测算算法。SSTORE是EVM将数据存入内存槽的主要指令。EIP1234这个提案调整难度炸弹、降低挖矿奖励。1、这次分叉并不包含Casper,POS的切换也被推迟了,还是采用POW机制,只不过调整下POW的难度计算规则,我们看下之前的难度计算规则://根据父块和最新块的时间差动态调整难度,小于10增加难度,大于等于20减小难度。block_diff = parent_diff + 难度调整 + 难度炸弹难度调整 = parent_diff // 2048 * MAX(1 - (block_timestamp - parent_timestamp) // 10, -99)难度炸弹 = INT(2^((block_number // 100000) - 2))从上面可以看到,难度炸弹是指数曲线增长的,到一定区块高度会陡增,从而减慢出块时间,而本次分叉不再用区块高度了,而是用一个伪区块高度计算,从而将难度炸弹延迟大约12个月,以太坊系统还保持以往15秒一块的稳定速率,等到2019年冬季结束的时候,平均出块时间会是30秒。看一下替换区块高度的那个伪区块高度:fake_block_number = max(0, block.number - 5_000_000) if block.number >= CNSTNTNPL_FORK_BLKNUM else block.numberCNSTNTNPL_FORK_BLKNUM是本次君士坦丁堡分叉生效的高度:第708万块。2、为了减小以后切换到POS,矿工发生分叉的概率,本次也减小了区块奖励提前让大家适应下。具体每块的奖励由3eth降到2eth,叔块奖励也调整为:new_uncle_reward = (8 - k) * new_block_reward / 8k = block.number - uncle.number侄块的奖励:new_nephew_reward = new_block_reward / 32分叉史最后梳理一下以太坊分叉史,以太坊规划了四个升级阶段:1、Froniter(边境)\2、Homestead(家园)\3、Metropolis(大都会)大都会分两个阶段:拜占庭和君士坦丁堡。\本次君士坦丁堡分叉就位于大都会的第二阶段,预计2019年1月实施。4、Serenity(宁静)未来实施。

December 14, 2018 · 1 min · jiezi

以太坊源码分析:交易缓冲池txpool

区块链就是何交易打交道,我们今天就介绍下,交易处理过程中的一个重要组成部分:txpool。这篇文章主要从功能角度介绍,通过这篇文章会了解:txpool的在交易中的位置和作用。txpool的功能,核心组成部分queued和pending。txpool如何实现它的功能。txpool源码的重要关注点。以太坊内部有个重要的内部功能是txpool,从字面意思就能看出来,交易池就是存放交易的池子。它在以太坊中的位置如下图,只要有新交易,无论是本节点创建的,还是其他peer节点广播来的,都会先加入到交易池里,在打包区块的时候,就从这个池子里提取,区块产生之后,共识区块,交易上链。txpool有4个功能:作为存放交易的缓冲区,大量交易到来时,先存起来为打包区块服务,合适交易会被打包到区块清理交易当交易的数量多于缓冲区大小时,过滤/惩罚发送大量交易的账户(攻击者)我们来一张稍微详细点的模块交互图,看txpool怎么实现上面4个功能的。缓存功能的设计txpool中的交易分为queued和pending 2种,其中queued存放未来的、当前无法执行的交易。以太坊使用nonce值决定某个账户的交易顺序,多条交易值nonce值必须连续,如果和过去的交易不连续,则无法执行,我们不妨使用nonce值,标记交易的号码,nonce为10的交易,称为第10号交易。举个例子,当前账户的nonce是10,txpool中有该账户的第100号交易,但txpool中没有第1199号交易,这些交易的缺失,造成第100号交易无法执行,所以第100号交易就是未来的交易、不可执行的交易,存放在queue中。pending存放可执行的交易。比如我们把上面的1199号交易补全了,那么11~100号交易都可以进入到pending,因为这些交易都是连续的,都可以打包进区块。当节点收到交易(本地节点发起的或peer广播来的)时,会先存放到queued,txpool在某些情况下,把queued中可执行的交易,转移到pending中。为区块打包服务这是txpool最核心的功能,worker在打包区块的时候,会获取所有的pending交易,但这些交易还存在txpool中,worker只是读取出来,至于txpool何时删除交易,稍后从txpool清理交易的角度单独在看。清理交易txpool清理交易有以下几种条件,符合任意以下1条的,都是无效交易,会被从pending或者queued中移除:交易的nonce值已经低于账户在当前高度上的nonce值,代表交易已过期,交易已经上链就属于这种情况交易的GasLimit大于区块的GasLimit,区块容不下交易账户的余额已不足以支持该交易要消耗的费用交易的数量超过了queued和pending的缓冲区大小,需要进行清理交易清理主要有3个场景:txpool订阅了ChainHeadEvent事件,该事件代表主链上有新区块产生,txpool会根据最新的区块,检查每个账号的交易,有些无效的会被删除,有些由于区块回滚会从pending移动到queued,然后把queued中可执行的交易移动到pending,为下一轮区块打包组号准备。queued交易移动到pending被称为“提升”(promote),这个过程中,同样会检查交易,当交易不符合以上条件时,就会被直接从queued中删除。删除停留在queued中超过3小时的交易,3小时这个超时时间是可以通过geth的启动参数调整的。txpool记录了某个账户交易进入pending的时间,如果这个时间超过了3小时,代表该账号的交易迟迟不能被主链打包,既然无法被主链接受,就删除掉在queued中本来就无法执行的交易。惩罚恶意账号这也是txpool很重要的一个属性,可以防止恶意账户以发起大量垃圾交易。防止恶意用户造成:占用txpool空间浪费节点大量内存和CPU降低打包性能只有当交易的总数量超过缓冲区大小时,txpool才会认为有恶意账户发起大量交易。pending和queued缓冲区大小不同,但处理策略类似:pending的缓冲区容量是4096,当pending的交易数量多于此时,就会运行检查,每个账号的交易数量是否多于16,把这些账号搜集出来,进行循环依次清理,什么意思呢?就是每轮只删除(移动到queued)这些账号的每个账号1条交易,然后看数量是否降下来了,不满足再进行下一轮,直到满足。queued的缓冲区容量是1024,超过之后清理策略和pending差不多,但这里可是真删除了。该部分功能未抽象成单独的函数,而是在promoteExecutables()中,就是在每次把queued交易转移到pending后执行的。本地交易的特权,txpool虽然对交易有诸多限制,但如果交易是本节点的账号发起的,以上数量限制等都对他无效。所以,如果你用本节点账号不停的发送交易,并不会被认为是攻击者,你用txpool.status命令,可以查看到交易的数量,肯定可以大于4096,我曾达到过60000+。重点关注的源码txpool的主要设计上面就讲完了,如果你想把txpool的代码阅读一番,我建议你重点关注一下这些函数和变量,按图索骥能就完全掌握txpool的实现。TxPoolConfig:txpool的配置参数chainHeadCh:txpool订阅了新区块事件pending:pending的交易,每个账号都有一个交易列表queue:queued的交易,每个账号都有一个交易列表loop:txpool的事件处理函数addTx:添加1条交易的源头,你能找到类似的函数promoteExecutables:queued交易移动到pendingreset:根据当前区块的最新高度,重置txpool中的交易仔细阅读一遍,你会发现txpool会涉及多个锁(TxPool.mu, TxPool.all, TxPool.priced.all),所以当txpool中的交易很多时,它的性能是很低的,这也会影响到区块的打包。如果这篇文章对你有帮助,请点个赞/喜欢,鼓励我持续分享,感谢。我的文章列表,点此可查看如果喜欢本文,随意转载,但请保留此原文链接。

December 11, 2018 · 1 min · jiezi

以太坊源码分析—Ethash共识算法

Ethereum当前和Bitcoin一样,采用基于工作量证明(Proof of Work,PoW)的共识算法来产生新的区块。与Bitcoin不同的是,Ethereum采用的共识算法可以抵御ASIC矿机对挖矿工作的垄断地位,这个算法叫做Ethash。为什么要反ASICPoW的的核心是Hash运算,谁的Hash运算更快,谁就更有可能挖掘出新的区块,获得更多的经济利益。在Bitcoin的发展过程中,挖矿设备经历了(CPU=>GPU=>ASIC)的进化过程,其中的动机就是为了更快地进行Hash运算。随着矿机门槛地提高,参与者久越来越少,这与区块链的去中心化构想背道而驰。因此,在共识算法设计时,为了减少ASIC矿机的优势(专用并行计算),Ethereum增加了对于内存的要求,即在进行挖矿的过程中,需要占用消耗大量的内存空间,而这是ASIC矿机不具备的(配置符合运算那能力的内存太贵了,即使配置,这也就等同于大量CPU了)。即将挖矿算法从CPU密集型(CPU bound)转化为IO密集型(I/O bound)Dagger-HashimotoEthash是从Dagger-Hashimoto算法改动而来的,而Dagger-Hashimoto的原型是Thaddeus Dryja提出的Hashimoto算法,它在传统Bitcoin的工作量证明的基础上增加了消耗内存的步骤。传统的PoW的本质是不断尝试不同的nonce,计算HASH$$hash_output=HASH(prev_hash,merkle_root,nonce)$$如果计算结果满足$hash_output<target$,则说明计算的nonce是有效的而对于Hashimoto,HASH运算仅仅是第一步,其算法如下:nonce: 64-bits.正在尝试的nonce值get_txid(T):历史区块上的交易T的hashtotal_transactions: 历史上的所有交易的个数hash_output_A = HASH(prev_hash,merkle_root,nonce)for i = 0 to 63 do shifted_A = hash_output_A >> i transaction = shifted_A mod total_transactions txid[i] = get_txit(transaction) << iend oftxid_mix = txid[0]^txid[1]…txid[63]final_output = txid_mix ^ (nonce<<192)可以看出,在进行了HASH运算后,还需要进行64轮的混淆(mix)运算,而混淆的源数据是区块链上的历史交易,矿工节点在运行此算法时,需要访问内存中的历史交易信息(这是内存消耗的来源),最终只有当 $final_output < target$ 时,才算是找到了有效的nonceDagger-Hashimoto相比于Hashimoto,不同点在于混淆运算的数据源不是区块链上的历史交易,而是以特定算法生成的约1GB大小的数据集合(dataset),矿工节点在挖矿时,需要将这1GB数据全部载入内存。Ethash算法概要矿工挖矿不再是仅仅将找到的nonce填入区块头,还需要填入一项MixDigest,这是在挖矿过程中计算出来的,它可以作为矿工的确在进行消耗内存挖矿工作量的证明。验证者在验证区块时也会用到这一项。先计算出约16MB大小的cache,约1GB的dataset由这约16MB的cache按特定算法生成,dataset中每一项数据都由cache中的256项数据参与生成,cache中的这256项数据可以看做是dataset中数据的parent。只所以是约,是因为其真正的大小是比16MB和1GB稍微小一点(为了好描述,以下将省略约)cache和dataset的内容并非不变,它每隔一个epoch(30000个区块)就需要重新计算cache和dataset的大小并非一成不变,16MB和1GB只是初始值,这个大小在每年会增大73%,这是为了抵消掉摩尔定律下硬件性能的提升,即使硬件性能提升了,那么最终计算所代表的工作量不会变化很多。结合上一条,那么其实每经过30000个区块,cache和dataset就会增大一点,并且重新计算全节点(比如矿工)会存储整个 cache和dataset,而轻客户端只需要存储 cache。挖矿(seal)时需要dataset在内存中便于随时存取,而验证(verify)时,只需要有cache就行,需要的dataset临时计算就行。Ethash源码解析dataset生成dataset通过generate()方法生成,首先是生成cache,再从cache生成dataset挖矿(Seal)在挖矿与共识中提到了,共识算法通过实现Engine.Seal接口,来实现挖矿,Ethash算法也不例外。其顶层流程如下:Seal调用中,启动一个go routine来调用ethash.mine()进行实际的挖矿,参数中的block是待挖掘的区块(已经打包好了交易),而nonce是一个随机值,作为挖矿过程尝试nonce的初始值。mine()调用首先计算后续挖矿需要的一些变量。hash为区块头中除了nonce和mixdigest的Hash值,dataset为挖掘这个区块时需要的混淆数据集合(占用1GB内存),target是本区块最终Hash需要达到的目标,它与区块难度成反比对本次尝试的nonce进行hashmotoFull()函数计算最终result(最终Hash值)和digest,如果满足target要求,则结束挖矿,否则增加nonce,再调用hashmotoFull()func hashimotoFull(dataset []uint32, hash []byte, nonce uint64) ([]byte, []byte) { lookup := func(index uint32) []uint32 { offset := index * hashWords return dataset[offset : offset+hashWords] } return hashimoto(hash, nonce, uint64(len(dataset))4, lookup)}hashmotoFull()是运算的核心,内部调用hashmoto(),第三个参数为dataset的大小(即1GB),第四个参数是一个lookup函数,它接收index参数,返回dataset中64字节的数据。func hashimoto(hash []byte, nonce uint64, size uint64, lookup func(index uint32) []uint32) ([]byte, []byte) { // 将dataset划分为2维矩阵,每行mixBytes=128字节,共1073739904/128=8388593行 rows := uint32(size / mixBytes) // 将hash与待尝试的nonce组合成64字节的seed seed := make([]byte, 40) copy(seed, hash) binary.LittleEndian.PutUint64(seed[32:], nonce) seed = crypto.Keccak512(seed) seedHead := binary.LittleEndian.Uint32(seed) // 将64字节的seed转化为32个uint32的mix数组(前后16个uint32内容相同) mix := make([]uint32, mixBytes/4) for i := 0; i < len(mix); i++ { mix[i] = binary.LittleEndian.Uint32(seed[i%164:]) } temp := make([]uint32, len(mix)) // 进行总共loopAccesses=64轮的混淆计算,每次计算会去dataset里查询数据 for i := 0; i < loopAccesses; i++ { parent := fnv(uint32(i)^seedHead, mix[i%len(mix)]) % rows for j := uint32(0); j < mixBytes/hashBytes; j++ { copy(temp[jhashWords:], lookup(2parent+j)) } fnvHash(mix, temp) } // 压缩mix:将32个uint32的mix压缩成8个uint32 for i := 0; i < len(mix); i += 4 { mix[i/4] = fnv(fnv(fnv(mix[i], mix[i+1]), mix[i+2]), mix[i+3]) } mix = mix[:len(mix)/4] // 用8个uint32的mix填充32字节的digest digest := make([]byte, common.HashLength) for i, val := range mix { binary.LittleEndian.PutUint32(digest[i4:], val) } // 对seed+digest计算hash,得到最终的hash值 return digest, crypto.Keccak256(append(seed, digest…))}验证(Verify)验证时VerifySeal()调用hashimotoLight(),Light表明验证者不需要完整的dataset,它需要用到的dataset中的数据都是临时从cache中计算。func hashimotoLight(size uint64, cache []uint32, hash []byte, nonce uint64) ([]byte, []byte) { keccak512 := makeHasher(sha3.NewKeccak512()) //lookup函数和hashimotoFull中的不同,它调用generateDatasetItem从cache中临时计算 lookup := func(index uint32) []uint32 { rawData := generateDatasetItem(cache, index, keccak512) // return 64 byte data := make([]uint32, len(rawData)/4) // 16 个 uint32 for i := 0; i < len(data); i++ { data[i] = binary.LittleEndian.Uint32(rawData[i4:]) } return data } return hashimoto(hash, nonce, size, lookup)}除了lookup函数不同,其余部分hashimotoFull完全一样总结Ethash相比与Bitcoin的挖矿算法,增加了对内存使用的要求,要求矿工提供在挖矿过程中使用了大量内存的工作量证明,最终达到抵抗ASIC矿机的目的。参考资料1 Ethash-Design-Rationale2 what-actually-is-a-dag3 why-dagger-hashimoto-for-ethereum ...

November 14, 2018 · 2 min · jiezi

在区块链上编程:DApp 开发实战——来写个竞猜游戏吧

导读:本文旨在引导对 DApp 开发感兴趣的开发者,构建一个基于以太坊去中心化应用,通过开发一款功能完备的竞猜游戏,迈出 DApp 开发的第一步,通过实例讲解 Solidity 语言的常用语法,以及前端如何与智能合约进行交互。如果正在阅读的你,从未接触过 DApp 开发也不要紧,可以先阅读【区块链上编程:DApp开发简介】进行前置知识补充。随着加密猫、FOMO3D 等游戏的火爆,去中心化应用在游戏领域遍地开花,下面就带着大家一起开发一款简单有趣的 DApp 游戏,帮助大家熟悉 DApp 开发。本 DApp 实现的合约功能:用户从 0-6 的数字中,任意组合三位数进行投注,合约计算出 3 位随机数,根据随机数的组合规则分别给予用户不同倍数的奖励,如随机数为 AAA ,A 等于 6 则奖励至少 20 倍投注金额,即奖池所有余额;A 不等于 6 则奖励 5 倍投注金额;随机数为 AAB,则奖励 2 倍投注金额;随机数为 ABC 则不奖励,同时用户可查看奖池余额和个人投注记录。合约编写可以看出合约需要实现用户投注、生成随机数、发放奖励、奖池余额查询的功能,接下来编写我们的合约代码。新建Lottery.sol合约文件,声明合约版本,^表示合约编译版本为 0.4.0 至 0.5.0(不含 0.5.0)。pragma solidity ^0.4.0;定义合约基本内容,同时声明最低投注金额。contract Lottery { uint public betMoney = 10 finney;}生成随机数,通过区块难度block.difficulty和内置函数keccak256生成随机数,在EVM中常用的数据存储位置:memory、storage,函数的参数、返回值默认存储在memory中,状态变量默认存储在storage中,我们可以通过声明memory、storage改变默认存储位置,两者的存储都需要消耗gas,但storage的开销远大于memory。contract Lottery { … function generateRandomNumber() private view returns(uint[]) { uint[] memory dices = new uint; for (uint i = 0; i < 3; i++) { dices[i] = uint(keccak256(abi.encodePacked(block.difficulty, now, i))) % 6 + 1; } return dices; } …}获取合约余额,address类型比较重要的成员属性主要有balance、transfer,分别为获取地址余额、转移eth至该地址,默认eth单位是wei。contract Lottery { … function getBankBalance() public view returns(uint) { return address(this).balance; } …}用户投注,投注方法需要使用payable关键字描述,用来表示可以接收eth;通过msg.sender和msg.value获得交易发送者地址和当前交易附带的eth。通常使用require来校验外部输入参数,当判定条件为false时,则会将剩余的gas退回,同时回滚交易;assert则用来处理合约内部的逻辑错误,当错误发生时会消耗掉所有gas,同时回滚交易。contract Lottery { … function bet() public payable { uint amount = msg.value; require(amount >= betMoney, ‘bet money not less than 10 finney’); require(address(this).balance >= amount * 20, ‘contract money not enough to pay reward’); uint[] memory dices = generateRandomNumber(); require(dices.length == 3, ‘dices illegal’); address addr = msg.sender; bool isReward = false; uint reward = 0; if ((dices[0] == dices[1]) && (dices[1] == dices[2]) && (dices[0] == 6)) { isReward = true; reward = address(this).balance; } else if ((dices[0] == dices[1]) && (dices[1] == dices[2]) && (dices[0] != 6)) { isReward = true; reward = amount * 5; } else if ((dices[0] == dices[1]) || (dices[0] == dices[2]) || (dices[1] == dices[2])) { isReward = true; reward = amount * 2; } if (isReward) { addr.transfer(reward); } } …定义事件,通过合约内部触发事件,web3 监听到事件回调进行相应逻辑处理,从而进行页面 UI 更新;同时前端也可以通过对应事件名称获取日志信息。contract Lottery { … event BetList( address addr, uint amount, bool isReward, uint reward, uint[] dices ); function bet() public payable { … emit BetList(addr, amount, isReward, reward, dices); } …与合约进行交互至此,我们已经写完了合约代码,前端页面实现就不在此赘述,主要介绍如何使用 web3 与合约交互,这里使用到的 web3 版本是 1.0,web3 1.0 和 0.2x.x 的 API 调用方式差别较大,1.0 的 API 支持异步调用。安装 Metamask 浏览器插件后,会在浏览器页面内注入一个 web3 实例。检测页面中是否存在 web3 实例,如果不存在则连接自己的实例。import Web3 from ‘web3’;if (typeof web3 !== ‘undefined’) { web3 = new Web3(web3.currentProvider);} else { web3 = new Web3(new Web3.providers.HttpProvider(NODE_NRL));}传入合约 ABI,合约地址,实例化合约对象。this.contract = new web3.eth.Contract( CONTRACT_ABI, CONTRACT_ADDR,);调用合约中的投注方法,通过try catch可以捕获到 Metamask 弹窗取消交易操作。userBet = async () => { try { await this.contract.methods .bet( … ) .send({ from: ACCOUNT, value: MONEY, }); } catch (error) { … }}查询记录的日志,可以通过指定事件名称、区块高度及过滤条件来进行日志查询,值得注意的是,在合约内不能查询到日志信息。queryEvent = async () => { const event = await this.contract.getPastEvents( EVENT_NAME, { filter: {}, fromBlock: 0, toBlock: ’latest’, } )}功能拓展比如修改用户投注金额及充值这类敏感操作,就需要管理员的权限来进行操作。同样地,我们也可以拓展赞助商的功能,通过充值奖池的累计金额排名来展示赞助商的广告,这里就不做展开了。定义修饰器,在构造函数里设置管理员地址,将创建合约的账户设置为管理员。contract Lottery { … address public owner; modifier onlyOwner() { require(owner == msg.sender); _; } constructor() public { owner = msg.sender; } …}实现修改投注金额的功能,仅管理员账户可触发。contract Lottery { … function setBetMoney(uint _betMoney) public onlyOwner { betMoney = _betMoney; } function deposit() public payable onlyOwner {} …}总结当前随机数的实现通过链上信息生成,这种生成随机数的方式容易受到不诚实的节点攻击。下一篇文章将通过多个实例介绍相应的第三方工具库的使用(Oricalize、SafeMath、OpenZepplin),生成安全的随机数。参考资料SolidityWeb3jsCryptozombiesCoursetro前置文章:在区块链上编程:DApp 开发简介文 / ielapp一个简单的程序员编 / 荧声本文已由作者授权发布,版权属于创宇前端。欢迎注明出处转载本文。本文链接:https://knownsec-fed.com/2018…想要订阅更多来自知道创宇开发一线的分享,请搜索关注我们的微信公众号:乐趣区。欢迎留言讨论,我们会尽可能回复。欢迎点赞、收藏、留言评论、转发分享和打赏支持我们。打赏将被完全转交给文章作者。感谢您的阅读。 ...

October 9, 2018 · 2 min · jiezi

在区块链上编程:DApp 开发简介

当你开始探索区块链开发,需要了解到这些。一、DApp介绍什么是 DApp?DApp 是 Decentralized Application 的简称,及去中心化应用。 在某种程度上,比特币可以说是出现的第一个 DAPP,因为它是完全开源的,为贡献者提供奖励回报,不受一个中央机构的控制,并使用区块链作为支撑技术。区块链,作为一个基础设施,提供了分布式的去中心化可信数据库,人们可以基于此,可以开发各种应用,适用于不同的场景。简单来说,DAPP 和普通的 App 原理一样,除了他们是完全去中心化的,由类似以太坊网络本身自己的节点来运作的 DAPP,不依赖于任何中心化的服务器,DAPP 是去中心化的,可以完全自动地运行。目前 DApp 通常指代基于以太坊或者 EOS 上的智能合约开发的相关应用。DApp 运行原理DApp 底层区块链开发平台就好比手机的 iOS 和 Android 系统,是各种 DApp 的底层生态环境,DApp 就是底层区块链平台生态上衍生的各种分布式应用,也是区块链世界中的基础服务提供方,DApp 于区块链,就好比 APP 之于 iOS 和 Android。什么是智能合约?如果把区块链看做是一个数据库,数据源,智能合约基本上就是一段数据库操作脚本,它决定了你如何在区块链上存储数据,修改数据。DApp应用案例前往这里可查看 DApp 的行业最新动态: https://www.stateofthedapps.com/cryptokitties 加密猫Fomo3D智能合约开发简介智能合约是代码(它的功能)和数据(它的状态)的集合,存在于以太坊区块链的特定地址。 智能合约账户能够在彼此之间传递信息,进行图灵完备的运算。智能合约依靠被称作以太坊虚拟机(EVM) 字节代码(以太坊特有的二进制格式)上的区块链运行。智能合约使用诸如 Solidity 等高级语言写成,然后编译成字节代码上传到区块链上。智能合约开发流程大概有以下步骤:编写智能合约(如基于 solidity)测试智能合约,在测试网络或者私有链进行合约的功能测试编译和发布合约,将合约部署到链上操作合约,利用诸如 web3.js 等接口,通过访问智能合约的地址,来调用和操作智能合约。结构示意图:智能合约的开发流程图:SoliditySolidity 是一种语法类似 JavaScript 的高级语言。它被设计成以编译的方式生成以太坊虚拟机代码。代码片段:pragma solidity ^0.4.22;contract helloWorld { function renderHelloWorld () public pure returns (string) { return ‘helloWorld’; }}ERC-20最著名的智能合约,想必大家都听过,那就是 ERC20。ERC-20 是一种代币的标准协议,简单地说,任何 ERC-20 代币都能立即兼容以太坊钱包(几乎所有支持以太币的钱包,包括 MIST、imToken 等),由于交易所已经知道这些代币是如何操作的,它们可以很容易地整合这些代币。这就意味着,在很多情况下,这些代币都是可以立即进行交易的。一个基于 ERC-20 的代币包含以下接口:contract ERC20Interface { function totalSupply() public constant returns (uint); function balanceOf(address tokenOwner) public constant returns (uint balance); function allowance(address tokenOwner, address spender) public constant returns (uint remaining); function transfer(address to, uint tokens) public returns (bool success); function approve(address spender, uint tokens) public returns (bool success); function transferFrom(address from, address to, uint tokens) public returns (bool success); event Transfer(address indexed from, address indexed to, uint tokens); event Approval(address indexed tokenOwner, address indexed spender, uint tokens);}Solidity开发环境介绍下面我会粗略的引入介绍一下 Solidity 智能合约相关开发环境跟工具,这些都是目前智能合约开发中常用的工具集合。IDE开发基于Solidity的智能合约,可以使用以下开发环境VSCode + Solidity PluginRemix Solidity IDE (https://remix.ethereum.org)TruffleTruffle 是针对基于以太坊的 Solidity 语言的一套开发框架。本身基于 Javascript。内置的智能合约编译,链接,部署和二进制文件的管理。快速开发下的自动合约测试。脚本化的,可扩展的部署与发布框架。部署到不管多少的公网或私网的网络环境管理功能使用 EthPM&NPM 提供的包管理,使用 ERC190 标准。与合约直接通信的直接交互控制台(写完合约就可以命令行里验证了)。可配的构建流程,支持紧密集成。在 Truffle 环境里支持执行外部的脚本。安装 Trufflenpm install -g trufflemkdir myproject && cd myproject && truffle initGanacheGanache 是一个带有图形界面的本地运行的以太坊区块链浏览器/模拟器,它在本地运行了一个 RPC Server,通过连接这个 Ganache,我们可以完成智能合约的本地测试,而不需要真正的接入以太坊的公网或测试网络。通过使用 Ganache,你可以快速的看到你的应用是如何影响区块链的。其中细节:如你的账户、余额、合约及 Gas 成本。Gethgeth 的全称是 go-ethereum,是以太坊的官方钱包客户端。Geth 是基于命令行的。通过使用 Geth 和相关参数,我们可以接入以太坊的公网,测试网以及私有网络。以太坊除了主网络,还有各种各样的测试网络。使用 geth 前要先解决要进入哪一个网络。Geth 相当于在本机启动一个以太坊网络节点,但是通过参数控制,可以让节点选择成为全节点或者轻节点。Geth 控制台提供 admin、debug、eth、miner、net、personal、rpc、txpool、web3 等服务及命令。比如有这些常用的操作:eth.blockNumber 可以查看当前的区块高度,总共有多少区块eth.getBlock(xxx) 可以查看指定区块的信息eth.accounts 查看当前钱包的账户地址,当第一次运行私有链网络的时候,没有账户,需要新建eth.coinbase 矿工账户,当网络进行挖矿操作挖到新的区块后,奖励会到这个账户里personal.newAccount() 新建账户,会提示输入密码,之后账户会以加密好的私钥文件存到data/keystore目录下miner.start(threas_number) 开始挖矿,前提是当前钱包已经有coinbase矿工账户miner.stop() 停止挖矿图示在 geth 命令行下新建账户及获取余额操作: MistMist 是以太坊的官方图形钱包,通过该钱包,用户可以很方便的管理账户,查看余额,以及发送和接收交易。Mist 还有一个非常实用的功能就是,编译和部署 Solidity 智能合约。web3.jsweb3.js 提供了 web3 对象,封装了一组可以用来操作智能合约的方法。底层实现上,它通过 RPC 调用与本地节点 geth 进行通信。geth 本身就可以与合约进行交互,通过 web3.js 再封装了一层,这样我们可以使用 js 程序与合约交互,方便开发。引入npm install web3以太坊通过 web3 的交互流程大致如下:总结随着区块链近些年的大红大紫,DApp 被推上了风口浪尖,本文从技术的角度大致介绍了一下 DApp 所涉及的技术要点。后续的文章,可以更加详细的分享一些 DApp 开发的具体案例,引入跟介绍一些 DApp Demo 跟具体开发流程等。后续文章:在区块链上编程:DApp 开发实战——来写个竞猜游戏吧文 / 李工普通程序猿,长期混迹移动互联网曾供职 91 与百度,现任区块链开发工程师资深韭菜,在韭菜经历中学习到扎实的区块链知识编 / 荧声本文已由作者授权发布,版权属于创宇前端。欢迎注明出处转载本文。本文链接:https://knownsec-fed.com/2018…想要订阅更多来自知道创宇开发一线的分享,请搜索关注我们的微信公众号:乐趣区。欢迎留言讨论,我们会尽可能回复。欢迎点赞、收藏、留言评论、转发分享和打赏支持我们。打赏将被完全转交给文章作者。感谢您的阅读。 ...

October 9, 2018 · 2 min · jiezi