首页 快讯 Ethereum Nowa(ETN)和ETCV硬分叉被质疑是骗局

Ethereum Nowa(ETN)和ETCV硬分叉被质疑是骗局

来源: ethereumworldnews
2019/01/12 19:43
原定于1月11日进行的ETCV硬分叉和原定于1月12日进行的ETN硬分支被BitcoinTalk论坛质疑是骗局,后者称,项目网站有可疑之处,它要求想要空投的用户将一些ETH发送到一个特定的地址,然后将他们的私钥导出到一个新的ETN钱包中道,再用私钥清空那些想要参与空投的人的钱包。当用户在Etherscan上查找ETN项目提供的地址时,会收到一条消息,警告用户不要向该地址发送任何内容。

扫一扫,关注区块链在线

区块链数字货币新闻、区块链项目信息、区块链技术分享就在 区块链在线

热门话题 更多
  • 区块链治理简介

    任何组织中的治理都是至关重要的。毕竟,决策的方式,也就是事情如何完成的过程。在发达社会,治理指的是民主进程。在现代跨国公司中,它关系到组织中人员的决策权。 然而,这两个示例都是集中的治理模型。在现代民主国家,民选政府做出的决定会影响大多数人。类似地,在一家公有公司,董事会任命运营公司的高管。 区块链治理带来了不同的机遇,因为区块链是分散式生态系统,没有中央决策权。虽然很容易从共识协议的角度来考虑区块链治理,但是还有更基本的需要考虑。 在aelf中,我们相信区块链的技术特征构成了下一代区块链的支柱,但我们也相信治理和经济模式构成了生态系统的灵魂,没有它,你将只是一台没有生命的机器。本系列将介绍什么是治理、需要考虑的重要概念、常见的挑战,最后介绍aelf如何处理这些问题。 区块链治理是什么意思? 区块链是一个分布式系统,其计算机网络运行完全相同的区块链软件。因此,本文中的区块链治理指的是用于决定网络将使用哪个软件或哪个软件版本的协议。 谁负责区块链治理? 在区块链中,通常有四个中心社区参与治理。它们是: •核心开发人员 •节点操作员 •代币有者 •区块链团队或组织 让我们分解治理过程中每个组的角色。 核心开发人员 核心开发人员负责维护支撑区块链软件本身的代码。通常有一个中央代码库,核心开发团队负责添加或删除修改软件的代码。 虽然核心开发团队可以对底层代码进行更改,但他们无法将其付诸实施,因为他们无法控制网络本身。实现更改是运行软件节点操作人员的责任。 节点操作员 就我们的目的而言,节点操作员是操作计算机的人员,该计算机运行完整版本的区块链软件并维护完整的分类账副本。 节点操作员通常不编写代码——它们依赖于核心开发人员。但是节点操作员可以决定是否在其节点上实现代码更改。因此,要使区块链治理顺利运行,核心开发人员必须实现节点操作人员同意运行的代码更改。 它相当于立法机构和司法机构的作用。立法者可以提出一项新的立法,但由司法官员决定是否实施该立法。 区块链组织 区块链组织可以是非营利性的基金会或公司。例如,比特币和以太坊,Aelf和Ripple、Dash等。 组织的中心角色是指导项目,包括项目的开发和资助。它可以帮助影响项目的方向,但是它不负责执行决策。 例如,组织通常会决定如何补偿开发人员。它还将在项目的营销以及代表更广泛的投资者和支持者群体方面发挥作用。 后者不应被低估。如果开发人员和节点运营商做出代币持有者不喜欢的决定,可能会出现大规模抛售,从而严重影响项目的整体价值。 代币持有者的离去将减少用于补偿核心开发人员的可用资金,如果代币价值下降,节点运营商的努力也将获得更低的回报。因此,让大多数代币持有者满意符合核心开发人员、节点操作员和区块链组织的利益。 分叉 当软件有更新时,它被称为分叉。如果软件更新使以前的软件版本与新的更新不兼容,则称为硬分支。硬分支通常是重大的更改,因此在区块链社区中可能存在争议。 由于比特币社区的硬分支,数种加密货币应运而生。例如,在2017年,关于增加比特币区块规模的提议就存在分歧。社区无法达成一致,所以一组继续增加,而另一组继续运行旧版本的软件。这一变化导致了比特币现金的出现。 可伸缩性的挑战 分叉是大规模管理分散式治理挑战的必然结果。最大的区块链项目拥有最大的社区,人口越多,在所有成员之间达成共识就越困难。这就解释了为什么到目前为止比特币出现了许多硬分叉。 举个小例子,当你邀请14个朋友就比只邀请4个朋友时,选择一家餐馆的难度要大。 区块链社区还参与了一些关于链上治理价值的热烈讨论。原则上,可以将更改编程到区块链本身并由成员投票通过,然后在代码本身中自动实现。 然而,这种方法存在着重大的挑战。首先,所有的成员都必须为整个团体的利益而行动,这在一个大的、不同的社区中是没有保证的。其次,区块链是不可变的。一旦投票通过,改变就无法逆转。 更多的可伸缩性: 1)侧链和可伸缩性 2)一个真正可伸缩的区块链 结论 与任何民主治理体系一样,没有管理区块链治理的正确方法——只有或多或少民主化的方法。到目前为止,还没有一种方法是放之四海而皆准的,只有很多有益的争论。 鉴于区块链技术还相对年轻,理性的进行辩论无疑是一件好事。对于区块链开发人员、节点运营商、组织和项目的投资者来说,每个参与者自然会被他们认为是根据自己的个人价值和偏好运行的项目所吸引。 这篇文章描述了在区块链生态系统中各方的角色,以及他们如何一起工作来管理项目。我们还谈到了治理中涉及的一些挑战。在第2部分中,我们将概述链上和链外治理之间的区别,以及aelf如何使用它们。此外,我们还详细讨论了PoW、PoS和DPoS之间的区别。 更多数字货币信息:www.qukuaiwang.com.cn/news
    2019-01-18 19:43 1752
  • 西班牙车厂SEAT加入Alastria联盟开发区块链供应链管理

    据报导,西班牙最大的汽车制造商SEAT已加入Alastria生态系统,致力于开发基于区块链技术的供应链管理,同时针对该公司位在Martorell工厂制造的汽车零组件进行追踪。 SEAT成立于1950年,是一家国有工业公司,也是西班牙最大的汽车制造商。据报导,2017年SEAT的营业额达到创纪录的95.52亿欧元(108.78亿美元),较去年同期成长11.1%。 近日SEAT宣布已加入Alastria生态系统,Alastria联盟由70多家公司和机构组成,其中包括BBVA银行和桑坦德银行、电信提供商Telefónica、能源公司Repsol和专业服务公司埃森哲等。该联盟的主要目标在于促进区块链技术的进步和发展。 作为合作的一部分,SEAT计划针对区块链技术在降低成本方面的优势进行试验,旨在改进并优化现有作业流程并促进供应链管理。 报导,SEAT总裁Luca de Meo表示,该公司「确信区块链技术在未来将息息相关。」 与此同时,SEAT和Telefónica已经开始联合开发区块链产品的概念性验证(POC),以追踪SEAT位于西班牙Martorell的工厂供应链中的汽车零组件。 去年9月份,德国汽车制造商保时捷宣布,将在未来五年内增加对新创公司的投资,并酌着重于区块链和人工智慧(AI)的技术,投资金额约为1.76亿美元。这项投资的目标针对的是「早期和成长」阶段的业务,涉及「客户体验、移动性和数位生活方式」,以及未来的技术,包括区块链、人工智能、虚拟扩增强实境。 更多数字货币信息:www.qukuaiwang.com.cn/news
    2019-01-18 19:37 1756
  • 君士坦丁堡对以太坊来说意味着什么

    据以太坊博客称,君士坦丁堡是以太坊区块链的重要“网络升级”,明天将开始生效。在发现一个严重的技术漏洞之后,升级被推迟了,但是如果君士坦丁堡被部署,它对于该领域最重要的区块链之一来说究竟意味着什么,它将如何影响基于以太坊的应用、智能合约和加密货币 什么是君士坦丁堡? 在以太坊的发文中,“网络升级”一词可能有些误导(尽管以太坊开发人员正式使用这个术语来指代君士坦丁堡)。它与传统意义上的网络或网络连接无关;相反,它指的是改变控制以太坊区块链工作方式的底层协议。 这次升级计划于2019年1月16日生效(已推迟至18日),但具体时间取决于以太坊网络的运作,没法准确地预测。 一旦升级到君士坦丁堡后,任何不同意升级的节点都将被排除在网络之外,这将有效地实现区块链的分支。但是,在这一点上,不太可能发生大量节点会不同意升级君士坦丁堡的情况。 君士坦丁堡升级变化 君士坦丁堡包含五个具体的变化,详见以太坊博客。所有这些调整都是“以太坊改进建议”(EIP),是社区成员为改进以太坊协议而提交的想法和方案。 在君士坦丁堡中将实施的5个EIP中,有4个涉及对以太坊区块链上数据管理或访问方式的更新。这些更新的细微差别可能只对那些使用以太坊开发DApps或智能合约的人有影响。 大变革:EIP 1234 然而,第五个更新对整个以太坊社区来说是最重要的。这个更新被称为EIP 1234,它会减少矿工在以太坊区块链上挖矿所能获得的加密货币数量。同时它还推迟了以太坊转向股权证明(PoS)共识模型的实施。随着网络变得越来越大,更改为PoS将有助于保持以太坊的高效性。 EIP 1234的主要目标是保持以太坊区块链的稳定性并安全过渡到PoS阶段。在以太坊社区中已经有很多关于切换到PoS的讨论,但是实现进展会比一些人预想的要慢。通过减少以太坊上的挖矿奖励,EIP 1234本质上是作为一条生命线,保持以太坊的平稳运行,直至切换到PoS模式。 EIP 1234的设计是假设从现在开始大约一年后转向PoS。 EIP 1234的赢家和输家 对于以太坊社区的成员来说,EIP 1234是一件好事。它有助于在PoS实现之前,确保网络的健康运行。通过这种方式,EIP 1234将有助于避免一些可扩展性问题和其他技术问题,这些问题是比特币区块链在几年前发展过程中遇到过的。 另一方面,至少在短期内,以太坊矿工将因EIP 1234而遭受损失。通过减少挖矿奖励,这一变化使得矿工手中的利润减少。这意味着一旦君士坦丁堡生效,以太坊区块链的挖矿活动可能会减少。 然而,似乎可以肯定的是,君士坦丁堡将通过添加技术特性使以太坊区块链和协议变得更好用,从而允许开发人员构建更好、更安全的DApp和智能合约。反过来,君士坦丁堡很可能会提高ETH的价值,这又将带来增加挖矿的动机。 君士坦丁堡的影响 在这之中,矿工们比较关注君士坦丁堡对他们的影响,以及以太坊创始人Vitalik Buterin在讨论中所起的角色作用变小,甚至一些人担心早期君士坦丁堡会破坏以太坊的稳定,或者由于大量节点选择不遵循新的协议而导致一次巨大的“硬分叉”。 然而,在升级调整前夕,这些担忧似乎不再重要。由于君士坦丁堡的存在,以太坊矿工们可能不会遭受任何长期的重大伤害,而且目前没有证据表明多数节点会拒绝这些调整。这些更新将从技术角度改进以太坊,最终为所有ETH持有者创造更多价值。 更多数字货币信息:www.qukuaiwang.com.cn/news
    2019-01-18 19:31 2075
  • 阿瓦隆小学 | 树莓派网络及IP设置

    矿工朋友在矿机启动时,可能会遇到无法正常登陆网页、无法连接树莓派的情况,本期阿瓦隆小学,小编将详细讲解正确访问树莓派IP的办法。 树莓派默认IP为192.168.0.100,即0网段,可能和我们自己电脑IP网段会有不同,如遇电脑网段为0以外的IP,在未经过设置的情况下,会导致树莓派后台无法进入。 针对如上所述,有以下三种设置更改IP的参考方式:   第一种设置:更改路由器IP 路由器设置 以现有网段为192.168.1.1,树莓派网段192.168.0.*为例: 1.需更改路由器的网络,先登陆路由器设置; 192.168.1.1就是路由器的登陆地址; 2.我们点击网络参数-LAN口设置; 在右边界面,一般我们只要把网关地址更改即可;如下设置: 2.1.将LAN口设置中IP地址改成网段0.1,然后点击保存; 2.2.点击确认重启,重启后重新连接; 3.然后在电脑游览器中,网址栏输入树莓派默认IP:192.168.0.100,就可以直接访问树莓派运行后台,更改信息。   第二种:设置访问IP 第一步:查询电脑IP 1.点击右键开始菜单,点击运行; 2.然后搜索cmd(输入cmd按回车); 3.出现一个黑框窗口,这个窗口俗称DOS窗口,窗口闪烁的‘_ '处输入ipconfig /all(注意ipconfig空格/all,这个命令复制ipconfig /all也可以),并按键盘回车键; 4.这时会出现一大串数据,往上拉找IPv4地址和DNS等; 第二步:找出设置IP界面 5.右键点击桌面右下角的小电脑,打开“网络和Internet”设置; 6.点击网络和共享中心; 7.点击以太网; 8.点击属性; 9.点击Internet协议版本4; 10.点击“使用下面的IP地址”进行更改; 第三步:IP设置  11.按照DOS程序窗口的IPV4地址数据,对应填入,如下所示: 12.填写后,点击高级; 13.在高级界面——IP地址——添加一个0段的访问IP,添加的IP后缀不能为100(即不可与已使用IP冲突,原理举例:树莓派默认IP后缀为0.100,如有冲突,则无法正常访问树莓派IP),子网掩码直接按电脑默认即可; 14.添加后,点击确定; 15. IP设置确定后,即可在电脑游览器中,网址栏输入树莓派默认IP:192.168.0.100,就可以直接访问树莓派运行后台,更改信息。 第三种:树莓派直接和电脑连接 第一步:树莓派通电并连接电脑 第二步:找出设置IP界面 1.右键点击桌面右下角的小电脑,打开“网络和Internet”设置; 2、点击网络和共享中心; 3.点击以太网; 4.点击属性; 5.双击点击Internet协议版本4; 6、点击“使用下面的IP地址”进行更改; 第三步:IP设置 7.然后将IP地址改成192.168.0.X(X不能为100),这里DNS不用填写,完成后点击确定;  8.IP设置确定后,即可在电脑游览器中,网址栏输入树莓派默认IP:192.168.0.100,就可以直接访问树莓派运行后台,更改信息。 以上就是正确访问树莓派IP的三种方法,如果您在实操过程中还有疑问,可以拨打阿瓦隆官方售后0571——85163777联系售后客服人员为您远程解析哦。 更多数字货币信息:www.qukuaiwang.com.cn/news
    2019-01-18 19:28 1891
  • Fountain基于贡献证明的区块链内容生态系统长啥样?

    寒夜,你泡好茶,准备加班,突然想起自己的简书账号已经两个月没更新了。于是,你登录简书,惊喜地发现,曾经凭兴趣撰写的原创文章获得了可流通的通证(Token)。 这并非编造的故事,而是已经近在咫尺的未来场景。我们已经习惯了大平台利用自己的流量优势攫取本应属于我们的版权和数据收益,却不知道,一切属于我们贡献的收益都应归还我们,而这,就是Fountain一个基于贡献证明的区块链内容生态系统正在做的事情。 PoC机制,按贡献分配始于一个好制度 如果给你一份清单,想必你会大吃一惊,你为微博、知乎等内容平台提供优质的原创作品,花费时间和精力阅读、点赞、转发文章,与文章作者互动、发表评论等,做了各种带来流量的贡献。这些贡献背后,都转化成了平台的广告收益,而你,一无所获。 幸而,Fountain团队设计了一套公开透明的贡献证明规则可以解决上面的问题,我们称之为 PoC (Proof of Contribution )。 这个PoC机制究竟怎么运转的呢? 简单来说,就是给每个贡献了蜂蜜的蜜蜂记账,无论贡献大小,一律笔笔上账,且根据贡献分配收益、权益等。 PoC机制使用FTN进行奖励,而FTN正是Fountain基于内容生态系统发行的一种通证(token)。 在Fountain上,用户有效的贡献方式分为内容贡献和运营贡献两种。 内容是 Fountain 中最重要的价值,内容的作者理应得到奖励。用户给内容的投票即是对内容的策展,也是给内容增值的过程,所以投票者也应当获得奖励。内容贡献的奖励主要围绕作者的创作 ( Creation ) 贡献和读者的策展 ( Curation ) 贡献来设计。每年增发 FTN 中的55%将用来作为这部分的奖励池。 在内容贡献中,投票权重、内容热度值和内容奖励分配都有精确的计算方法,且一环扣一环,投票会产生内容热度值,内容热度值又会进入内容奖励分配的计算中。 而在运营贡献上,Fountain将内容社区应用运营工作中有基础价值的且有群众基础的社区治理贡献和介绍推广贡献,列入奖励范围。每年增发 FTN 中的15%将用来作为这部分的奖励池。 值得一提的是,社区治理奖励作为运营贡献的一环,由社区成员围绕违规内容和违规用户行为进行自治管理,通过质押FP、判定、收益、解押等方式实现一整套治理奖励机制。介绍人奖励是运营贡献的另一方面,对介绍人既有奖励,又通过准备金制度防止刷量和僵死用户的出现。 为应对针对奖励池的女巫攻击,Fountain设置了较高的注册认证门槛以及准备金制度,在总财富值相同情况下,注册账号越多,占用准备金越多,使得可用财富值越小,有效防止恶意攻击。 不得不说,Fountain的PoC机制充分考虑了激励与惩戒的规则、界限,让真正有贡献的社区成员获益,让投机取巧者无缝可钻。 FTN通证,让所有用户行为都变得更有价值 当BTC从最高点的20000跌落到3000多的时候,疯狂之后,大家突然意识到,原来其总量恒定能抗通胀,与防止投机让市场更公平,是一对无法调和的矛盾。 不巧,Fountain在设计之初,便想到这一层,在发行期通证FTN时,采用了初始总量定量和每年增发量相同但随基数增加增发比例下降的可增发模式。 FTN 初始总量为30亿。其中15亿个将作为基金会预留金,用于初期社群共识建设、合作方测试、核心团队的长期激励、日常经营和投资等用途。同时预留金也将用于抑制有可能被大投资人所操纵的短期炒币投机行为。其中5亿个将赠与简书,以感谢简书对Fountain 的支持。剩余10亿个将用于社区支持计划,所得资金将用于 Fountain 的开发、运营和市场。 与此同时,Fountain注意到,内容社区有其独有特点——用户不断创造新的有价值的内容分享给全体用户,在此过程中,整个社区中的价值是在不断增长的,所以,Fountain认为,完全通缩或者总量恒定的 Token 经济体系并不适用于这个快速增长、鼓励内容生产和消费的社区。 因此,Fountain将每日增发100万个 FTN 用以生态激励,首年增发率约为12%,随后逐年降低,趋近于0。 据悉,Fountain每年增发的 FTN 中的85%将基于 PoC ( Proof of Contribution ) 的共识机制用于社区奖励,10%将基于 DPoS 的共识机制用于奖励区块生产,剩余5%转为基金会预留金以保障基金会的可持续发展。 为减少投机行为,Fountain设计了 FP ( Fountain Power ),用户随时可以将 FTN 以1:1的比例兑换成FP。但当用户选择将 FP 兑换成 FTN 时,FTN 总额即被分成等额的13份,每周兑换1份,13周兑换完成。FP 无法流通,必须兑换为 FTN 后才可以流通。所有 FTN 的奖励,将可能全部以 FP 的形式给予用户。 简书钻,为实现简书与Fountain彻底互通打前站 “感谢 Steem,一位先行者。”Fountain的一份白皮书里这样写道。的确,Steem开辟了一条社交媒体社区的大道,而Fountain希望沿着这条道路走得更远、探索得更深入。 很快,Fountain找到了首个战略合作伙伴——简书,一家老牌的中文创作社区,Fountain生态内的第一个Dapp将与简书整合。 为什么是简书?你一定会问。 我们不妨看一组对比数据: 不难发现,简书不仅与Steemit有很高的相似度,同时还有很好的拓展性和坚实的用户基础,在累计注册用户、日均活跃用户以及主站Alexa全球排名上更胜一筹。 当然,相似并不表示一定能成功。那么,简书在Fountain项目的落地应用中表现如何呢? 在《简书与Fountain项目合作公告》里,我们找到了双方合作的进展: · Fountain生态内的第一个Dapp将与简书整合,简书的用户群体与内容最终将与Fountain彻底互通。 · 简书推出“简书钻”(暂定名)的全新虚拟道具。 · 简书平台将在Fountain协议正式上线前,使用简书钻进行PoC机制的模拟和试运营,用于用户激励的“简书钻”将基于共识规则逐步发放给简书用户(方案评估中)。 · 持有简书钻的用户,将拥有与Fountain网络中FP持有者同样的社区权益。 · 此外,简书将与Fountain紧密合作,互相输出资源,早日完成链端+Dapp端的产品设计与整合。 可以说,简书钻,成为实现简书与Fountain彻底互通的桥头堡,也是两者整合最为重要的一步。 如今,简书体系内简书钻总量为45991607,截止目前,持有简书钻用户数达到1466W,而在简书钻的持有人数和分布上也十分合理,拥有100000钻以上用户占有的简书钻占到总体的比例仅为11.7%,持钻总数为5389906.977;拥有100钻以上用户占有的简书钻占到总体的比例则达到55.23%,持钻总数为25403820.787。 总体来看,持钻占比分布较为均匀,没有出现多数钻集中在少数用户手中的情况,100钻到1000钻、1000钻到10000钻、10000钻到100000钻、100000钻以上四个等次用户持钻总数占总体比例分别为19.54%、10.37%、13.6%和11.7%,每个档次间所占比例均在合理区间内。 在PoC机制下,简书钻每天参与用户数达40000人;参与用户持钻数占到生态内总体钻(900W )的比例为25%;简书钻上线后,生态内点赞及评论数量均有大幅上升。 有了Fountain的加持,简书在区块链领域的探索会逐步迈入正轨,成为内容创作社区一颗冉冉升起的新星。
    2019-01-18 19:10 1986
  • 吾有上将可治扩容——浅谈区块链分片技术

    对区块链比较熟悉的朋友们可能都知道,公链的吞吐量一直是个让人诟病的问题,比如比特币和以太坊的吞吐量每秒只有个位数,如果想要在以太坊上面搭载一个吞吐量需求较大的DApp,那么这条公链就需要具备可扩展性。 但是区块链扩容这种事情,说起来容易做起来难,有什么解决方案可以实现呢?这就不得不说一说我们今天的主角——上将“分片技术”! 啥?有看官可能会说,之前不是已经写过一篇《区块链小知识 | 闪电网络》来介绍如何解决区块链交易慢的问题了吗?那这个分片技术有什么不同呢?别急,七维矩阵(ID:dongzi716)专业讲解会让你明白的,往下看。 吞吐量 在说分片技术之前,我们需要通过了解“吞吐量”的概念,来帮助我们进一步了解区块链的分片技术。 吞吐量这个概念很好理解,它基本上相当于人们正常吃饭、排泄一样:当你在访问某个网站点开这个链接的时候,就相当于人吃下去食物了;当服务器接收到你的链接请求后,会给你反馈相应的数据使该网页呈现在你的面前,就相当于这个人吃进去的东西消化完毕且把废物排泄出来了,这整个过程就是一个吞吐。 一个人自从吃进去事物到排泄出去所需要的时间就可以看成区块链网络进行一个吞吐所需要的时间,单位时间内吞吐的次数,就用吞吐量来形容。 为什么需要分片技术? 我们在了解了吞吐量之后,就可以回头看看现有的扩容问题。 我们常说区块链是一个分布式账本,是因为区块链网络是由一个个节点链接起来的,然后要求每一个完全参与的节点都必须要验证每一笔交易,而且这些节点还必须跟全网的所有其他节点保持一致。 虽然这样的机制可以最大限度的保证全网的安全,在容错性、安全性、政治中心和真实性上面有很大的优势,但是这种方式是以降低可扩展性为代价的。 当公链变得越来越大时,它就需要越来越多的处理能力来验证这些公共交易,进而可能造成交易瓶颈。众所周知,当前阶段公链的吞吐量实在是小的可怜,平均每秒只能处理7-15笔交易,所以,这在极大程度上阻碍了那些对吞吐量有较高要的应用在链上的发展(即使聊天、实时支付等)。 发现问题总是好的,但如何解决问题却又成为了一个新的问题。关于这个新问题,业界提供的解决方案主要分为链上和链下两种。 链下的解决方案就是利用闪电网络将大量交易放到链外进行,只把关键环节放到链上确认(缺点很明显就是没有区块链的保护不是很安全)。 鉴于前者的情况,我们就需要一种与其互补的、链上的解决方案,也就是今天所讲的:分片技术(还有侧链、DAG等,此处暂且不表)。 什么是分片技术? 分片(Sharding)是一种基于数据库分成若干片段的传统概念扩容技术,它将数据库分割成多个碎片并将这些碎片放置在不同的服务器上,在底层公链的系统内,网络上的交易将被分成不同的碎片,其由网络上的不同节点组成。 因此,只需要处理一小部分输入的交易,并且通过与网络上的其他节点并行处理就能完成大量的验证工作。将网络分割为碎片会使得更多的交易同时被处理和验证,我们将这种技术称之为“分片技术”(或水平扩容),可以简单地理解为“分而治之”。 其实分片技术不止一种,为了满足不同的需求,分片技术还分为:网络分片、交易分片和状态分片等。(七维君说好是浅谈,那就一定是浅谈,因为程度太深的话非专业人士真的很难理解清楚。)举个例子方便理解: 现有的区块链网络就像一条繁忙的高速公路,这条高速公路的收费站暂时只有一个收费出口,在这样的布局下,车辆稍微增加,交通很容易堵塞。比如当时基于以太坊发布的加密猫游戏,游戏玩家暴增,导致以太坊网络拥堵。 若是想减少高速拥堵的情况,就需要在高速公路上增加N个收费口,这才能极大地提高汽车通过收费站的速度。因此,分片技术可以为区块链网络带来巨大的改善,并显著提高区块链的交易速度。 可以想象,当我们将低费用与高交易处理能力结合起来的时候,必然会使公共链变得越来越有吸引力。这些积极的趋势所持续的时间越长,我们就越能看到更多的主流的加密技术和区块链应用程序的出现,最终呈现一个百花齐放的状态。 分片技术带来的好处 基于分片技术的区块链的实现底层公链有很多好处: 1.区块链上处理交易的速度变成了每秒上千笔甚至更多,这可以改变人们对加m货b作为支付方式效率的看法。 2.改善交易吞吐量将会给去中心化的系统带来使越来越多的用户和应用程序,而这反过来可以促进区块链技术的进一步发展与采用,也使挖矿变得更有$可图,同时也能吸引更多不同人士加入到公共网络上的节点,从而形成一个良性循环。 3.分片技术因为验证单笔交易的处理量减少了,可以帮助降低交易费用,节点盈利的同时减少收取的费用,在现实的区块链世界中,将降低节点费用与提高交易处理能力结合,使底层公有链更具吸引力与竞争力。 分片技术独特在于其他解决扩容的链上技术的关键特性,就是它可以进行水平扩容,也就是说,网络的吞吐量随着挖矿网络的扩展而增加,这种特殊的特性可能使它成为推动区块链技术被快速采用的理想技术。 简单来说,分片技术的本质是通过改变网络内部各步骤之间的验证方式来增加吞吐量,各步骤之间验证范式可以采用链上验证,也可以采用链下验证的方式,没有统一,这就足以为现有公链带来诸多好处。 总结 分片技术信息量巨大,它无疑是区块链中解决扩容问题的一个绝佳方案,同时分片技术还可以保证了去中心化和透明度的情况。但是分片技术,在设计和实现层面都是困难重重的,挑战还有很多,目前一切还只是个开始(七维君不讲难点,讲了普通人也解决不了,还是留给技术大佬们解决吧)。 七维君想说的是,在我们普通人还没有领会到这些技术时,最需要的是提高深度的逻辑分析思考能力(持续学习才是王道),这样才能迎接区块链时代的到来,不被大浪潮所淘汰。如何做到持续学习呢? 更多区块链信息:www.qukuaiwang.com.cn/news
    2019-01-18 19:04 1972
  • Cosmos整体流程

    Cosmos主要的源码其实是在SDK部分,听名字也可以理解出来,直接用这个SDK就可以写出一条不考虑底层的区块链来,但是做为中继链的一个代表,理想和现实并不是那么完美的结合在一起。 目前区块链跨链的难点在于,网络异构、共识算法不兼容等,而解决这些问题,都意味着巨大的投入和风险。Cosmos的目的是想建立一个区块链互联网,所以他把网络和共识抽象出来,专门做了一层。但是这样做的方法,虽然从理论上讲是没有问题的,可开发上难度还是增加了,开发者必须适应新的套路和不同的设计方法,怎么办? 弄个SDK,隔离变化,软件界的通用手段。 一、SDK的架构 看一下架构图: 上图可以看出来,其实SDK就是为了APP服务的,图中的应用程序其实就是给的例子,让大家能快速上手。然后另外两部分一个是和抽象层(共识和P2P)通信的,另外一个是用来调用各种插件的。 SDK从开始到现在,也进行了好几次比较大的改动了,至于今后会不会再有大的改动,也不敢肯定。所以说,做成插件化,是一个最好的选择,到时候看谁不顺眼,直接搞掉就可以了,喜欢谁,把插件接进来就OK。 1、plugins层 在插件层其实图中画的并不是很完全只是一个示意。主要的几个插件包括staking、IBC、 bank、 auth、 governance 、tx、 keys等几个。staking主要是控制Atom持有者相关贡献。类似一个汇率机制,动态变化。IBC其实就是链间通信机制,因为各个通信链是通过插件插入到HUB中进行通信,所以需要一个相应的通信机制来保证通信的安全性。governance这个模块目前在源码中看好像注释了不少,只保留了较少的东西,它主要是治理相关的实现,如提议、投票等。bank其实就是提供了一系列的通信接口(资产转移的),所以叫“银行”。 2、APP层 这一层基本没啥可说的,应该就是客户开发的APP,但是为了能让客户迅速进入,提供了三个相关的Demo。其中Basecoin是第一个完成的,是一个相对完整的应用,实现了SDK的核心模块的扩展,提供了诸如帐户管理、管理交易类型、处理存储等。 其它两个都是相关的扩展。 3、BaseApp 这一层主要是ABCI的通信,和Tendermint进行交互,Cosmos的核心就在这里。 二、源码流程 1、启动流程 从主程序的接口来分析源码: 这里只分析前两步,最后一步等分析Tendermint时再展开分析。 func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp {     cdc := MakeCodec()     // create your application object     //创建一个相关的APP,其它所有的APP都可以按照这个方法     var app = &GaiaApp{         BaseApp:     bam.NewBaseApp(appName, cdc, logger, db),         cdc:         cdc,         keyMain:     sdk.NewKVStoreKey("main"),         keyAccount:  sdk.NewKVStoreKey("acc"),         keyIBC:      sdk.NewKVStoreKey("ibc"),         keyStake:    sdk.NewKVStoreKey("stake"),         keySlashing: sdk.NewKVStoreKey("slashing"),     }     // define the accountMapper     //帐户管理--从KVSTROE抽象     app.accountMapper = auth.NewAccountMapper(         app.cdc,         app.keyAccount,      // target store         &auth.BaseAccount{}, // prototype     )     // add handlers     //添加各种操作——它们都从KVSTORE抽象出来,但是它们的抽象度更高,或者可以认为是accountMapper的更高一层。     //处理帐户的操作,再抽象一层     app.coinKeeper = bank.NewKeeper(app.accountMapper)     app.ibcMapper = ibc.NewMapper(app.cdc, app.keyIBC, app.RegisterCodespace(ibc.DefaultCodespace))     //处理Atom     app.stakeKeeper = stake.NewKeeper(app.cdc, app.keyStake, app.coinKeeper, app.RegisterCodespace(stake.DefaultCodespace))     //设置惩罚机制操作者     app.slashingKeeper = slashing.NewKeeper(app.cdc, app.keySlashing, app.stakeKeeper, app.RegisterCodespace(slashing.DefaultCodespace))     // register message routes     //这个是重点,在这里注册路由的句柄     app.Router().         AddRoute("bank", bank.NewHandler(app.coinKeeper)).         AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.coinKeeper)).         AddRoute("stake", stake.NewHandler(app.stakeKeeper))     // initialize BaseApp     //初始化相关参数     app.SetInitChainer(app.initChainer)     app.SetBeginBlocker(app.BeginBlocker)     app.SetEndBlocker(app.EndBlocker)     //设置权限控制句柄     app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeCollectionKeeper))     //从KV数据库加载相关数据--在当前版本中,IVAL存储是KVStore基础的实现     app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyIBC, app.keyStake, app.keySlashing)     err := app.LoadLatestVersion(app.keyMain)     if err != nil {         cmn.Exit(err.Error())     }     return app } // custom tx codec //将相关的编码器注册到相关的各方 func MakeCodec() *wire.Codec {     var cdc = wire.NewCodec()     ibc.RegisterWire(cdc)     bank.RegisterWire(cdc)     stake.RegisterWire(cdc)     slashing.RegisterWire(cdc)     auth.RegisterWire(cdc)     sdk.RegisterWire(cdc)     wire.RegisterCrypto(cdc)     return cdc } //其下为具体的上面的HANDLER的设置 // application updates every end block func (app *GaiaApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {     tags := slashing.BeginBlocker(ctx, req, app.slashingKeeper)     return abci.ResponseBeginBlock{         Tags: tags.ToKVPairs(),     } } // application updates every end block func (app *GaiaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {     validatorUpdates := stake.EndBlocker(ctx, app.stakeKeeper)     return abci.ResponseEndBlock{         ValidatorUpdates: validatorUpdates,     } } // custom logic for gaia initialization func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {     stateJSON := req.AppStateBytes     // TODO is this now the whole genesis file?     var genesisState GenesisState     err := app.cdc.UnmarshalJSON(stateJSON, &genesisState)     if err != nil {         panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468         // return sdk.ErrGenesisParse("").TraceCause(err, "")     }     // load the accounts     for _, gacc := range genesisState.Accounts {         acc := gacc.ToAccount()         app.accountMapper.SetAccount(ctx, acc)     }     // load the initial stake information     stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData)     return abci.ResponseInitChain{} } 这里面需要说明的是,Mapper和Keeper。记得在写数据库程序的时候,有几种方法,一种是直接连接操作数据库,拿到结果,这种方法最原始,但是权力也最大,想怎么操作就怎么操作。后来有了可以使用封装对象,这样访问数据库就被控制了起来,但是仍然是可以访问很多原始的东西。现在主流的使用的是Mybaits什么的,抽象的更厉害,基本上与你无关的数据,你根本不知道在哪儿了。 Mapper和Keeper就是干这个的,前者抽象度一般,后者更高一些。目的就是限制模块对功能访问的方式。按照最小权限原则来提供访问机制。这样,安全性和不必要的异常的出现就被控制起来,使得应用上更容易扩展。 这里其实主要是governance和slashing,前者主要是控制提议和投票等,后者主要是防止有人做恶,然后从staking中slash掉你的Atom。说白了就是把你的抵押的钱没收。这里顺道说一下这个原则:Atom的持有者可以是验证人也可以是委托人,委托人可以根据他们对验证人的认知和具体的情况将token委托给验证人,验证人即可代理Atom资产并从每个出块奖励中得到大部分,另外有一小部分给委托人,还有一小部分供节点的自运行。而为了保证验证人的诚实,向区块链中发布不正确的数据的恶意验证人会失去他们的Atom。这就叫做slashing。 2、ABCI接口分析 在整个的SDK的流程中,调用ABCI同Tendermint进行通信是一个重要的机制。虽然这篇并不讨论Tendermint,但是相关的ABCI的接口得说明一下,否则在SDK的流程调用中不明白相关的规则,就会导致对整个流程的理解无法正常进行。ABCI有三种消息类型,DeliverTx,CheckTx, Commit。其中DeliverTx和BeginBlock和EndBlock两个接口有关系。 1、InitChain 在上面的流程介绍过app.initChain的方法,它会被Tendermint在启动时调用一次,用来初始化各种相关的Message,比如共识层的参数和最初的验证人的集合数据。当然,肯定还会有决定信息处理的方式。在白皮书中提到,你可以在此处将引进的数据结构进行JSON编码,然后在调用这个函数的期间,对这些信息进行填充并存储。 // Implements ABCI // InitChain runs the initialization logic directly on the CommitMultiStore and commits it. func (app *BaseApp) InitChain(req abci.RequestInitChain) (res abci.ResponseInitChain) {     if app.initChainer == nil {         return     }     // Initialize the deliver state and run initChain     app.setDeliverState(abci.Header{})     app.initChainer(app.deliverState.ctx, req) // no error     // NOTE: we don't commit, but BeginBlock for block 1     // starts from this deliverState     return } func (app *BaseApp) setDeliverState(header abci.Header) {     ms := app.cms.CacheMultiStore()     app.deliverState = &state{         ms:  ms,         ctx: sdk.NewContext(ms, header, false, nil, app.Logger),     } } 当这些信息被正确的处理后,比如是一个帐户相关的信息,那么就可以使用它来进行交易的处理了。 2、BeginBlock 在上面提到过Tendermint的三种消息,其中的交易处理消息DeliverTx,它就是在区块开始被调用前,在这个接口中处理验证人签名的信息。如果大家写过数据库的底层操作,这个东西应该和它非常类似,不外乎是Begin准备,End结束,清扫资源。不过使用它的时候也需要注意,它和其它的相类似的操作一样,在这两个函数的处理过程中,不应该包含过多的和过于复杂的操作,导致整个消息的阻塞。 如果在这二者中出现了不合理的循环等,就有可能导致应用程序APP的假死。 // application updates every end block func (app *GaiaApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {     tags := slashing.BeginBlocker(ctx, req, app.slashingKeeper)     return abci.ResponseBeginBlock{         Tags: tags.ToKVPairs(),     } } // slashing begin block functionality func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, sk Keeper) (tags sdk.Tags) {     // Tag the height     heightBytes := make([]byte, 8)     binary.LittleEndian.PutUint64(heightBytes, uint64(req.Header.Height))     tags = sdk.NewTags("height", heightBytes)     // Deal with any equivocation evidence     for _, evidence := range req.ByzantineValidators {         pk, err := tmtypes.PB2TM.PubKey(evidence.Validator.PubKey)         if err != nil {             panic(err)         }         switch string(evidence.Type) {         case tmtypes.ABCIEvidenceTypeDuplicateVote:             //处理验证器在同一高度签名两个块             sk.handleDoubleSign(ctx, evidence.Height, evidence.Time, pk)         default:             ctx.Logger().With("module", "x/slashing").Error(fmt.Sprintf("Ignored unknown evidence type: %s", string(evidence.Type)))         }     }     // Iterate over all the validators  which *should* have signed this block     for _, validator := range req.Validators {         present := validator.SignedLastBlock         pubkey, err := tmtypes.PB2TM.PubKey(validator.Validator.PubKey)         if err != nil {             panic(err)         }         sk.handleValidatorSignature(ctx, pubkey, present)     }     return } 3、EndBlock 响应上一个函数接口,在DeliverTx消息处理完成所有的交易后调用,主要用来对验证人集合的结果进行维护。 // Implements ABCI func (app *BaseApp) EndBlock(req abci.RequestEndBlock) (res abci.ResponseEndBlock) {     if app.endBlocker != nil {         res = app.endBlocker(app.deliverState.ctx, req)     } else {         res.ValidatorUpdates = app.valUpdates     }     return } 4、Commit 当处理完成交易后,应该把完成的交易从内存持久化到硬盘上,并根据创建返回被下一个Tendermint区块需要的默克尔树的Root哈希值。这个哈希值 的作用在区块链中基本是一样的,用来验证合法性。 // Implements ABCI func (app *BaseApp) Commit() (res abci.ResponseCommit) {     header := app.deliverState.ctx.BlockHeader()     /*         // Write the latest Header to the store             headerBytes, err := proto.Marshal(&header)             if err != nil {                 panic(err)             }             app.db.SetSync(dbHeaderKey, headerBytes)     */     // Write the Deliver state and commit the MultiStore     app.deliverState.ms.Write()     commitID := app.cms.Commit()     app.Logger.Debug("Commit synced",         "commit", commitID,     )     // Reset the Check state to the latest committed     // NOTE: safe because Tendermint holds a lock on the mempool for Commit.     // Use the header from this latest block.     app.setCheckState(header)     // Empty the Deliver state     app.deliverState = nil     return abci.ResponseCommit{         Data: commitID.Hash,     } } 5、Query 这个就不多说了吧,你总得给别人一个看一看的机会。 // Implements ABCI. // Delegates to CommitMultiStore if it implements Queryable func (app *BaseApp) Query(req abci.RequestQuery) (res abci.ResponseQuery) {     path := strings.Split(req.Path, "/")     // first element is empty string     if len(path) > 0 && path[0] == "" {         path = path[1:]     }     // "/app" prefix for special application queries     if len(path) >= 2 && path[0] == "app" {         var result sdk.Result         switch path[1] {         case "simulate":             txBytes := req.Data             tx, err := app.txDecoder(txBytes)             if err != nil {                 result = err.Result()             } else {                 result = app.Simulate(tx)             }         default:             result = sdk.ErrUnknownRequest(fmt.Sprintf("Unknown query: %s", path)).Result()         }         value := app.cdc.MustMarshalBinary(result)         return abci.ResponseQuery{             Code:  uint32(sdk.ABCICodeOK),             Value: value,         }     }     // "/store" prefix for store queries     if len(path) >= 1 && path[0] == "store" {         queryable, ok := app.cms.(sdk.Queryable)         if !ok {             msg := "multistore doesn't support queries"             return sdk.ErrUnknownRequest(msg).QueryResult()         }         req.Path = "/" + strings.Join(path[1:], "/")         return queryable.Query(req)     }     // "/p2p" prefix for p2p queries     if len(path) >= 4 && path[0] == "p2p" {         if path[1] == "filter" {             if path[2] == "addr" {                 return app.FilterPeerByAddrPort(path[3])             }             if path[2] == "pubkey" {                 return app.FilterPeerByPubKey(path[3])             }         }     }     msg := "unknown query path"     return sdk.ErrUnknownRequest(msg).QueryResult() } 6、CheckTx 所有的拥有交易池的区块链,基本上在进池前后都要搞一些事情,包括对各种合法性的检查,目的只有一个,防止千辛万苦才生产出来的区块打包一些没用的交易。在Cosmos中也会有这种手段,在前面提到过AnteHandler,通过其对发送者授权,确定在交易前有足够的手续费,不过它和以太坊有些类似,如果交易失败,这笔费用仍然没有了,收不回去。 // Implements ABCI func (app *BaseApp) CheckTx(txBytes []byte) (res abci.ResponseCheckTx) {     // Decode the Tx.     var result sdk.Result     var tx, err = app.txDecoder(txBytes)     if err != nil {         result = err.Result()     } else {         result = app.runTx(runTxModeCheck, txBytes, tx)     }     return abci.ResponseCheckTx{         Code:      uint32(result.Code),         Data:      result.Data,         Log:       result.Log,         GasWanted: result.GasWanted,         GasUsed:   result.GasUsed,         Fee: cmn.KI64Pair{             []byte(result.FeeDenom),             result.FeeAmount,         },         Tags: result.Tags,     } } 3、IBC通信源码 在前面的代码中初始化时需要对路由进行注册,在这里同样会有路由的实际注册过程,先看一看提供的命令处理方式: // IBC transfer command func IBCTransferCmd(cdc *wire.Codec) *cobra.Command {     cmd := &cobra.Command{         Use: "transfer",         RunE: func(cmd *cobra.Command, args []string) error {             ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc))             // get the from address             from, err := ctx.GetFromAddress()             if err != nil {                 return err             }             // build the message             msg, err := buildMsg(from)             if err != nil {                 return err             }             // get password             res, err := ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, msg, cdc)             if err != nil {                 return err             }             fmt.Printf("Committed at block %d. Hash: %s\n", res.Height, res.Hash.String())             return nil         },     }     cmd.Flags().String(flagTo, "", "Address to send coins")     cmd.Flags().String(flagAmount, "", "Amount of coins to send")     cmd.Flags().String(flagChain, "", "Destination chain to send coins")     return cmd } 处理传输命令,进入中继环节处理: // flags--代表从一个空间转向另外一个窠 const (     FlagFromChainID   = "from-chain-id"     FlagFromChainNode = "from-chain-node"     FlagToChainID     = "to-chain-id"     FlagToChainNode   = "to-chain-node" ) type relayCommander struct {     cdc       *wire.Codec     address   sdk.Address     decoder   auth.AccountDecoder     mainStore string     ibcStore  string     accStore  string     logger log.Logger } // IBC relay command func IBCRelayCmd(cdc *wire.Codec) *cobra.Command {     cmdr := relayCommander{         cdc:       cdc,         decoder:   authcmd.GetAccountDecoder(cdc),         ibcStore:  "ibc",         mainStore: "main",         accStore:  "acc",         logger: log.NewTMLogger(log.NewSyncWriter(os.Stdout)),     }     cmd := &cobra.Command{         Use: "relay",         Run: cmdr.runIBCRelay,     }     cmd.Flags().String(FlagFromChainID, "", "Chain ID for ibc node to check outgoing packets")     cmd.Flags().String(FlagFromChainNode, "tcp://localhost:46657", "<host>:<port> to tendermint rpc interface for this chain")     cmd.Flags().String(FlagToChainID, "", "Chain ID for ibc node to broadcast incoming packets")     cmd.Flags().String(FlagToChainNode, "tcp://localhost:36657", "<host>:<port> to tendermint rpc interface for this chain")     cmd.MarkFlagRequired(FlagFromChainID)     cmd.MarkFlagRequired(FlagFromChainNode)     cmd.MarkFlagRequired(FlagToChainID)     cmd.MarkFlagRequired(FlagToChainNode)     viper.BindPFlag(FlagFromChainID, cmd.Flags().Lookup(FlagFromChainID))     viper.BindPFlag(FlagFromChainNode, cmd.Flags().Lookup(FlagFromChainNode))     viper.BindPFlag(FlagToChainID, cmd.Flags().Lookup(FlagToChainID))     viper.BindPFlag(FlagToChainNode, cmd.Flags().Lookup(FlagToChainNode))     return cmd } //启动遍历监听 func (c relayCommander) runIBCRelay(cmd *cobra.Command, args []string) {     fromChainID := viper.GetString(FlagFromChainID)     fromChainNode := viper.GetString(FlagFromChainNode)     toChainID := viper.GetString(FlagToChainID)     toChainNode := viper.GetString(FlagToChainNode)     address, err := context.NewCoreContextFromViper().GetFromAddress()     if err != nil {         panic(err)     }     c.address = address     c.loop(fromChainID, fromChainNode, toChainID, toChainNode) } func (c relayCommander) loop(fromChainID, fromChainNode, toChainID,     toChainNode string) {     ctx := context.NewCoreContextFromViper()     // get password     passphrase, err := ctx.GetPassphraseFromStdin(ctx.FromAddressName)     if err != nil {         panic(err)     }     ingressKey := ibc.IngressSequenceKey(fromChainID) OUTER:     for {         time.Sleep(5 * time.Second)         processedbz, err := query(toChainNode, ingressKey, c.ibcStore)         if err != nil {             panic(err)         }         var processed int64         if processedbz == nil {             processed = 0         } else if err = c.cdc.UnmarshalBinary(processedbz, &processed); err != nil {             panic(err)         }         lengthKey := ibc.EgressLengthKey(toChainID)         egressLengthbz, err := query(fromChainNode, lengthKey, c.ibcStore)         if err != nil {             c.logger.Error("Error querying outgoing packet list length", "err", err)             continue OUTER //TODO replace with continue (I think it should just to the correct place where OUTER is now)         }         var egressLength int64         if egressLengthbz == nil {             egressLength = 0         } else if err = c.cdc.UnmarshalBinary(egressLengthbz, &egressLength); err != nil {             panic(err)         }         if egressLength > processed {             c.logger.Info("Detected IBC packet", "number", egressLength-1)         }         seq := c.getSequence(toChainNode)         for i := processed; i < egressLength; i++ {             egressbz, err := query(fromChainNode, ibc.EgressKey(toChainID, i), c.ibcStore)             if err != nil {                 c.logger.Error("Error querying egress packet", "err", err)                 continue OUTER // TODO replace to break, will break first loop then send back to the beginning (aka OUTER)             }             err = c.broadcastTx(seq, toChainNode, c.refine(egressbz, i, passphrase))             seq++             if err != nil {                 c.logger.Error("Error broadcasting ingress packet", "err", err)                 continue OUTER // TODO replace to break, will break first loop then send back to the beginning (aka OUTER)             }             c.logger.Info("Relayed IBC packet", "number", i)         }     } } func (c relayCommander) broadcastTx(seq int64, node string, tx []byte) error {     _, err := context.NewCoreContextFromViper().WithNodeURI(node).WithSequence(seq + 1).BroadcastTx(tx)     return err } //处理接收的消息 func (c relayCommander) refine(bz []byte, sequence int64, passphrase string) []byte {     var packet ibc.IBCPacket     if err := c.cdc.UnmarshalBinary(bz, &packet); err != nil {         panic(err)     }     msg := ibc.IBCReceiveMsg{         IBCPacket: packet,         Relayer:   c.address,         Sequence:  sequence,     }     ctx := context.NewCoreContextFromViper().WithSequence(sequence)     res, err := ctx.SignAndBuild(ctx.FromAddressName, passphrase, msg, c.cdc)     if err != nil {         panic(err)     }     return res } 通过一个中继节点来监听两条不同的链,进行消息的路由注册来达到自动跨链交易,Cosmos提供的这个方式还是比较不错的。至少,不用自己再犯愁怎么做。但是这个有一个前提,需要注册一下: // RegisterRoutes - Central function to define routes that get registered by the main application func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) {     r.HandleFunc("/ibc/{destchain}/{address}/send", TransferRequestHandlerFn(cdc, kb, ctx)).Methods("POST") } 三、总结 通过上面的代码分析,可以看出,ABCI和IBC两个模块,是运行整个Cosmos的一个基础。Cosmos-SDK把这几个模块有机的抽象到一起,并提供了基础的交易、通信等功能。新的区块链可以从它上面调用或者继承Example中的例程,只关心区块链功能的开发,短时间内就可以方便的开发出一条公链来。
    2019-01-18 18:58 2515
  • 区块链操作系统中治理的重要性

    亚马逊(Amazon)、谷歌、Netflix和Facebook等大公司都有自己的规则,这一点很明显,因为它们就像国家一样,拥有中央集权。在集中的基础设施中,规则可以由管理团队或其他授权人员执行。每个国家都需要公民来遵守宪法。当政府在议会获得多数票时,可以批准修改和新立法。 治理是统治的行为。它是对《宪法》(政治治理)中政府或权威规定的规则的执行。公司治理是组织用于决策的过程。总的来说,您可以说治理涉及组织和国家的决策过程。在本文中,我想讨论另一个治理系统的重要性,即区块链治理。 分散式基础设施中的治理 分散式区块链操作系统(OS)是基于双方之间的对等交互。在分散式操作系统中,集中的第三方决策者可以被自治的治理系统所替代。 现在让我们将治理应用于分散式系统。在一个分散式生态系统中,缺失的环节是第三方。那么,我们如何知道这些规则,如何确保每个人都遵守这些规则呢?将其与特定国家的传统政府制度进行比较是有意义的。宪法是每个人都需要遵守的官方规章制度的协议。在区块链操作系统中,可以通过集成协议中的规则集来替换构造。每个区块链都可以标记自己特定的规则集。 治理系统的组成部分 区块链治理操作模型将由两个主要组件组成: -奖励计划,网络参与者的贡献将得到相应的奖励。 -协调机制,其中每组网络参与者都有能力提交具体的调整方案。 区块链治理还涉及4个关键社区: · 核心开发人员 · 节点操作符 · 代币持有者 · 项目团队/组织 区块链治理系统可以在链上或链外实现。链上治理允许代币持有者通过使用网络内部代币进行投票。链外治理意味着重要的决策将在网络涉众之间直接投票。例如,开发人员可以通过将由网络社区投票的改进建议提交更改。大多数区块链治理系统选择离线治理。 为了给出一些目前在区块链项目中实现治理系统的例子,我想强调四个不同的区块链及其相应的治理结构。 比特币治理系统 比特币的大部分治理系统都源自中本聪(Satoshi Nakamoto)的白皮书。在过去10年中,一些规则被添加或修改,以解决错误和拒绝的服务漏洞。当研究人员或开发人员发现一个问题的解决方案时,例如可伸缩性或安全性,可以提交一个比特币改进建议(BIP)。当网络的涉众达成一致意见时,该提议被集成到协议中,并且由于协议的变更而产生一个分叉。分叉有两种不同的形式,软分叉和硬分叉。对于比特币网络用户来说,与硬分叉相反,实现软分叉通常没有问题。软分叉不需要每个人同时切换到新的协议。硬分叉将网络分成两个部分,两个协议各自独立,将来无法重新连接。 以太坊治理系统 以太坊的治理相当直接。在下面的图像中,你将发现以太坊治理系统的基本结构。箭头越粗,影响越大。所有开发人员每两周安排一次会议,讨论开发更新和治理建议,以保持系统的同步。 以太坊治理系统的最大好处之一是能够从工作证明向权益关系证明进行重大转变。以太坊的君士坦丁堡硬分叉,将发生在7080,000块高度,实现了从工作证明到权益证明的变化。矿商的权力将转移到任何持有足够数量ETH以运行虚拟货币的人手中。 对以太坊治理系统的一大挑战是DAO攻击和随后的以太坊硬分叉。2016年以太坊硬分叉将链分为两个独立区块链,以太坊和以太经典。 当区块链项目Polkadot在2017年11月由于平价漏洞损失了大部分ICO资金(9100万美元)时,以太坊的不同利益相关者要求获得一个类似于DAO基金的硬分叉。这一次,大股东投票否决了一项收回资金的艰难计划。 EOS的治理系统 EOS的四大支柱之一是其治理系统。EOS选出了21家同意网络章程的区块链生产商。充当p2p终端用户许可协议。一项宪法改革要求大多数大宗商品生产商同意这一提议。EOS已经建立了一个治理系统来处理争端。这就是EOSIO核心仲裁论坛(ECAF)。区块生产商有义务执行ECAF的所有规定。 最近,一份可能来自EOS块生成商的泄露文件浮出水面,助长了有关领先数字资产服务提供商打算操纵EOS块生成商治理系统的传言。到目前为止,还没有证据证明他们实际上操纵了其他区块生产商,但如果这是一种可能性,那么治理系统并没有显示出真正的去中心化。 Aelf的治理系统 分布式云计算平台Aelf,提出了一种DPoS共识治理系统。DPoS选择能力很强的代表,以快速高效的方式做出重要的协议决策。 Aelf建议通过Aelf操作系统创建的侧链通过主链合并挖掘并部署它们自己的协商共识协议。这样,每个侧链都可以拥有自己的治理系统,根据自己的特定需求进行定制。Aelf将使用投票系统,根据节点对网络的贡献,定期对系统内和系统外的节点进行投票。 总结 一个正常运行的治理系统对于区块链项目继续向前发展是至关重要的。一个可定制的治理系统应该能够满足大多数需求,因为区块链系统需要能够适应它们的环境。 更多区块链信息:www.qukuaiwang.com.cn/news
    2019-01-18 16:50 4335
# 币种 价格¥ 涨幅
# 币种 价格¥ 涨幅
# 币种 价格¥ 成交额¥
  • 1 BTC/比特币 42,494.02 302.75亿
  • 2 USDT/泰达币 6.46 182.21亿
  • 3 ETH/以太坊 3,219.53 146.48亿
  • 4 EOS/柚子 70.33 81.77亿
  • 5 BCH/比特现金 5,568.76 29.32亿
  • 6 LTC/莱特币 628.10 22.90亿
  • 7 XRP/瑞波币 3.53 20.68亿
  • 8 TRX/波场 0.2891 17.39亿
比特币多空调查

今日比特币行情,你怎么看?

看涨37%
盘整17%
看跌47%
  • 看涨
  • 盘整
  • 看跌
投票 您已经投过票了

每日15:00投票数据自动清零


扫二维码

扫一扫,关注微信公众号