精华内容
下载资源
问答
  • 3月23日晚20:00点,【时点对话】邀请到了老白,般若(Prochain)创始人,区块链大数据专家,来进行对话主题:大厦将倾,以太坊路在何方。本次对话,老白以行业多年的经验,为我们分享了其对以太坊和EOS未来发展看法...

    3月23日晚20:00点,【时点对话】邀请到了老白,般若(Prochain)创始人,区块链大数据专家,来进行对话主题:大厦将倾,以太坊路在何方。



    本次对话,老白以行业多年的经验,为我们分享了其对以太坊和EOS未来发展看法。


    以下为对话原文整理





    【时点对话·开场】


    2018年初,Ethereum 似乎要成为币圈不可或缺的主角。借着一波牛市,甚至圈内流出 ETH 的价格会在接下来的几个月问鼎 $5000 的传闻。但是,它却匪夷所思地从$1,300 的顶峰滑落至 $500 的低谷。


    前天,市场稍有回暖,然而 ETH 却跌了 2.7% 。另外值得注意的是,在过去的8天里,ETH价值总计坠落 27%!成了了币圈 TOP 10 榜单中最大 loser!


    短期内比特币并不那么熊的情况下,ETH 不停下跌。显然,用单薄的“熊市”二字解释 ETH 的短期疲软,已经说不通了。大厦将倾,以太坊路在何方?下面有请本期嘉宾-老白!





    【时点对话·第一问】


    时艳强:老白,你2011年开始接触比特币,与李笑来同期。能介绍一下当时比特币市场情况么?是否对比特币持续投入了?般若(Prochain)项目能介绍一下么?


    老白各位【布洛克财经】的朋友,大家好!回答布洛克财经【时点对话】第一问。2011年12月,我开始接触比特币。当时是看到了一篇文章,叫《比特币,史上最危险的货币》,看了这个文章以后就专门去翻了一下(比特币)白皮书,觉得这个技术是非常可行的。那个时候还是比较早期的状态,所以只是尝试性地去购一点币,没有把它当作一个正经的业务来做。因为还有很多的互联网业务在运作,主要精力不在比特币上。当时的市场是这样的,就是大家想买币的话,一般都会去门头沟(Mt.Gox)。那里面最大的问题就是缺乏一个稳定的充值渠道,包括贝宝(Paypal)和信用卡都是不支持的,所以买币的门槛是比较高的。



    2013年,比特币在中国开始上线了。我第一时间注册了账户,但是这时候价格已经涨到了大概七百人民币左右。当时觉得这个价格已经太高了,就没有再进入,因为年初时候价格可能在一百多人民币左右。那段时间也是移动互联网的一个创业高峰期,所以主要精力没有放在比特币这方面,但是隔三差五也会关注一下币市的走势。


    2016年底,发现比特币价格从一千人民币左右开始升到五千人民币左右,与Gartner的技术曲线走势是非常像的。2013年,比特币价格达到了一个高点,八千人民币左右,然后又跌落到一千左右,这个时候就是有点儿像Gartner泡沫期,媒体过度关注了,这时候它就回归到一个正常价格状态。2016年下半年,发现价格开始回升了,就有一点像技术曲线里一个技术开始往成熟的方面去走的这么一个势头。


    所以我们认为比特币不仅仅是一个金融产品,它同时也是一个科技产品,加上Twitter上面关注了一个人,叫Kim Dotcom,他发了一条推特,就重新入市了。




    (大意:比特币涨到一千美金了,而且这只是一个开始)


    2017年6月,国内三大交易所同时开放了以太币的交易,我在这个时候开始正式入场,开始进行以太坊的一些投资。我们首先投入到了一个叫ENS的以太坊域名注册方面的一个业务,同时也开始关注项目众筹这个事情。6月份前后,有几个大的项目,一个叫Basic Attention Token,是海外的一个区块链广告业务;以及Status,就是区块链微信;还有一个叫TENX,就是区块链信用卡的一个项目。我们关注到这些项目会以非常快的速度就达到了众筹的硬顶,而且这些项目上市以后往往就都是涨幅比较好的,所以带动了第一波以太坊的价格上涨。


    同时那段时间参加了北京这边有一个叫dorahacks的一个黑客马拉松活动,与腾讯的同事一起组建了区块链团队,这也是当时唯一做区块链方向的一个团队,这个时候大家就去思考有什么好的区块链方向可以做,我们就回顾了互联网的一个发展路径,最早就纯数字化的业务是比较容易落地的,尤其是这种广告、游戏。而这个广告市场的一个特点就是,它是一个多方角色来共同参与的,包括广告主、流量主、用户三方。那么广告主和流量主之间呢,也是存在信任成本高的问题,正好可以通过这个区块链技术来解决信任成本的问题,所以就考虑用广告切入。



    看这张图的话可以看到现在广告市场存在的一些问题。第一个就是投放精度低,广告主并不知道受众在哪,缺少一个数据手段。第二就是欺诈流量高,在广告的流量方提供的流量里面有60%,甚至80%都是机器人的点击欺诈,对于广告主的资金造成了大量的损失;第三就是数据不透明,广告主也不知道资金投放的投向到底是什么,有哪些用户去点击了;第四就是数据不互通,BAT他之间的数据是不通的,所以导致数据存在孤岛这个现象。


    所以我们就是从广告市场的一个痛点开始切入,正好基于以太坊公链、雷电网络 与 IPFS 分布式存储技术,建立一个基于大数据的精准广告分发系统。广告主通过智能合约建立投放任务,对于触发广告的用户和媒体进行奖励,以 PRA Token 实时结算。ProChain 主要服务于以太坊生态,为即将爆发的去中心化媒体提供一种收入模式,同时为去中心化应用(ĐAPP )提供一套完整的链上推广方案。


    他主要解决的这个问题就是五个,①数据投放过程不透明 ②点击欺诈 ③结算延迟 ④数据孤岛 ⑤用户屏蔽广告。这都是现有广告市场存在的典型痛点。




    【时点对话·第二问】


    时艳强2014年7月至今,以太坊价格从1.89元至高峰时10000元,增长速度令人咂舌。以太坊是什么,为什么称其为区块链2.0?为什么曾经ETH价格火箭式的上升?为什么现在其他主流币价格不断回暖,仅以太坊价格不断探底,什么原因?


    老白回答布洛克财经【时点对话】第二问。2014年,以太坊是开始进行众筹,它其实才是比特币历史上第一大的众筹项目。因为他当时在最早创立阶段是没有ERC20的标准的(也就是TOKEN所采用的技术标准,没有落地刚需),所以它的价格长期是盘在10美金左右,甚至到2017年年初的时候只有80元人民币前后,当时也是关注比较多的。那么当ERC20标准通过之后,大家慢慢可以意识到这个价值了,然后价值价格才开始一直往上走,从一块多钱一直涨到一万块。为什么称它为区块链2.0,就是他本身有一个最大特色就是智能合约,他这种智能合约可以进行一个链上的原生资产的标准化结算


    在以太坊的官网里面可以看到它的典型应用有三个,第一个是创建Token;第二个功能是设置众筹;第三功能是投票与去中心化自治组织。大部分现在的项目方其实主要用到的是第一和第二,后来因为众筹这个东西无法再进行了,现在大部分的项目方还是以创建Token为主。实际上它还有很多的功能,比如投票的功能也是一个非常好的机制,这在后续的项目里其实都完全可以用起来。区块链1.0的数字货币称为Coin,特点是需要通过算力进行挖矿,比如莱特币,狗狗币,他们都是基于比特币源码的一个改进币种。而通过以太坊发行的代币被称为TOKEN,可以跳过挖矿这一步,相当于借用了以太坊的节点,直接分叉出一个币种,从而实现快速建立数字货币的需求


    那在2018年1月下旬之后,币市确实是转入低迷行情,有很多原因。有一个就是以太币价格取决于Token发行后的市场表现,如果破发严重,甚至机构都是亏损,没有人参与,自然价格回归正常水平。



    【时点对话·第三问】


    时艳强:有人说以太坊价格下跌,除了一级市场私募、ICO遇冷之外,更可能是有人在故意操纵,以便抄底建仓。对于利空建仓,您怎么看?V神曾警告:如果再炫富,其退出以太坊。如V神退出,以太坊社区会如何?


    老白回答布洛克财经【时点对话】第三问。不知道是否有人做空以太坊,但以太坊发行Token是它的特色。以太坊除了被项目方应用以外,也被各种骗子盯上,发行空气币圈钱跑路,导致了对市场的不信任,这才是它下跌的一个根本原因。投资者对项目的鉴别能力也在增强,不会随便一个项目都去投资了。 V神是一个理想主义青年,希望维护社区氛围,已经着手优化Token发行机制-DAICO,将项目方的进展列入考核,参加众筹者可以决定是否对项目方释放ETH。如果V神退出以太坊,还有社区会继续维护。



    【时点对话·第四问】


    时艳强:EOS创始人BM称:EOS开发基本结束,将在6月份主网测试。EOS被誉为区块链3.0,为何大家看好EOS?EOS上线成功,会对以太坊产生哪些影响?从Etherscan上调查发现,EOS众筹地址曾转出41万以太坊充值到Bitfinex进行拉盘,是对手在做空以太坊?


    老白回答布洛克财经【时点对话】第四问。EOS有21个区块主节点以及100个备选节点,它的去中心化程度没有以太坊那么高,因为以太坊可能是上万个节点在进行全部共识,但是EOS它牺牲了部分的去中心化,导致它的效率更高,更适合高频低价值的区块数据记录,用户免费的特性尤其适合传统互联网产品上链


    那EOS上线成功的话,对以太坊有什么影响呢?其实以太坊和EOS实际上是完全不同的两个方向,不能说是互相替代,他们是各有应用场景,以太坊潜在的竞争对手,除了EOS外,还有AE、NEO、CARDANO、RCHAIN、ZILLIQA等公链,主要解决公链性能,还有数据库分片以及扩容的问题。


    那么EOS众筹的以太币是怎样使用呢?因为是用于公司支配的,具体怎么操作不是特别清楚。但是从一个技术上面去讲,很多人其实并不知道到6月1号之后,EOS的ERC20的TOKEN是停止交易的。他将最后在以太坊的TOKEN地址上生成一个快照,用于启动EOS公网。因为还有两个月的时间,相信大家反应过来以后,价格会进一步提升,这个才是真正价格提升的一个逻辑。那么现在已经有几十个EOS的项目在筹备,根据这个快照来进行糖果发放,有很多的项目,现在发放比例是超过50%的,所以这个是非常好的一个糖果行情。



    【时点对话·第五问】


    时艳强3月18日,Facebook被爆出超过5000万用户信息被滥用,Facebook股价最高跌幅超过10%,市值蒸发超过600亿美元。区块链作为价值网络,其用于隐私保护是否能够避免类似事件?通过区块链解决用户数据问题的遭遇的瓶颈是什么?


    老白回答布洛克财经【时点对话】第五问。用户数据隐私性是区块链一大特色,多数公链的用户持有私钥,才能操作账户,没有任何中心节点可以掌控用户私钥的使用情况,这和传统的中心化的服务器来保管密钥的这种方式是完全不同的。数据方面也是同样,用户在区块链上的数据,自己可以选择性的去授权给不同的应用,同时获得相应的回报。比如授权给广告主做精准投放,用户可以被推送更高价值的广告,点击的收益会更高。有些数据泄露会流入地下,用于电话营销、恶意诈骗等灰产。


    现阶段,通过区块链技术可以解决用户数据保密的需求,但是当前技术最缺的是去中心化的结构化数据库,这个东西可以保存大量的用户信息,现在大家知道的以太坊、比特币区块无法承载这么多的用户数据,需要更好的公链承载用户数据。



    【时点对话·第六问】


    时艳强:币安被日本金融厅警告的消息不胫而走,数字货币市场相应股价大跌,两者是否有关系?目前币市行情,你对回暖期的预测和对投资者的建议是?


    老白回答布洛克财经【时点对话】第六问。对于币市是否能回暖,我个人的观点是取决于项目能否有效落地,尤其是能否有爆款的去中心化应用,也就是DAPP的出现。在去年我们只看到了以太猫,这一款产品就导致了以太坊的主网络的拥堵,侧面也说明现在以太的一些性能的限制,还不太适合DAPP大规模去开发。包括我们自己ProChain也在思考迁移到EOS来满足更更高的TPS要求,以及用户端免费,这些都是非常好的特性。


    普通投资者,我个人是建议适当囤些主流公链币,以及产品已经落地的区块链项目的Token。区块链项目距离大规模应用还需要几年时间,多关注GITHUB的代码的提交的情况,提交越频繁的,代码质量越高的项目,实际上是应该注意重点关注的。


    行情下跌与币安是否有关系,暂时没有什么逻辑。还是取决于整个市场的信心,不仅是交易所层面的,关键还是项目落地方面。



    【布洛克财经·提问一】


    问题你好,老白。之前听朋友提到过般若项目,我对区块链技术和广告生态结合挺感兴趣。以前我们在百度和58上投放广告,钱消耗的很快,效果不怎么好。我想了解一下,你们这个广告系统现在什么发展阶段,什么时候能落地使用呢?广告能覆盖多少人?----来自【布洛克—北京--225】


    老白回答布洛克财经【时点对话】提问一。这个问题问得非常有意思,区块链广告有两种玩法:一种叫做广告加区块链;一种叫做区块链加广告。那么它们区别是什么呢?第一种方式,广告加区块链就是他自有流量,那本身我就是一个做广告的一个流量主,通过区块链的这种方式来让上下游达成透明,它本质上是一个联盟链的一个机制,这是第一种方式。第二种方式,基于一个成熟的公链上面去搭建一个服务,服务于这条链上的各个业务的一套生态系统,那这叫区块链加广告,像之前所说的Basic Attention Token,包括我们自己都是在做的都是属于区块链加广告这样的一个业务。


    为什么在百度上投放广告,钱消耗的很快?这个是存在刚才说的点击欺诈。一个小广告主放上去的广告,很快就被点击完了,这个问题用区块链怎么解决呢?区块链有个叫做币天销毁的一个机制。当用户持有你的币,并且保留在你的钱包里一定时间,没有操作的时候,它才能够去触发这个智能合约,然后获得Token。并且在获得Token的这个过程中,实际上相当是打了一笔交易,打到一个链上,这时候你的币天就会归零,就像一个气槽一样,会一点一点地积攒,攒够了气你才能去点击广告获得收益,这个时候气又重新归零了,你重新要去积攒,用这种方式来防止所谓的薅羊毛的这种行为,包括机器刷量的行为。


    我们Prochain这套系统是原生链上区块链的一个系统,他们主要广告主服务是原生链上的数字资产,包括TOKEN的项目发行方、包括DAPP的以太坊游戏发行商,他们是主体,他们通过TOKEN的形式来进行投放,用户在点击了他们项目之后获取一定的糖果,以这种形式来完成一个闭环。


    这是传统的链下向链上迁移是有一个逻辑的,那就需要链上的广告系统省去中间的信任成本,用户获取成本要比链下低,这里头产生的套利空间,即使链上流量很小,就是咱们所说的去中心化媒体现在还没有起量,但是它仍然是一个价格很便宜的获取用户的一个渠道。通过这种套利机制,让更多的链下用户选择用链上的方案来做。


    去中心化媒体会在六月份,应该是包括EOS、Filecoin这两个比较大的公链项目,一个是做计算,另外一个是做存储,这两块都会进行挖矿,开始提供这样的去中心化媒体的服务,这个时候链上媒体才能起来,就每个人的电脑都是一个服务器,不需要把数据保存在一公用服务器里,就保存在你自己的电脑里就可以进行浏览,这种就叫去中心化媒体。


    整个链下向链上迁移的过程需要比较长的时间,但是因为存在套利空间,所以会逐步地把链下的用户往链上进行导入。


    我们自己目前的MVP,最小可用化的一个产品模型在年前已经落地了。我去帮项目方来进行一个项目的精准营销,通过投放Token的方式,用户点击这个项目方的信息,了解项目来获取Token的一个形式,这个闭环已经通了,我们这个产品名字叫Prabox,IOS版已经在App Store上线了,安卓版在这个月底也会上线。



    【布洛克财经·提问二】


    问题老白哥好,我刚接触区块链不久,带我炒币的朋友说现在投资IPFS矿机很划算,不知道白老师了解IPFS矿机吗,靠不靠谱呀?----来自【布洛克—上海--053】


    老白回答布洛克财经【时点对话】提问二。IPFS矿机和比特币不一样,它是通过提供存储和带宽。你有一个磁盘阵列,以及你有比较好的网络条件,用这种方式来进行挖矿。那么一般来说,用电信机房或者是有些运营商的资源去做这个事情会比较靠谱,现在所说的华强北这种专卖的矿机可以暂时先不考虑,因为具体怎么用这套系统现在还没有确定,但是这个挖矿是一个好机会



    【布洛克财经·提问三】


    问题老师好,身边一起玩币的同学说EOS今年能涨到500,一直在推荐,老师您能多介绍一些EOS的资料吗,为什么大家都这么看好EOS?----来自【布洛克—北京理工大学--05】


    老白回答布洛克财经【时点对话】提问三。EOS到6月1号之后就会停止交易了,所以过了6月1号它并不是EOS了,它可能是EOS主网的一条新公链上的一个币,这个币还不只是一个,有多条公链,因为EOS并不是一个像以太一样的一条公链,它是一个软件系统,任何人可以基于这个软件系统来搭建自己的公链。但前提是拥有足够量的EOS的Token持有者的同意才可以,所以就是具体每条链的Token它哪一条涨的比较高,这个说不清楚,但是从整个趋势来看的话EOS是比较适合互联网应用开发的,所以相信这里面会诞生更多的去中心化应用,它比以太坊开发的DAPP性能更好一些。


    你可以通过EOS的众筹合约能够看到众筹结束之后,也就是6月1号之后任何人都可以把他的Token进行冻结,这个时候就没法进行转账了。


    来源:布洛克财经

    展开全文
  • 为你的以太坊应用程序设计架构

    万次阅读 2019-04-28 09:42:12
    当你即将开始以太坊开发,并查阅...在本篇文章中,我将提及以太坊应用程序中最经典的一些场景。它们的出现源于这三个部件(客户端、服务器与区块链)间的不同互动。我将论述无服务器应用程序、浏览器插件、私有节点...

    当你即将开始以太坊开发,并查阅了一些很好的教程帖子后,创建你的首个以太坊应用程序就成为了你所面临的挑战。

    这会带来一系列围绕在你的应用程序架构和蓝图设计周围的新挑战:传统的客户端-服务器应用程序中现在又有一个新部件,区块链

    1

    在本篇文章中,我将提及以太坊应用程序中最经典的一些场景。它们的出现源于这三个部件(客户端、服务器与区块链)间的不同互动。我将论述无服务器应用程序、浏览器插件、私有节点、离线签名和其他一些在设计你的解决方案蓝图时扮演重要角色的问题。

    无服务器应用程序中的客户端-区块链

    以太坊应用程序的典型风格是无服务器的(serverless),你应用程序的整个流程全部是在客户端和区块链之间进行的。

    这里的第一步是向用户确切地分发客户端代码。最简便的方法是建立一个静态页面,其中要包含一个可用web 3(校对注:web3是一套以太坊客户端的API,有几种不同语言的实现,即客户端库,被用来通过JSON RPC接口与以太坊节点进行交互)的网页应用程序。任何地方都可托管这类页面:AWS S3、 Google Cloud、 Github pages、其它云服务供应商或你自己的服务器。另外,如果你能指望你的客户端支持bzz或ipfs协议,那么你就甚至可以通过 Swarm 或IPFS来分发代码以达到完全的去中心化。

    查询区块链

    下一步就是使应用程序能够读取区块链中的信息,而这正如你所知,需要连接到一个活跃的以太坊节点上。作为一个处理节点的 Web3 实际连接的组件,Web 3 provider 会设置好它。

    现在,你的一些用户可能已经连接上一个节点了,比如说是通过官方 Mist 客户端或通过浏览器插件,如非常流行的 Metamask,它们对于区块链而言就像轻量级客户端。它们的常见问题答疑中甚至提供一个代码片段,告诉你如何检测它在客户端上是否可用,以及如何将它用作web3 provider。

    // Adapted from https://github.com/MetaMask/faq/blob/master/DEVELOPERS.md#partly_sunny-web3---ethereum-browser-environment-check
    window.addEventListener('load', function() {
    
      // Checking if Web3 has been injected by the browser (Mist/MetaMask)
      if (typeof web3 !== 'undefined') {
        // Use Mist/MetaMask's provider
        window.web3 = new Web3(web3.currentProvider);
      } else {
        // fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
        window.web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
      }
    
      // Now you can start your app & access web3 freely:
      startApp()
    })

    那么,那些没有 Mist 或 Metamask 的用户怎么办呢?如果你只是需要他们来查询区块链而并不发送任何交易,那么你可以连接一个公共以太坊节点。这得是一个向公众开放的 geth 或 parity 节点,但没有暴露账户管理的个人 API,也没有何解锁的账户。这样的节点只能用作查询固定的合约函数的网关。如果你不想自己作为宿主提供这样的节点,在 Infura(校对注:一个提供区块链基础服务的网站)上可以找到无偿提供的公共节点服务。

    这样,有正在运行的以太坊基础设施的用户可以连接到的他们信任的节点,而不那么精通技术的用户则可使用公共节点。这意味着为了便于使用,后者将选择相信由第三方控制的节点所提供的信息。

    发送交易

    查询区块链容易,但是如果你想要你的用户发送交易并在智能合约上真正采取改变状态的行动,那该怎么办呢?对于你那些安装了Mist或Metamask的用户,问题立马就能解决,只需为他们提供一种管理帐户、在应用程序需要的时候请求用户同意交易的方法。Mist会提供一个通向用户本地节点及其帐号的途径以签署交易,而Metamask则在客户端签署交易,并将其中继到Metamask公共节点上。

    2-源于用Truffle和MetaMask开发以太坊去中心化应用程序 -

    对于你的其他用户,如果你不要求他们安装Metamask或使用Mist来用你的应用程序,那你就需要指导他们从他们任一钱包里手动发送交易来与你的应用程序进行交互。

    大多数应用程序是通过让用户发送一定量的以太币到一个地址来实现这种互动的,该地址可选地包括一个二维码或一个复制到剪切板的按钮。

    3-Shapeshift 以太坊交流对话框-

    当带外交易(Transaction Sent Out-of-band)发送(校对注:指把交易数据发送到已连接的本地节点或公共节点上)的时候,你的客户端应用程序应当及时监控合约事件以更新用户界面。由于监控事件只是查询区块链的一种简单的方法,所以通过一个公共节点就能轻松实现。

    现在,为了执行合约函数,你可能需要请求用户发送以太币和附加数据来执行特定函数。你可以用合约函数中的 Request 方法轻松获得运行该方法所需的数据,并将数据和目标地址呈现给用户。

    SimpleToken.at(tokenAddress).transfer.request("0xbcfb5e3482a3edee72e101be9387626d2a7e994a", 1e18).params[0].data
    // returns data for invoking transfer with args => '0xa9059cbb00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000de0b6b3a7640000'

    就个人而言,我不是这一模式的狂热粉丝,因为它需要用户进行相当复杂的操作。不是所有的用户都知道附加数据是如何在以太坊中发挥作用的,更不用说如何在交易中发送数据。

    如果你确实要以这种方式实现,请确保你合约的 fallback函数拒绝所有支付款项或有一个合理的默认行为,这样如果用户在手动发送交易时忘记了将附加数据包含在内,他不会失去所发送的资金。

    注意,在很多情况下,一个巧妙设计的fallback 函数可以一直为发送交易的用户执行预期行为。这样的话,你的智能合约只会对用户发送款项来作出反应,并根据当前的状态(合约状态)运行不同的函数(合约函数),还不会要求用户设置任何附加数据。

    另一个技巧就是添加代理合约,一旦收到以太币,每一个代理合约就要执行你主合约中的一个特定合约函数。举一个简单的例子,比如说你正在执行一个二进制投票应用程序:你会在主合约中加入一个vote-yes函数(投赞成票)和一个vote-no函数(投否决票)。与其要求用户将赞成或否决的标记包含在交易内,你可以部署两个附加合约,无需其他逻辑,只需代表信息发送者在收到任何交易时调用主合约中的vote-yes函数或vote-no函数(相应在主合约中投赞成票或否决票)。不用说,这个方法只适用于非常简单的应用程序,但经常能帮助那些浏览器里没有以太坊识别软件的用户使得难度降低。

    创建你自己的钱包程序

    让你的用户与你的智能合约进行复杂互动的另一选择实际上是将钱包管理加进你的应用程序中。对于用户来说,第一步是应用程序可以为他们创建一个新的帐户,而该账户可用于直接通过你的代码发送任何交易。

    4-Coral Fundraiser 向新生成的账户要一个密码,可以下载并加密地保存到用户的电脑上,以便用户之后可以在在其他会话中乃至用另一个钱包来访问它。

    用户之后将需要转入一些以太币以便可以使用这一账户,要么从另一个账户转入,要么直接从交易所购得;在这里可以考虑将 Shapeshift 集成进来以便于使用。一旦账户上有支付交易费用所需余额,客户端代码就可以代表用户通过一次简单点击来执行任何所需操作。

    在这种场景下,你的应用程序将使用所生成账户的私钥来签署任何客户端交易,然后将其转发到一个公共节点去执行。

    这一模式涉及繁重的编程任务,因为你需要添加对一个以太坊账户的生成、加密和导入功能(你可能想看看以太坊-钱包库是如何实现这些功能的)。另外,所有的交易需手动精心制作和签署,然后作为原始交易发送到一个节点。这还需要用户的更多参与,其任务是建立一个新账户,且有义务保护账户文件的安全。不过,一旦条件齐备,你的用户就可以毫无障碍地直接从你的应用程序中进行以太坊交易,无需安装任何软件。

    总而言之,你采用哪种方法将主要取决于你接触的这类用户以及你期待用户与你的应用程序进行的这类互动,无论是持续使用还是偶尔使用,甚至是一次性访问。

    服务器到区块链

    现在,让我们在上述结构中添加一个服务器,并在这一节里先不管客户端。同样地,接下来的内容可能不仅适用于应用程序服务器,还适用于独立应用程序、脚本或批处理程序。

    建立一个本地节点

    第一个解决办法很普通:建立一个本地以太坊节点,并在你的程序中使用其 JSON RPC 接口来进行你需要的区块链操作。

    5

    你可能也想要留一个未锁定帐号来运行你应用程序中的交易( Geth 和 Parity 的解锁标志可能在这里会派上用场)。必须确保节点的 JSON RPC 接口除你的应用程序之外其它地方都无法访问,否则任何人都有可能进入你的节点并盗取你的资金。有一个额外的预防措施,未锁定账户里的钱保持在最小值即可,并在需要时从另一个地方将其取出。

    离线签名和公共节点

    另一个解决办法,和上一节提到的解决办法类似,就是让你的应用程序离线签署交易,并将其转发到一个公共节点。本文探讨如何在你的 Truffle 配置里建立一个web3provider engine来透明化地离线签署交易,并将其发送到一个Infura节点上。

    6

    如果你按这条线路走下去,记住你这是在盲目相信你所连接的公共节点:虽然这个节点无法更改你发送过去的交易,但它可以选择不转播到网络,或向你的查询提供假回应。这一点可通过同时连接多个节点,并将同样的交易或查询发送给所有的节点来缓解;但是这会让你的代码库复杂很多。

    全盘了解

    从头到尾说了一遍设置客户端-区块链和服务器-区块链查询和交易的不同方法后,是时候来讨论如何将一切安排协调起来了。

    协调客户端和服务器

    客户端和服务器与区块链同时交互暗示着可能两者你都需要协调。比如,你可能想让服务器对客户端链上执行的操作作出反应,或在客户端中将合约状态的变动可视化。

    客户端和服务器中观察合约变化的规范方式是监听合约事件。仔细设计你自己的事件,以确保所有相关行为都有一关联事件,并使用索引参数,这样观察者可以只筛选与之相关的事件。一般来说,客户端只会监听直接影响它们的事件,而服务器可能会监视所有与应用程序相关的合约。

    如果交易是通过你的应用程序代码直接发出的,那你也可以直接监视具体交易以检查它们是否成功。

    7

    客户端也可以把它们发布的交易号发送到服务器来作为链上执行行为的证据,而不是让服务器来监听事件。但是,要记住,恶意行动者可能会监视链上交易,并可能将一个来自于不同客户端的交易号发送给服务器,假装这是属于他的。确保只将客户端到服务器的信息当作通知,而不是最终事实的来源。

    无论是靠监视交易或事件,都要确保只有经过合理数量的确认后才能对其做出响应。即使你有一个交易在挖矿,它仍会链重组的影响,并最终在不同的环境中运行,也可能会变得无效。在对链上事件做出响应前,大概等十二个区块(测试网中需要更多),但是可以考虑让你的终端用户知道交易是成功了,但未经过足够数量的确认,这样他们不会被蒙在鼓里。

    服务器职责

    现在,你需要回答的一个关键问题就是到底为什么你需要一个服务器。在传统的客户端-服务器应用程序中,服务器作为一个永久储存器,执行业务逻辑,并协调客户端;现在所有任务都可以在链上完成。

    但是,服务器仍有很多用途可以支持你的应用程序。首先,链上代码无法直接与链外服务一起工作。这意味着如果你想要与第三方服务结合起来,注入像美元/以太币利率这样的外部数据,或执行如发送邮件这样的基本操作,你就需要一个服务器来做到这些。

    服务器也可充当你智能合约的高速缓冲存储器或索引引擎。虽然事实的最终来源是区块链,但是你的客户端可以依赖服务器的搜索功能,并证实链上返回的数据。

    如今以太坊的大数据存储极其昂贵,这是由使用合约存储时产生的gas成本造成的。同样地,你的应用程序可能也会靠服务器来储存大数据块,而只有一个散列是保存在链上进行验证的。

    这也同样发生在复杂的计算中,因为复杂的计算所消耗的gas也许会超过以太坊区块的gas上限,所以需要在链外的基础架构中运行。

    值得一提的是越来越多关于以太坊虚拟机(EVM)的项目正在出现,这些项目为这些服务提供了无缝集成。例如用于存储的 FilecoinStorj ,用于计算的 Truebit,或用于预言机(校对注:为区块链应用获取由第三方Web API提供的数据,比如天气、股票等公共数据)的 Oraclize 。

    最终,服务器可能变得越来越瘦,直到它们消失在无数侧链服务和集成中。可能,几年后,这个帖子将过时,我们的区块链应用程序将会以一种绝对分散的方式运行。

    如果你对讨论智能合约安全感兴趣,请加入我们的slack channel在Medium上关注我们申请与我们共事智能合约安全系统开发审计工作也可以找我们。


    原文链接: https://blog.zeppelin.solutions/designing-the-architecture-for-your-ethereum-application-9cec086f8317
    作者: Santiago Palladino

    展开全文
  • 【区块链技术工坊34期】王登辉:以太坊通证协议标准及应用场景 2)议题: 通过本次技术分析,可以了解以太坊的ERC定义及知名ERC协议标准,如同质化通证系列ERC20以及ERC223协议; 非同质化系列ERC721以及 ERC875,ERC...

    1,活动基本信息

    1)题目:
    【区块链技术工坊34期】王登辉:以太坊通证协议标准及应用场景

    2)议题:
    通过本次技术分析,可以了解以太坊的ERC定义及知名ERC协议标准,如同质化通证系列ERC20以及ERC223协议; 非同质化系列ERC721以及 ERC875,ERC1155协议;STO标准半同质化系列ERC1400系列协议。

    议题纲要:

    1. ERC的定义及标准列表
    2. 同质化通证ERC20系列 - ERC20、ERC223
    3. 非同质化通证ERC721系列 - ERC721,ERC875,ERC1155
    4. 证券类通证ERC1400系列

    3)嘉宾:

    王登辉,创业股平台 CTO,尖晶投资技术赋能中心副总经理, HiBlock技术社群上海合伙人,电子科技大学硕士毕业, 10年华为/中兴 产品.研发经验,深耕区块链应用。

    4)活动定位
    区块链技术工坊系列活动,由HiBlock,兄弟区块链,,创业股平台联合主办,HPB芯链战略支持的,聚焦于深度分享区块链知识,实现小会技术交友。区块链技术工坊坚持4F原则
    Frency - 每周三晚上一次;
    Focus - 聚焦区块链技术分享;
    Fun - 20人以内会前做自我介绍,分享有深度的技术内容,技术交友;
    Feedback - 会后有活动实录和合影照片。

    2. 会议实录

    ERC代表“Etherum Request for Comment",这是Ethereum版的意见征求稿 (RFC),包括一些关于以太坊网络建设的技术指导。
    EIP表示以太坊优化协议(Ethereum Improvement Protocol),是一个进行代码修改并提交到平台加以接受的过程。
    改进方案中包括协议规范和合约标准。 一旦EIP被委员会批准并最终确定,它就成为ERC。

    1)如果开发人员对软件改动有了新的想法,这个想法应该以拉取请求(pull request)的形式呈现出来。在一个拉取请求中,改动能够在提案中轻易完成,同时积极听取社区的反馈。在这里,它属于EIP编辑的审查改动范围内。
    2)如果EIP编辑认为这个请求在技术上没有错误的地方,并且符合以太坊的社区价值观,他们会将其作为草稿合并到下一个阶段中。
    3)在合并之后,如Geth和Parity等以太坊各式各样的软件应用才会诞生,并且如果它们能真的运作起来,这个提案最终被看作是“已接受”。
    4) 一旦接受以后,整个平台就会根据这个EIP提供的用以运行以太坊软件的多样代码来进行升级。
    相应的EIP对应有4种状态:
    草稿(Draft) - 处于打开状态,便于考察讨论;
    接受(Accepted) - 即将被接受,例如将包含在下一个硬分叉中;
    定稿(Final)- 在上一个硬分叉中被接受,已定稿;
    延期(Deferred)- 不会马上被接受,但也许在将来的硬分叉版本会考虑。

    1. 同质化通证ERC20系列
    2. 非同质化通证ERC721系列
    3. 证券类通证ERC1410系列
      网址:https://github.com/ethereum/EIPs

    1)ERC20概要
    状态:
    定稿(Final)
    提交记录:
    https://github.com/ethereum/EIPs/issues/20
    标准说明:
    https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
    推荐样例:
    https://github.com/OpenZeppelin/openzeppelin-solidity/tree/master/contracts/token/ERC20

    2)ERC-20标准核心函数:

    • totalSupply():
      返回代币供给总量
    • balanceOf(address _owner):
      返回_owner的帐户余额
    • transfer(address _to,uint256 _value):
      并将数量为_value的代币转入地址_to并触发transfer事件
    • transferFrom(address _from,address _to,uint256_value):
      将地址_from中的_value数量的代币转入地址_to ,并触发transfer事件
    • approve(address _spender,uint256 _value):
      允许_spender提取限额_value的代币
    • allowance(address _owner,address _spender):
      返回_spender可从_owner提款的代币数量上限

    1)概要
    状态:
    草稿(Draft)
    提交记录:
    https://github.com/ethereum/EIPs/issues/223
    标准说明:
    https://github.com/Dexaran/ERC223-token-standard
    推荐样例:
    https://github.com/Dexaran/ERC223-token-standard/tree/Recommended

    2)ERC223核心函数

    • transfer(address _to, uint _value):
      会区分代币是发往外部账户地址还是发往智能合约地址。
    • transfer(address _to, uint _value, bytes _data):
      会区分代币是发往外部账户地址还是发往智能合约地址,还可以传送数据。
      2、如果_to(接收方合约)中没有实现tokenFallback函数,则事务必须失败,并且不会发生通证的传输。
      3、如果_to是外部拥有的地址,则必须发送事务,而不尝试在_to中执行tokenFallback。
      4、_data可以附加到这个通证(token)交易中,它将永远保持在块状(需要更多的gas)。 _data可以是空的。

    ERC721官方简要解释是Non-Fungible Tokens,简写为NFTs,多翻译为非同质代币。
    ERC721 是由谜恋猫CryptoKitties背后的公司Axiom Zen的技术总监Dieter Shirley 在2017年9月提出。
    目前谜恋猫已有20万ETH地址参与玩过。
    那怎么理解非同质代币呢?
    非同质代表独一无二,谜恋猫为例,每只猫都被赋予拥有基因,是独一无二的(一只猫就是一个NFTs),猫之间是不能置换的。这种独特性使得某些稀有猫具有收藏价值,也因此受到追捧。
    ERC20代币是可置换的,且可细分为N份(1 = 10 * 0.1), 而ERC721的Token最小的单位为1,无法再分割。
    如果同一个集合的两个物品具有不同的特征,这两个物品是非同质的,而同质是某个部分或数量可以被另一个同等部分或数量所代替。
    非同质性其实广泛存在于我们的生活中,如图书馆的每一本,宠物商店的每一只宠物,歌手所演唱的歌曲,花店里不同的花等等,因此ERC721合约必定有广泛的应用场景。通过这样一个标准,也可建立跨功能的NFTs管理和销售平台(就像有支持ERC20的交易所和钱包一样),使生态更加强大。

    (1)ERC721概要
    状态:
    定稿(Final)
    提交记录:
    https://github.com/ethereum/EIPs/issues/721
    标准说明:
    https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
    推荐样例:
    1)https://www.cryptokitties.co/
    2)https://github.com/OpenZeppelin/openzeppelin-solidity/tree/master/contracts/token/ERC721

    (2)ERC721函数接口

    • balanceOf(address _owner):
      返回由_owner 持有的NFTs的数量。
    • ownerOf(uint256 _tokenId):
      返回tokenId代币持有者的地址。
    • exists(uint256 _tokenId):
      tokenId代币是否存在,返回BOOL值;
    • approve(address _to, uint256 _tokenId):
      授予地址_to具有_tokenId的控制权,方法成功后需触发Approval 事件。
    • getApproved(uint256 _tokenId):
      获得_tokenId授权的地址;
    • setApprovalForAll(address _operator, bool _approved):
      授予地址_operator具有所有NFTs的控制权,成功后需触发ApprovalForAll事件。
    • isApprovedForAll(address _owner, address _operator):
      用来查询授权。
    • transferFrom(address _from, address _to, uint256 _tokenId)
      不建议使用本函数,建议使用safeTransferFrom函数。
    • safeTransferFrom(address _from, address _to, uint256 _tokenId):
      把_tokenId代币从_from账户安全转移到_to账户,安全是指如果目标地址为合约地址,则执行onERC721Received进行资产转移,否则的话交易会回滚;如果目标地址为外部账号地址,则正常转移。
    • ERC721Metadata(可选接口)
      ERC721Metadata接口用于提供合约的元数据:name , symbol 及 URI
      URI表示NFT所对应的资源,例如
      https://opensea-creatures-api.herokuapp.com/api/openseatest/3
      tokenURI(): 返回_tokenId所对应的外部资源文件的URI。
      外部资源文件需要包含名字、描述、图片, 输入URI可返回,其格式的要求如下页。
    • ERC721Metadata – 外部资源JSON

    如何创建自己的ERC721非同质化资产生物商店?

    如何装饰ERC721非同质化资产

    ERC875协议是由AlphaWallet团队提出的,他们希望基于ERC875协议族,能够实现人、事、物、权token化。
    另一种协议ERC721也能实现token的不可置换性,但其存在需要交易双方支付gas费用、无法简单实现原子化交易等一些不易于用户使用的问题。

    **首个落地应用:**体育票务 或许与张中南在票务业务的经历有关,AlphaWallet选择从ERC875和钱包切入的第一个use case就是俄罗斯世界杯门票。目前 AlphaWallet 已与盛开体育达成合作。今年的俄罗斯世界杯,二者联合引入区块链技术以测试新的票务解决方案,将盛开体育世界杯票库内的部分门票转化为以太坊上的ERC875的token。由于这些token具有不可置换性,用户通过AlphaWallet钱包的动态二维码,以及线下的现场扫描,即可获得世界杯门票。考虑到进一步安全的问题,AlphaWallet钱包显示的动态二维码,每隔10s就会变一次。

    ERC875概要
    状态:
    还处于pull request下(issue)
    提交记录:
    https://github.com/ethereum/EIPs/issues/875
    标准说明:
    推荐样例:
    https://github.com/alpha-wallet/ERC875-Example

    (2) ERC875核心函数

    • function transfer(address _to, uint256[] _tokens) public;
      通过包含通证索引的数组参数,把一组独一无二的通证转移给一个账户地址。相比ERC721一次只能转账一个通证,ERC875更显友好,它可以一次批量转账一组通证。这样既便利又能节约大量的GAS消耗。

    • function trade(uint256 expiryTimeStamp, uint256[] tokenIndices, uint8 v, bytes32 r, bytes32 s) public payable
      该函数允许用户出售一组非同质通证而不需要支付GAS费,只需要购买者支付。这是通过签署包含要销售的代币数量,合同地址,到期时间戳,价格和包含ERC规范名称和链ID的前缀的证明来实现的。然后,买方可以通过附加适当的以太币(ether)来满足交易,从而在一次交易中支付交易。 这种设计也更有效,因为它允许订单在离线前完成,而不是在智能合约中创建订单并更新订单。到期时间戳保护卖方免受使用旧订单的人的影响。 这为点对点(p2p)原子交换(atomic swap)打开了大门,但对于这个标准应该是可选的,因为有些可能没有用它。 需要在消息中添加一些保护,例如编码链ID,合同地址和ERC规范名称,以防止重放和欺骗人们签署允许交易的消息。

    恩金(Enjin)花了大半年的时间一直在完善ERC-1155这个通证协议,毫不夸张地说,该标准是现有以太坊上最适用于游戏资产的通证标准,将主流游戏中道具涉及到的一切操作经过高度抽象之后,基本通过ERC-1155进行了实现。
    “多重宇宙的道具”,也就是可以跨游戏使用的游戏资产,他可以是角色,可以是武器,也可以是各类物品。

    ?行业内最先支持ERC-1155标准
    ?可以创建不限数量支持游戏藏品的钱包
    ⏩对游戏藏品的显示速度进行了最大程度的优化
    ?游戏内道具的交易记录(发送/接收/铸造)
    ?浏览其他人钱包里游戏道具
    ?原生支持ERC-721&ERC-1155协议
    ?针对War of Crypto 提供ERC-1155的支持
    ?针对Gods Unchained 提供ERC-721的支持
    ?针对CryptoKitties 提供ERC-721的支持

    ERC1155概要
    状态:
    草稿(Draft)
    提交记录:
    https://github.com/ethereum/EIPs/issues/1155
    标准说明:
    https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1155.md
    推荐样例:
    https://enjincoin.io/
    (2)ERC1155核心函数

    • 1) mint(string _name, uint256 _totalSupply, string _uri, uint8 _decimals, string _symbol)
      增发同质化通证
    • 2)approve(address _spender, uint256 _id, uint256 _currentValue, uint256 _value)
      授权给_spender账户一定额度的编号为 _id的同质化通证,_currentValue为当前已授权额度;
    • 3)transferFrom(address _from, address _to, uint256 _id, uint256 _value)
      拥有者从 _from地址给 _to地址转账授权范围内的一定额度的一类同质化通证;
    • 4)balanceOf(uint256 _id, address _owner)
      拥有者_owner的 _id同质化通证的余额;
    • 5)allowance(uint256 _id, address _owner, address _spender)
      拥有者 _owner给消费者_spender在当前查询账户授权(approve)的额度;
    • 6)batchApprove(address _spender, uint256[] _ids, uint256[] _currentValues, uint256[] _values) 批量授权给_spender[]一组账户一定额度_values[]的编号为_ids[]的同质化通证,_currentValue[]为当前已授权额度,这几个数组的长度要严格对齐;
    • 7)batchTransferFrom(address _from, address _to, uint256[] _ids, uint256[] _values)
      拥有者从 _from地址给 _to地址转账授权范围内的一定额度_values[]的各类编号为_ids[]的各类同质化通证;
    • 8) -batchTransfer(address _to, uint256[] _ids, uint256[] _values)
      批量给目标账号_to转账各类编号为_ids[]的各类数额分别是_values[]的各类同质化通证;
    • 9)multicastTransfer(address[] _to, uint256[] _ids, uint256[] _values)
      当前账号批量给目标地址组合_to[]分别转移额度为_values[]的各类编号为_ids[]的同质化通证。


    1,合法合规性
    STO 最大优势就是主动接受监管,在有关部门的监督管理下合法合规运作。与信息不对称、权责不对称的 ICO 相比,监管机构将更容易对 STO 交易进行穿透式
    监管;再结合区块链公开透明、不可篡改等优点,监管机构更容易实施反洗钱、投资者准入、交易合约设计审核等等监管措施。STO 对投资者的保障更加完善,也有可能会降低监管的难度,增加了项目发展的稳定性和可预期性。
    2, 为有价值的项目提供快捷融资渠道, 扁平化PE/VC剪刀差空间。
    这意味着未来谁的资产/项目更具有财富效应,全球资本就会涌向哪里。未来跨境资本流动会更加剧烈,对于创富能力强的国家和组织,是大的利好。
    3, crypto的出现导致全球第一次从技术上出现了全球统一市场。
    过去,除非各国监管共同努力,才能导致金融市场互联互通,现在由于crypto市场的出现,除非监管拼命努力,才能导致这个全球互联互通的市场断开。

    标准制定了 Token 持有人的余额分离成多个分片(tranche)的能力。tranche 是一种以债务为基础的投资结构。这些证券将具有不同期限的,投资风险或高或低的 tranche 组合成一个整体,以达到降低投资者的风险,提供长期投资的目的。例如,你可能有一笔贷款转付证券,其中包括5到30年期的高风险和低风险的转付证券,基于 ERC1400 标准的 Token 将支持这种投资方式。


    (1)ERC1410概要
    状态:
    草稿(Draft)
    提交记录:
    1)ERC 1410: Partially Fungible Token Standard:
    https://github.com/ethereum/EIPs/issues/1410
    2)ERC 1400: Security Token Standard #1411
    https://github.com/ethereum/EIPs/issues/1411
    推荐样例:
    https://blog.neufund.org/good-protocols-how-to-properly-standardize-security-tokens-95ff83c81c4a

    (2)ERC1410核心函数

    • function sendByTranche(…)
      表示上述接口表示从调用者的指定tranche转指定金额到目的账户。
    • function operatorSendByTranche(…)
      ERC1410基于 ERC777继承了交易员(operator)的相关概念,允许某个交易员代表某个账户持有者基于tranche进行转账。
    • function authorizeOperatorByTranche
      消息发送者授权给某个交易员某个特定tranche的操作权。每次被调用,必须emit AuthorizedOperatorByTranche event。

    文章链接

    【以太坊通证标准】ERC20系列,ERC721系列,ERC1400系列 https://www.jianshu.com/p/fc4dbe1fbf2c
    第十九课 代币锁仓后逐步释放的ERC20智能合约实践 https://www.jianshu.com/p/db7cb9431ecc

    第十七课 【ERC721实践】迷恋猫从玩耍到开发 https://www.jianshu.com/p/684490db252c
    第三十三课 如何创建自己的ERC721非同质化资产生物商店? https://www.jianshu.com/p/57d58b1cd53a
    第三十四课 采用TRUFFLE框架如何创建自己的ERC721非同质化资产生物商店? https://www.jianshu.com/p/e1c7191b5f70
    第三十五课 如何配置Metadata以便装饰你的ERC721非同质化资产? https://www.jianshu.com/p/d5710a41a388

    第十八课 【ERC875】Hiblock黑客马拉松门票从定制到编码实现 https://www.jianshu.com/p/ddaa0d3643ce

    【ERC1155实践】ENJ铸造第一个有价值背书的游戏资产-WOC https://www.jianshu.com/p/2d67a0f0d199
    第二十课 【ERC1155实践】欧阳询书法复制品从确权设计到买卖测试 https://www.jianshu.com/p/159bb16001a7
    【ERC1155实践】区块链游戏的平行宇宙和为此而生的Enjin钱包 https://www.jianshu.com/p/d558acbc8f65

    【ERC1400标准】支持证券增发,交易,相关法律文件存储的证券类同质化通证 https://www.jianshu.com/p/1e300a73eeef
    第三十一课 ERC1410标准从分析到代码实现 https://www.jianshu.com/p/7588bcdda28c
    【区块链实践】STO技术标准(ST-20,SRC20,R-TOKEN,DS Protocol,ERC1400,ERC1410) https://www.jianshu.com/p/db0ccdeb81ad


    本次实录纪要由辉哥(王登辉,尖晶资本副总,HiBlock上海合伙人)整理记录,转发务必注明出处及本段信息。

    现场活动照片:

    坐席嘉宾介绍:嘉定蓝天经济城代表嘉宾,承诺区块链企业注册落地嘉定,享受2年免租,3年税收减半政策。这是对创业者的最大福利,本次享受VIP专席待遇。

    3. 下期活动宣传

    1)题目:
    【区块链技术工坊35期】区块链上的稳定币理论和技术实现

    2)议题:
    过去一年里,稳定币成为了区块链的最热门话题之一。USDT 的独占鳌头,去中心化稳定币 Dai 的一枝独秀以及各种引入监管稳定币的出现让稳定币的市场好不热闹。最近摩根大通银行推出的 JPM coin再次引爆了区块链行业。错综复杂的市场下,对于用户而言,要去了解每一种稳定币的模式、甄别优劣和选择合适的稳定币却不是一件简单的事情。甚至对很多资深的区块链从业者,理解稳定币也并不容易。

    “稳定币会是区块链的第三次落地应用吗?”“稳定币该怎么设计才能保持稳定?”“稳定币会取代法币吗?”“稳定币的商业模式和风险是什么?”“央行数字货币是何物”。请报名者带好笔记本电脑,且看MakerDAO 中国区负责人潘超的技术观点和从业经验的分享。

    议题纲要:

    1. 稳定币出现的背景和原因。
    2. 稳定币的已有模式和经济学原理。
    3. 稳定币的技术实现和难点
    4. 央行数字货币的原理与设计

    3)嘉宾:

    潘超, MakerDAO 的货币政策研究员,同时担任中国区的负责人和 Maker 基金会理事。潘超的主要研究领域包括货币银行理论、区块链上的稳定币实现和机器学习在经济学中的应用,著有《稳定货币:区块链的第三次落地应用》课程。

    4)时间/地点:
    2019-03-13(周三晚上) 18:30 / 上海徐汇区龙华中路596号A座

    5)活动报名海报
    请微信扫描二维码报名参与,有门禁密码私送,空降无法参加。

    展开全文
  • 以太坊的BloomIndexer具体实现了Chain_Indexer,可以认为是Chain_Indexer的派生类。 Chain_Indexer的初始化: func NewChainIndexer(chainDb, indexDb ethdb.Database, backend ChainIndexerBackend, section,...

    上一节分析reciept产生过程的时候提到:reciept会为日志数据生成一个Bloom过滤器,那Bloom过滤器是用来干嘛的呢?有什么用呢?

    一,Bloom过滤器的数据结构和reciept创建Bloom的过程
    type Bloom [BloomByteLength]byte
    BloomByteLength = 256
    Bloom 就是一个256个字节数组。一共2048位。

    我们看看怎么把庞大的收据日志数据放到bloom过滤器里面的。

    func CreateBloom(receipts Receipts) Bloom {
        bloomBin := new(big.Int)
        for _, receipt := range receipts {
            bloomBin.Or(bloomBin, LogsBloom(receipt.Logs))
        }
    
        return BytesToBloom(bloomBin.Bytes())
    }
    
    func LogsBloom(logs []*Log) *big.Int {
        bin := new(big.Int)
        for _, log := range logs {
            bin.Or(bin, bloom9(log.Address.Bytes()))
            for _, b := range log.Topics {
                bin.Or(bin, bloom9(b[:]))
            }
        }
    
        return bin
    }
    
    func bloom9(b []byte) *big.Int {
        b = crypto.Keccak256(b[:])
    
        r := new(big.Int)
    
        for i := 0; i < 6; i += 2 {
            t := big.NewInt(1)
            b := (uint(b[i+1]) + (uint(b[i]) << 8)) & 2047
            r.Or(r, t.Lsh(t, b))
        }
    
        return r
    }
    

    1,先看看bloom9(b []byte)算法函数。
    1.1, 首先将传入的数据,进行hash256的运算,得到一个32字节的hash
    1.2,然后取第0和第1字节的值合成一个2字节无符号的int,和2047做按位与运算,得到一个小于2048的值b,这个值就表示bloom里面第b位的值为1。同理取第2,3 和第4,5字节合成另外两个无符号int,增加在bloom里面的命中率。
    1.3,也就是说对于任何一个输入,如果它对应的三个下标的值不都为1,那么它肯定不在这个区块中。 当如如果对应的三位都为1,也不能说明一定在这个区块中。 这就是布隆过滤器的特性。
    1.4,这三个数取或,得到一个bigInt,代表这个传参数据的bloom9值。

    2,LogsBloom(logs []*Log)方法把日志数据转成对应的bloom9值,包括日志的合约地址以及每个日志Topic

    3,CreateBloom(receipts Receipts)方法创建收据的bloom
    3.1,创建一个空的bigInt bloomBin,遍历receipts,取得receipt里的日志,调用LogsBloom(receipt.Logs)将取得所有日志的bloom值按位或和到bloomBin。这意味着bloomBin包括了所有日志的bloom9数据。
    3.2,调用BytesToBloom(bloomBin.Bytes())方法,把bloomBin加入区块的bloom过滤器中,这时Bloom过滤器就有了本次交易的所有收据。
    3.3,需要说明的是Bloom过滤器只是提供一个查找数据是否存在的工具,它本身不包含任何数据。

    4, BloomLookup()方法查找对应的数据是否在bloom过滤器里面。

    func BloomLookup(bin Bloom, topic bytesBacked) bool {
        bloom := bin.Big()
        cmp := bloom9(topic.Bytes()[:])
    
        return bloom.And(bloom, cmp).Cmp(cmp) == 0
    }
    

    先将传入的数据转成bloom9值,传入的bloomBin 转成bigInt。根据按位与操作,判断传入的值是否在Bloom过滤器里面。

    二,Bloom过滤器的实际应用
    bloom过滤器是用来快速的查找log的,那以太坊是如何用bloom过滤器来查找的呢?
    想要要找某一条log,如果从区块链的头区块开始,根据区块头的hash依次开始查找的话是效率比较低的,每个区块写在本地数据库是散列存储的, 会增加很多io请求,io请求的速度很慢的。如何能快速的找到目的区块,这时候就要用到Chain_Indexer。以太坊的BloomIndexer具体实现了Chain_Indexer,可以认为是Chain_Indexer的派生类。
    Chain_Indexer的初始化:

    func NewChainIndexer(chainDb, indexDb ethdb.Database, backend ChainIndexerBackend, section, confirm uint64, throttling time.Duration, kind string) *ChainIndexer {
        c := &ChainIndexer{
            chainDb:     chainDb,
            indexDb:     indexDb,
            backend:     backend,
            update:      make(chan struct{}, 1),
            quit:        make(chan chan error),
            sectionSize: section,
            confirmsReq: confirm,
            throttling:  throttling,
            log:         log.New("type", kind),
        }
        // Initialize database dependent fields and start the updater
        c.loadValidSections()
        go c.updateLoop()
    
        return c
    }
    

    chainDb是整个区块链的Db
    indexDb是这个BloomIndexer的Db
    sectionSize等于4096,把每4096个区块划到一个section中
    loadValidSections,取得indexDb里面存放的section的数量
    c.updateLoop是chainIndexer 更新的主循环,有新的区块,或者有新的没有在indexDb里面存放的section产生都会send到c.updateLoop的goroutine里面去。

    func (c *ChainIndexer) updateLoop() {
        var (
            updating bool
            updated  time.Time
        )
    
        for {
            select {
            case errc := <-c.quit:
                // Chain indexer terminating, report no failure and abort
                errc <- nil
                return
    
            case <-c.update:
                // Section headers completed (or rolled back), update the index
                c.lock.Lock()
                if c.knownSections > c.storedSections {
                    // Periodically print an upgrade log message to the user
                    if time.Since(updated) > 8*time.Second {
                        if c.knownSections > c.storedSections+1 {
                            updating = true
                            c.log.Info("Upgrading chain index", "percentage", c.storedSections*100/c.knownSections)
                        }
                        updated = time.Now()
                    }
                    // Cache the current section count and head to allow unlocking the mutex
                    section := c.storedSections
                    var oldHead common.Hash
                    if section > 0 {
                        oldHead = c.SectionHead(section - 1)
                    }
                    // Process the newly defined section in the background
                    c.lock.Unlock()
                    newHead, err := c.processSection(section, oldHead)
                    if err != nil {
                        c.log.Error("Section processing failed", "error", err)
                    }
                    c.lock.Lock()
    
                    // If processing succeeded and no reorgs occcurred, mark the section completed
                    if err == nil && oldHead == c.SectionHead(section-1) {
                        c.setSectionHead(section, newHead)
                        c.setValidSections(section + 1)
                        if c.storedSections == c.knownSections && updating {
                            updating = false
                            c.log.Info("Finished upgrading chain index")
                        }
    
                        c.cascadedHead = c.storedSections*c.sectionSize - 1
                        for _, child := range c.children {
                            c.log.Trace("Cascading chain index update", "head", c.cascadedHead)
                            child.newHead(c.cascadedHead, false)
                        }
                    } else {
                        // If processing failed, don't retry until further notification
                        c.log.Debug("Chain index processing failed", "section", section, "err", err)
                        c.knownSections = c.storedSections
                    }
                }
                // If there are still further sections to process, reschedule
                if c.knownSections > c.storedSections {
                    time.AfterFunc(c.throttling, func() {
                        select {
                        case c.update <- struct{}{}:
                        default:
                        }
                    })
                }
                c.lock.Unlock()
            }
        }
    }
    

    1,c.updateLoop收到update的通知后,看是否有已知的未写入indexDb的section。
    2,调用c.processSection(section, oldHead)生成新的section

    func (c *ChainIndexer) processSection(section uint64, lastHead common.Hash) (common.Hash, error) {
        c.log.Trace("Processing new chain section", "section", section)
    
        // Reset and partial processing
    
        if err := c.backend.Reset(section, lastHead); err != nil {
            c.setValidSections(0)
            return common.Hash{}, err
        }
    
        for number := section * c.sectionSize; number < (section+1)*c.sectionSize; number++ {
            hash := GetCanonicalHash(c.chainDb, number)
            if hash == (common.Hash{}) {
                return common.Hash{}, fmt.Errorf("canonical block #%d unknown", number)
            }
            header := GetHeader(c.chainDb, hash, number)
            if header == nil {
                return common.Hash{}, fmt.Errorf("block #%d [%x…] not found", number, hash[:4])
            } else if header.ParentHash != lastHead {
                return common.Hash{}, fmt.Errorf("chain reorged during section processing")
            }
            c.backend.Process(header)
            lastHead = header.Hash()
        }
        if err := c.backend.Commit(); err != nil {
            c.log.Error("Section commit failed", "error", err)
            return common.Hash{}, err
        }
        return lastHead, nil
    }
    

    2.1,调用c.backend.Reset(section, lastHead)产生一个待组装的section,每个section中存在一个bloom过滤器。
    2.2,把number等于section * c.sectionSize到(section+1)*c.sectionSize的block依次加入到待组装的section中。并把这些block的header.bloom加入到section的bloom过滤器中。
    2.3,调用c.backend.Commit(),把新的section写入db。返回最近的那block的header。

    3,更新sectionHead和ValidSctions,如果还有新的没有在db里面的section的话,在throttling时间后在循环更新一次。

    三,外部调用接口查找log的流程
    PublicFilterAPI提供了给外部rpc调用的过滤查找接口。比如GetLogs()方法

    func (api *PublicFilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*types.Log, error) {
        // Convert the RPC block numbers into internal representations
        if crit.FromBlock == nil {
            crit.FromBlock = big.NewInt(rpc.LatestBlockNumber.Int64())
        }
        if crit.ToBlock == nil {
            crit.ToBlock = big.NewInt(rpc.LatestBlockNumber.Int64())
        }
        // Create and run the filter to get all the logs
        filter := New(api.backend, crit.FromBlock.Int64(), crit.ToBlock.Int64(), crit.Addresses, crit.Topics)
    
        logs, err := filter.Logs(ctx)
        if err != nil {
            return nil, err
        }
        return returnLogs(logs), err
    }
    

    1,FilterCriteria是外部请求的过滤条件,可以根据起始区块,日志的合约地址,日志topics的hash值来设置过滤条件。
    2,以太坊内部根据FilterCriteria,创建一个过滤器,把合约地址和topics的hash作为bloombit的匹配器的匹配条件。
    3,调用filter.Logs(ctx)来获取日志

    func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) {
        // Figure out the limits of the filter range
        header, _ := f.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber)
        if header == nil {
            return nil, nil
        }
        head := header.Number.Uint64()
    
        if f.begin == -1 {
            f.begin = int64(head)
        }
        end := uint64(f.end)
        if f.end == -1 {
            end = head
        }
        // Gather all indexed logs, and finish with non indexed ones
        var (
            logs []*types.Log
            err  error
        )
        size, sections := f.backend.BloomStatus()
        if indexed := sections * size; indexed > uint64(f.begin) {
            if indexed > end {
                logs, err = f.indexedLogs(ctx, end)
            } else {
                logs, err = f.indexedLogs(ctx, indexed-1)
            }
            if err != nil {
                return logs, err
            }
        }
        rest, err := f.unindexedLogs(ctx, end)
        logs = append(logs, rest...)
        return logs, err
    }
    

    3.1,如果没有设定起始位置,就认为从最新区块的header开始。找到开始位置区块对应的的section,如果开始位置在section里面就走f.indexedLogs()在chainIndexer里面找log,如果不是就调用f.unindexedLogs()不再chainIndexer里面找。
    3.2,f.unindexedLogs()相对简单。

    func (f *Filter) unindexedLogs(ctx context.Context, end uint64) ([]*types.Log, error) {
        var logs []*types.Log
    
        for ; f.begin <= int64(end); f.begin++ {
            header, err := f.backend.HeaderByNumber(ctx, rpc.BlockNumber(f.begin))
            if header == nil || err != nil {
                return logs, err
            }
            if bloomFilter(header.Bloom, f.addresses, f.topics) {
                found, err := f.checkMatches(ctx, header)
                if err != nil {
                    return logs, err
                }
                logs = append(logs, found...)
            }
        }
        return logs, nil
    }
    

    3.2.1,因为没有并入section的区块都是比较新的区块,数量也不多。直接从最新的区块开始遍历查找就可以了。
    3.2.2,bloomFilter(header.Bloom, f.addresses, f.topics)方法,根据合约地址和topics的bloom9值在header的bloom过滤器中按位与操作,看是否在这个区块中。
    3.2.3,如果找到这个block,调用checkMatches方法在block里面查找对应的log

    func (f *Filter) checkMatches(ctx context.Context, header *types.Header) (logs []*types.Log, err error) {
        // Get the logs of the block
        logsList, err := f.backend.GetLogs(ctx, header.Hash())
        if err != nil {
            return nil, err
        }
        var unfiltered []*types.Log
        for _, logs := range logsList {
            unfiltered = append(unfiltered, logs...)
        }
        logs = filterLogs(unfiltered, nil, nil, f.addresses, f.topics)
        if len(logs) > 0 {
            // We have matching logs, check if we need to resolve full logs via the light client
            if logs[0].TxHash == (common.Hash{}) {
                receipts, err := f.backend.GetReceipts(ctx, header.Hash())
                if err != nil {
                    return nil, err
                }
                unfiltered = unfiltered[:0]
                for _, receipt := range receipts {
                    unfiltered = append(unfiltered, receipt.Logs...)
                }
                logs = filterLogs(unfiltered, nil, nil, f.addresses, f.topics)
            }
            return logs, nil
        }
        return nil, nil
    }
    

    3.2.3.1 调用ethApi的f.backend.GetLogs(ctx, header.Hash())方法,找到这个区块的所有收据下的所有日志。
    3.2.3.2 调用filterLogs(unfiltered, nil, nil, f.addresses, f.topics),根据f.addresses, f.topics过滤出想要的logs。如果第一个log的hash是空的,需要通过light client重现获取一遍所有的日志,再走一下过滤。

    3.3,f.indexedLogs() 在chainIndexer里面查找日志

    func (f *Filter) indexedLogs(ctx context.Context, end uint64) ([]*types.Log, error) {
        // Create a matcher session and request servicing from the backend
        matches := make(chan uint64, 64)
    
        session, err := f.matcher.Start(ctx, uint64(f.begin), end, matches)
        if err != nil {
            return nil, err
        }
        defer session.Close()
    
        f.backend.ServiceFilter(ctx, session)
    
        // Iterate over the matches until exhausted or context closed
        var logs []*types.Log
    
        for {
            select {
            case number, ok := <-matches:
                // Abort if all matches have been fulfilled
                if !ok {
                    err := session.Error()
                    if err == nil {
                        f.begin = int64(end) + 1
                    }
                    return logs, err
                }
                f.begin = int64(number) + 1
    
                // Retrieve the suggested block and pull any truly matching logs
                header, err := f.backend.HeaderByNumber(ctx, rpc.BlockNumber(number))
                if header == nil || err != nil {
                    return logs, err
                }
                found, err := f.checkMatches(ctx, header)
                if err != nil {
                    return logs, err
                }
                logs = append(logs, found...)
    
            case <-ctx.Done():
                return logs, ctx.Err()
            }
        }
    }
    

    indexedLogs启动一个匹配器来查找Filter条件下对应的区块,这一节暂不分析f.matcher的工作原理。
    找到对应区块,接下来的事情就和unindexedLogs的处理一样了。

    总结:
    以太坊的bloom过滤器大大的提高了查询的效率。以太坊先创建topics的bloom,再创建logs的bloom,再创建收据的bloom,在创建header的bloom,最后创建block的bloom,一步一步构建上去。于此对应的,在查找日志的过程正好相反,先在block的bloom里面找,再在header的bloom里面找,再在收据的bloom里面找,直到找到最终的日志。

     

    展开全文
  • 以太坊·电影院场景区块链应用探索 最近一直在思考区块链在各种场景下的落地问题。 下面是电影院场景区块链应用探索,这是我的一个设想,区块链如何在院线场景落地的一些思路。 为此我写一个这样的智能合约,...
  • 以太坊的BloomIndexer具体实现了Chain_Indexer,可以认为是Chain_Indexer的派生类。 Chain_Indexer的初始化: func NewChainIndexer(chainDb, indexDb ethdb.Database, backend ChainIndexerBackend, section,...
  • 以太坊 以太坊是采用区块链 2.0 技术实现的产品,它的出现是为了解决比特币系统的不足。 比特币的不足 比特币的出区块时间是 10 分钟,换算出来仅仅支持全球单秒 7-8 比交易,影响交易速度。 比特币的挖矿是拼算力...
  • 以太坊框架梳理

    2021-01-07 18:54:29
    以太坊使用场景 支付系统:用于去中心数字货币交易,价值互换 去中心化应用:黄金和股票的数字化应用、金融衍生品应用、数字认证、追踪溯源、游戏等 以太坊特点 智能合约(smart contract):存储在区块链上的程序,...
  • 0、前传 比特币(《精通比特币》笔记) 区块链-以太坊技术详解与实战下载 V神(Vitalik Buterin),区块链名人—以太坊(Eth)创始人简介 ... 区块链应用场景 2、以太坊架构和组成 以太坊整体框架 ...
  • 走向 以太坊

    2020-03-05 15:54:54
    什么是以太坊 自2008年比特币出现以来,数字货币已经渐渐被接受。随着应用的扩展,人们发现比特币的设计只适合虚拟场景,由于存在着非图灵备性,缺少保护状态的账户概念,以及Pow挖矿机制所带来的资源浪费和效率问题...
  • 2.2 以太坊

    2018-10-02 20:41:56
    但是随着应用的扩展,人们发现比特币的设计只适合虚拟货币场景,由于存在着非图灵完备性、缺少保存状态的账户概念,以及PoW挖矿机制所带来的资 源浪费和效率问题,在很多区块链应用场景下并不适用。...
  • 近年随着区块链技术的迅速升温,其技术和应用场景受到了各界人士越来越多的关注,以太坊作为区块链2.0的代表,是第一个通用的区块链平台,自诞生之初便备受瞩目,很多项目受到了以太坊的启发,为了让国内开发者...
  • 以太坊加密猫代币协议剖析

    千人学习 2018-08-02 13:41:21
    以太坊加密猫代币协议剖析视频教程,让你了解以太坊这两种协议的基本应用场景,以及结合ERC20,ERC721 的双重代币模型实现。内容涵盖ERC20 和ERC721 整体介绍、基于ERC20标准在测试链上面发币、ERC721 协议标准的...
  • 杨镇老师2017年初开始翻译以太坊Homestead官方文档,对以太坊黄皮书(以太坊技术手册)中文版进行独立校订和增补更新,并且独立翻译了以太坊分片技术说明,他认为:“了解以太坊,最好的方式是学习官方技术文档,也...
  • 课程选型原因: 基于以太坊的智能合约开发可以解决各种各样的信任问题.有着非常广泛的应用场景,目前基于以太坊的创业公司众多, 市场招聘量巨大.
  • 以太坊 —— 挣脱数字货币的枷锁

    千次阅读 2019-05-17 18:29:28
    作为公有区块链平台,以太坊将比特币针对数字货币交易的功能进一步进行拓展,面向更为复杂和灵活的应用场景,支持了智能合约(Smart Contract)这一重要特性。 从此,区块链技术的应用场景,从单一基于 UTXO 的数字...
  • 无论在应用场景和应用数量上,2019年都取得了很好的进展。 然而,这一背景也给区块链开发平台带来了很大的挑战,如何才能既满足不同的应用场景,又能在交互性能和安全性方面有所提升呢? 以太坊也不例外,营长就...
  • 英文原文:https://arvanaghi.com/blog/pentesting-ethereum-dapps/一、前言所谓的以太坊(Ethereum)去中心化应用...在本文中,我们选择的目标为dApp最常见的某类应用场景:与一个或者多个智能合约(smart c...
  • 区块链之以太坊学习

    2019-03-30 22:14:06
    直到2015年,区块链这一概念才被单独提出来为更多人所了解,且向着更广泛的应用场景发展。发生在这个时间点的主要原因之一是以太坊的出现和日益成熟。 简单地说,以太坊是一个有智能合约(Smart Contract)功能的...
  • 以太坊区块链官方节点GETH安装

    千次阅读 2018-09-27 16:37:18
    GETH是官方使用go语言实现以太坊协议的客户端节点,通过GETH可以接入以太坊区块链的主网,通过以太坊主网,人们可以创建账号,交易以太币,发布智能合约,构建去中心化应用等应用场景。同时,区块链开发人员,可以...
  • 前言:加密货币市场,除了价值存储和流通之外,剩余的场景还有什么?Defi算一个,虽然还很稚嫩,但也有不错的开始。Defi是开放金融,它对传统金融市场的竞争才刚刚开始。在未...
  • 直到2015年,区块链这一概念才被单独提出来为更多人所了解,且向着更广泛的应用场景发展。发生在这个时间点的主要原因之一是以太坊的出现和日益成熟。 简单地说,以太坊是一个有智能合约(Smart Contr...
  • 一、概述如果到开发dapp与以太坊交互有很多方法,这里使用web3与geth交互,web3是以太坊官方提供的一个js的客户端交互工具。可以在nodejs项目引用,同样也可以在html中引入web3.js进行交互,但这种方法安全性较差不...
  • 以太坊白皮书.pdf

    2020-04-16 12:21:12
    前景广阔或具有潜在应用价值的应用场景,并对区块链的应用价值进行了 展望。 三、提出我国区块链技术发展路线图的建议。分析提出了由7个主 要技术特征构成的区块链通用技术需求,结合国内外发展现状和应用场 景,...
  • 以太坊将比特币针对数字交易的功能进一步进行了拓展,面向更为复杂和灵活的应用场景,支持了智能合约这一重要特性。 以太坊项目简介 以太坊:项目最初的目标是打造以个智能合约的平台,该平台支持图灵完备的应用,...
  • 主要介绍了利用对call调用处理不当,配合一定的应用场景的一种攻击手段。 0x00 基础知识 以太坊中跨合约调用是指的合约调用另外一个合约方法的方式。为了好理解整个调用的过程,我们可以简单将调用发起方合约当做...
  • 但是随着应用的扩展,人们发现比特币的设计只适合虚拟货币场景,由于存在着非图灵完备性、缺少保存状态的账户概念,以及PoW挖矿机制所带来的资源浪费和效率问题,在很多区块链应用场景下并不适用。人们需要...

空空如也

空空如也

1 2 3 4 5 ... 12
收藏数 227
精华内容 90
关键字:

以太坊应用场景