├── 08.0.md ├── images └── 3.1.eval-perm.png ├── 06.0.md ├── 07.0.md ├── 05.0.md ├── ref.md ├── 01.4.md ├── 03.3.md ├── 03.2.md ├── preface.md ├── 01.0.md ├── 02.0.md ├── README.md ├── 06.1.md ├── 03.0.md ├── 04.0.md ├── 02.1.md ├── 09.0.md ├── 04.1.md ├── 02.2.md ├── 01.3.md ├── 03.1.md ├── 01.2.md └── 01.1.md /08.0.md: -------------------------------------------------------------------------------- 1 | # 带宽 2 | 3 | ## links 4 | * [目录]() 5 | * 上一章: [存储模型](<07.0.md>) 6 | * 下一章: [治理](<09.0.md>) 7 | -------------------------------------------------------------------------------- /images/3.1.eval-perm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyHao/Source-code-analysis-for-EOS/HEAD/images/3.1.eval-perm.png -------------------------------------------------------------------------------- /06.0.md: -------------------------------------------------------------------------------- 1 | # 智能合约 2 | 3 | ## links 4 | * [目录]() 5 | * 上一章: [共识算法](<05.0.md>) 6 | * 下一节: [脚本和虚拟机](<06.1.md>) 7 | -------------------------------------------------------------------------------- /07.0.md: -------------------------------------------------------------------------------- 1 | # 存储模型 2 | 3 | ## links 4 | * [目录]() 5 | * 上一章: [脚本和虚拟机](<06.1.md>) 6 | * 下一章: [带宽](<08.0.md>) 7 | -------------------------------------------------------------------------------- /05.0.md: -------------------------------------------------------------------------------- 1 | # 共识算法 2 | 3 | 4 | ## links 5 | * [目录]() 6 | * 上一章: [通证模型和资源使用](<04.1.md>) 7 | * 下一章: [智能合约](<06.0.md>) 8 | -------------------------------------------------------------------------------- /ref.md: -------------------------------------------------------------------------------- 1 | # 附录A 参考自考 2 | 3 | 1. [EOS wiki](https://github.com/EOSIO/eos/wiki) 4 | 2. [EOS White Paper](https://github.com/EOSIO/Documentation/blob/master/TechnicalWhitePaper.md/#background) -------------------------------------------------------------------------------- /01.4.md: -------------------------------------------------------------------------------- 1 | # 1.4 总结 2 | 3 | 本章中我们首先向大家介绍了EOS这个项目的由来和它重点要解决的问题,接下来介绍了如何在服务器上安装EOS系统,然后我们具体讨论了如何运行EOS节点,目前支持几种方式的运行,包括本地单节点,本地多节点,连接测试网络的节点与Docker 节点。最后,我们通过一个智能合约案例让大家对EOS系统的功能有了一个初步的体验。 4 | 由于EOS系统代码正处于快速的迭代开发中,因此你在实际操作中,下载的版本可能与本文所对应的版本并不完全相符,可能会导致有些地方有出入,不过相信这些地方应该不多,欢迎大家随时交流,交流QQ 为:721541010 5 | 6 | 7 | 8 | ## links 9 | * [目录]() 10 | * 上一节: [EOS案例分析](<01.3.md>) 11 | * 下一章: [EOS钱包](<02.0.md>) -------------------------------------------------------------------------------- /03.3.md: -------------------------------------------------------------------------------- 1 | # 恢复被盗窃的密钥 2 | EOS系统提供给用户一种找回失窃密钥控制权的方式。账户的恢复需要有以下两个要素: 3 | 4 | 1. 过去30 天活跃的任意的`owner key` 5 | 2. 指定的账户恢复合作伙伴所给出的批准 6 | 7 | 以上两个条件缺一不可。 8 | 9 | 那对于已经获取了账号控制权的黑客来说,他会尝试去执行这个账户恢复流程吗?正常来说应该不会,因为他已经取得了账号控制权,再走这个流程对他没有太大的意义。当然,也许这位黑客想完全控制此账户,他希望通过重置`owner key`而完全拥有它,但当他走这个账户恢复过程的时候,账户恢复合作伙伴将会通过多种方式进行身份验证(例如电话,邮箱等)。这将是的黑客做出让步或者无功而返。 10 | 11 | 账号恢复流程看上去也需要多个账户的合作,有点类似多签名交易的过程,但其实它们是完全不同的两个流程。在多签名流程中,其他参与账号需要针对每笔执行的交易都要进行签名。但在账号恢复流程中,账号恢复合作者只能参与到账号恢复的流程,而无权参与到日常的交易消息签名。这大大降低了账号恢复合作者的成本和法律责任。 12 | 13 | ## links 14 | * [目录]() 15 | * 上一节: [消息和处理程序](<03.2.md>) 16 | * 下一章: [Token](<04.0.md>) 17 | -------------------------------------------------------------------------------- /03.2.md: -------------------------------------------------------------------------------- 1 | # 消息和处理程序 2 | 在EOS中,每个账号都可以向其他账户发送结构化的消息,并且可以定义脚本来处理他们接收到的消息。同时,EOS 还给每个账户提供了只有自己的消息处理脚本才能访问的私有数据库。消息处理脚本同样能够给其他账户发送消息,消息和自动化消息处理的结合构成了EOS的智能合约。 3 | 4 | ## 带强制性延迟的消息 5 | 时间是安全中的一个关键组成部分。在大多数情况下,一个私钥在没有被使用前都无从知晓它是否被盗窃。当一个需要密钥的应用在你的某台每天联网的电脑上运行时,基于时间的安全会更加重要。EOS 允许应用开发者指定某条消息在加入到区块之后需要等待多久才能被执行,在这段等待时间,可以随时取消这条消息。 6 | 7 | 用户会在消息广播出去后通过邮件或者文字的形式收到通知,如果他们没有授权相关操作,则可以使用账户恢复流程来恢复账号,并收回消息。 8 | 9 | 这个延迟的长短取决于操作的敏感性。如果是为一杯咖啡付款,可以无需设置任何延迟,几秒内交易就不可逆了。而购买一套房子也许需要72小时的结算期。转移整个账号的控制则可能需要长达30 天。具体的延迟时间由开发者和用户来做选择。 10 | 11 | ## links 12 | * [目录]() 13 | * 上一节: [权限管理](<03.1.md>) 14 | * 下一节: [恢复被盗窃的密钥](<03.3.md>) 15 | -------------------------------------------------------------------------------- /preface.md: -------------------------------------------------------------------------------- 1 | * 1.[EOS 初体验](01.0.md) 2 | - 1.1. [EOS 安装](01.1.md) 3 | - 1.2. [EOS 运行](01.2.md) 4 | - 1.3. [EOS 案例分析](01.3.md) 5 | - 1.4. [小结](01.4.md) 6 | * 2.[EOS 钱包](02.0.md) 7 | - 2.1. [EOS 钱包工具](02.1.md) 8 | - 2.2. [钱包密钥](02.2.md) 9 | - 2.3. [EOS 钱包源代码分析] 10 | * 3.[EOS 账户](03.0.md) 11 | - 3.1. [权限管理](03.1.md) 12 | - 3.2. [消息和处理程序](03.2.md) 13 | - 3.4. [带有强制延迟性的消息](03.4.md) 14 | - 3.5. [恢复被盗窃的秘钥](03.5.md) 15 | * 4.[Token](04.0.md) 16 | - 4.1. [简介](04.1.md) 17 | - 4.2. [Token模型](04.2.md) 18 | * 5.[共识算法]() 19 | * 6.[智能合约] 20 | - 6.1. [脚本和虚拟机](06.1.md) 21 | * 7.[存储模型] 22 | * 8.[带宽] 23 | * 9.[治理与其他] 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /01.0.md: -------------------------------------------------------------------------------- 1 | # EOS 简介 2 | 区块链的概念首次在2008年末由中本聪(Satoshi Nakamoto)在比特币论文《Bitcoin: A Peer-to-Peer Eletronic Cash Sytem》中提出,论文中区块链技术是构建比特币数据结构与交易信息加密传输的基础技术,该技术实现了比特币的挖矿与交易。 3 | 4 | 随着电子货币的概念被更多的人所接受,其背后的区块链技术也进一步被更多的技术人员和商业人员充分发掘,他们认为区块链技术在很多领域中都将有广泛的应用,这种去中心化的可信网络将重构现有的商业逻辑。 5 | 6 | 但是完整的开发和部署一套去中心化的区块链网络并不是一件容易的事情,这需要投入巨大的研发精力和经费。于是有很多团队开始尝试开发一套底层区块链系统,从而能够方便更多的应用开发者在其基础上构建分布式应用。大家比较熟悉的以太坊正是这样一套区块链公链系统。但这些系统也有自身的问题,例如性能太低,确认延迟太长,需要用户付费等。 7 | 8 | 为了能够解决这些问题,Block.One 公司启动了EOS项目,这是一套基于区块链底层的公链系统,简单的说就是一套去中心化的操作系统,当EOS完成系统目标之后,任何团队都可以在EOS 上以比较快的速度开发出所需要的Dapp(基于区块链的分布式应用),这些应用可以让普通人无需任何手续费就可以方便的使用。而EOS的高性能(100w+tps,可以在一秒之内进行100W次打包记账)也可以承载数量众多的Dapp应用。 9 | 10 | 目前EOS还处于开发阶段,系统将于2018年七月份上线。到目前为止,最新发布的版本是Dawn3.0 版本,但这个代码只适合建构本地测试环境。公网的测试环境使用的是2.0 版本的代码,如果希望测试公网环境,可以考虑下载与部署2.0 版本。 11 | 12 | 接下来,我们就一起体验下如何安装,部署和使用EOS。 13 | 14 | 15 | ## links 16 | * [目录]() 17 | * 下一节: [EOS安装](<01.1.md>) -------------------------------------------------------------------------------- /02.0.md: -------------------------------------------------------------------------------- 1 | # EOS 钱包 2 | 钱包是区块链中一个很重要的概念。顾名思义,说到钱包的时候,我们一定会想到它是用来存钱的,但是数字化的钱包和现实社会的钱包还是有一些区别的。现实世界的钱包中真的放着法币,而数字化钱包存放的是钥匙,这把钥匙可以打开存放你余额的保险箱。 3 | 我们拿支付宝钱包做一个例子,支付宝钱包这个应用中也没有真实的钱,只有很多个账号和密码,每一对账号和密码都能打开一个保险箱,这些保险箱统一寄存在阿里服务器上。 4 | 区块链钱包也和支付宝钱包类似,里面没有真实的货币,而是存储了很多私钥,每一把钥匙都对应着一个数字货币的保险箱,这些保险箱则是保存在区块链上。这里的密钥就等同于支付宝中的一对账号和密码。这个私钥有以下两点作用: 5 | 6 | 1. 生成公钥,从而生成交易地址(类似于你的支付二维码) 7 | 2. 生成签名,从而签署一笔交易(类似于你的支付密码) 8 | 9 | 有了以上这两个功能后,你就可以与任何人进行货币的交易了。 10 | 11 | EOS 钱包中也保存着密钥,但EOS钱包和其他区块链钱包也存在着一些差异,主要差异在于EOS 中的密钥主要是用来生成签名的,它并不用来生成交易地址。也就是说上述私钥中的两点功能,EOS密钥主要用来支持第二点功能。那如果缺少了第一点功能,别人如何向你转账呢? EOS 的解决办法是引入了账号的概念,账号可以是2位到32位的任意字符串,从而方便用户记忆,用户之间的转账是通过账号来进行操作的。EOS团队认为使用公钥作为交易地址对用户来说太不友好了,没人能够记得一长串无意义的字符串,相比而言,人们更习惯以字符串名称作为账号来使用,因此,EOS引入了账号系统,每个账号都对应的密钥,主要用来进行签名处理。 12 | 13 | 接下来,我们将具体了解下EOS系统中钱包所提供的主要接口及其具体的实现。 14 | 15 | ## links 16 | * [目录]() 17 | * 上一章: [第一章总结](<01.4.md>) 18 | * 下一节: [EOS 钱包工具](<02.1.md>) 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EOS 源码分析 2 | 3 | 区块链的概念首次在2008年末由中本聪(Satoshi Nakamoto)在比特币论文《Bitcoin: A Peer-to-Peer Eletronic Cash Sytem》中提出,论文中区块链技术是构建比特币数据结构与交易信息加密传输的基础技术,该技术实现了比特币的挖矿与交易。 4 | 5 | 随着电子货币的概念被更多的人所接受,其背后的区块链技术也进一步被更多的技术人员和商业人员充分发掘,他们认为区块链技术在很多领域中都将有广泛的应用,这种去中心化的可信网络将重构现有的商业逻辑。 6 | 7 | 但是完整的开发和部署一套去中心化的区块链网络并不是一件容易的事情,这需要投入巨大的研发精力和经费。于是有很多团队开始尝试开发一套底层区块链系统,从而能够方便更多的应用开发者在其基础上构建分布式应用。大家比较熟悉的以太坊正是这样一套区块链公链系统。但这些系统也有自身的问题,例如性能太低,确认延迟太长,需要用户付费等。 8 | 9 | 为了能够解决这些问题,Block.One 公司启动了EOS项目,这是一套基于区块链底层的公链系统,简单的说就是一套去中心化的操作系统,当EOS完成系统目标之后,任何团队都可以在EOS 上以比较快的速度开发出所需要的Dapp(基于区块链的分布式应用),这些应用可以让普通人无需任何手续费就可以方便的使用,而EOS的高性能(100w+tps,可以在一秒之内进行100W次打包记账)也可以承载数量众多的Dapp应用,相信今后在此系统上将会诞生很多独角兽级别的分布式应用。 10 | 11 | 为了能够在此系统上建构高效的分布式应用,对于EOS系统的深入理解和分析必不可少,而源码的阅读是深入理解EOS系统最有效的方式,本书就是从源码入手来分析EOS背后的概念和机制,从而让大家对于区块链技术有一个更加深入的了解。书中主要会涉及以下内容: 12 | 13 | 1. 对白皮书的解读。EOS白皮书有中文版,但很多地方的翻译非常晦涩,完全不通顺,我根据自己对项目的理解进行了重新解读 14 | 2. EOS 中涉及到的一些区块链概念,在文中也给出了详细介绍 15 | 3. 对于某些概念的现实意义,给出了自己的理解。从源码级别理解项目固然重要,但更重要的是对区块链本身的认知升级,不断的探索这些概念在现实世界中的使用场景,这才能更大程度的推进区块链的发展。 16 | 4. 源码阅读;源码之下,了无密码。做技术的人往往更喜欢从源码级了解一个项目,这使得很多概念能够对应到底层的算法,对于理解这些概念将会很有帮助。理解了源码层,才能够说真正理解了一个项目,你不仅知道他能干什么,更能知道他为什么能够这么用,并且能够深刻的理解它下一步的演进方向。 17 | 18 | 19 | 目前EOS还处于开发阶段,源代码还在不断的迭代中,但整体流程和框架已经基本成型,目前已经发布到Dawn3.0 版本了,本书也会根据系统的迭代不断进行完善,欢迎对EOS 项目感兴趣的朋友一起交流。 20 | 21 | 微信:wary_2012 22 | 23 | -------------------------------------------------------------------------------- /06.1.md: -------------------------------------------------------------------------------- 1 | # 脚本和虚拟机 2 | EOS 将是第一个协同用户间认证消息传递的重要平台。脚本语言和虚拟机的具体实现与EOS 系统的设计是分离的。任何语言或者虚拟机,只要满足确定性和沙箱化,并且性能足够高,它就可以与EOS API集成。 3 | 4 | ## 模式定义的消息 5 | 所有用户间发送的消息都是通过模式定义出来,它是区块链共识状态的一部分。这个模式允许消息在二进制与JSON格式之间无缝的转换。 6 | 7 | ## 模式定义的数据库 8 | 数据库状态也是通过类似的模式来定义的。这是为了确保所有应用存储的数据都可以转换成人类可读的JSON格式,而其存储和操作时在采用高效的二进制格式。 9 | 10 | ## 分离鉴权和应用 11 | 为了最大限度的实现并行,并最小化从交易日志中恢复应用状态所需的计算债务,EOS 软件将验证逻辑分成三个部分: 12 | 13 | 1. 验证消息是否内部一致 14 | 2. 验证所有前提消息是否有效 15 | 3. 修改应用程序状态 16 | 17 | 验证消息内部一致性的操作是只读的,并且不需要访问区块链的状态。这就意味着此操作可以最大限度的并行化。验证前提条件的操作,例如验证余额是否足够,这也是只读的,因此也可以尽量并行化。只有修改应用程序状态需要写操作,对于每个应用来说,此操作只能顺序化的执行。 18 | 19 | 鉴权是一个验证消息是否能够被执行的只读过程。应用程序则实际的执行消息命令。在同一时间,这两种计算都需要被处理,然而,一旦交易被包含在区块中后就不再需要执行鉴权操作了。 20 | 21 | ## 虚拟机独立架构 22 | EOS 区块链支持多种虚拟机,并且随着时间的推移,可以根据需要来增加新的虚拟机。因此,在这份白皮书中不会讨论某个具体的脚本语言和虚拟机。不过,目前EOS正在评估可能使用的虚拟机有两种,分别是WASM(Web Assembly)和以太坊虚拟机 23 | 24 | ### Web Assembly(WASM) 25 | Web Assmembly 是一种为了构建高性能的Web应用而兴起的Web 标准。只需要进行少量的修改,Web Assembly 就可以支持确定性和沙盒化的特性,从而能够满足了EOS对脚本语言的要求。Web Assembly 的好处是它有着广泛的产业支持,并且它可以让开发者使用熟悉的语言,例如C和C++ 来开发智能合约。 26 | 27 | 以太坊的开发者已经开始更改Web Assembly来提供适当的沙盒化与确定性的支持,这使得它很容易在EOS中适配和集成。 28 | 29 | ### 以太坊虚拟机(EVM) 30 | 以太坊虚拟机已经被众多已有的智能合约所使用,并且可以通过适配应用在EOS区块链中。可以想象,以太坊合同能够以沙盒化的方式在EOS区块链上运行,并且通过一些适配,以太坊合同能够与EOS上的应用之间相互交流。 31 | 32 | 33 | ## links 34 | * [目录]() 35 | * 上一节: [智能合约](<06.0.md>) 36 | * 下一章: [存储模型](<07.0.md>) 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /03.0.md: -------------------------------------------------------------------------------- 1 | # EOS 账号 2 | EOS 的账号系统可以说在当前的公链系统中是非常完善的,在进一步理解EOS的账号系统以前,让我们先看一下区块链中其他公链的账户系统是怎样设计的。 3 | 4 | 大家都知道,区块链上的第一个应用就是比特币,它创建了一种点对点的电子货币系统。由于是一套货币系统,因此它主要针对的是货币的产生,点对点货币支付等场景,在这套系统中,设计的视角是从货币出发的,系统中仅有交易地址的概念,并没有账号的概念。 5 | 6 | 相比于交易地址,账号一般都会有余额的概念,系统为每个账户存放了余额信息,任何时候你都可以查询到此余额,而比特币交易地址并没有这些余额信息,比特币所保存的信息主要就是交易信息本身,余额信息是通过交易推算出来的,交易的过程类似于我们在生活中使用法币的场景。试想一下你兜里目前有3张一元和一张五元的纸币,当你要购买一个价格为2.5 角的冰激凌的时候,你可以考虑拿三张一元的纸币,也可以考虑直接使用一张五元的纸币,对方会根据你的纸币金额再找零给你。在任何一个时间点,其实没有一个固定的余额数字告诉你兜里还有多少钱,但你的余额可以根据你所有的交易数据推算出来,每个账户的余额就是你交易地址所涉及的所有未花费交易输出(UTXO: unspent transaction outputs)。比特币的这种账号系统的优势就在于他完全是无状态的,从技术的角度来说,无状态的系统更容易扩展,更容易并行处理。 7 | 8 | 与比特币的UTXO模型不同,以太坊是有账户体系的,它的账户包含四个部分: 9 | 10 | 1. 随机数,用于确定每笔交易只能被处理一次的计算器 11 | 2. 账户目前的以太币余额 12 | 3. 账户的合约代码,如果有的话 13 | 4. 账户的存储(默认为空) 14 | 15 | 以太坊有两种类型的账户:外部账户和智能合约账号,其中外部账号是没有代码的。人们可以通过创建和签名一笔交易从外部账号发送消息,每当智能合约账户收到消息后,其内部代码会被激活,允许代码对账户内部存储进行读取和写入。可以看到,账户系统对于智能合约功能的支持来说是必须的,有了账户的概念,智能合约中才能更方便的访问账户中的信息。 16 | 17 | 以太坊账户系统已经提供了一些通用的信息和功能,但这个账户系统在实际应用使用中,还是不够完善,主要集中在三个方面: 18 | 19 | 1. 账户的地址是一个20字节的地址,不方便记忆 20 | 2. 账户不支持权限管理,不能应用在需要复杂权限管理的场景 21 | 3. 密钥一旦丢失,再也无法使用此账号 22 | 23 | 正是看到了以上这些问题,EOS系统在设计的时候,力求打造一套具备完善功能的账号体系,这样能够更好的支持各类应用场景需要,具体特性包括: 24 | 25 | 1. 采用了方便人类阅读的字符串(2-32字符)来创建账号 26 | 2. 支持域的概念,例如@domain 账号的拥有者是唯一能够创建@user.domain 账号的人 27 | 3. 支持完善的权限管理体系 28 | 4. 账户间消息发送和处理 29 | 5. 恢复被盗窃的密钥 30 | 31 | 在本章中,我们就将详细的介绍以上这些特性,让你对EOS账号有一个更加深入的理解。 32 | 33 | ## links 34 | * [目录]() 35 | * 上一章: [钱包密钥](<02.2.md>) 36 | * 下一节: [权限管理](<03.1.md>) 37 | 38 | -------------------------------------------------------------------------------- /04.0.md: -------------------------------------------------------------------------------- 1 | # Token(通证) 2 | 3 | 区块链一直就有币圈和链圈之分,币圈的人有的埋头挖矿,有的专卖矿机,有的专心炒币,还有的搬砖套利做交易。而链圈的人则更关注区块链技术研发及应用。之前这两个圈子间相互鄙视,谁也看不起谁,币圈的人鄙视链圈贫穷,装清高;链圈的人鄙视币圈只知道炒作投机,唯利是图。 4 | 5 | 但这一切都已成为过去,2015年末,以太坊的上线为两圈融合提供了可能,通过以太坊发行自己的Token(也就是常说的发币,后续把Token 统一翻译成通证)变得很容易,业内产生了”以币养链,以链促币“ 的发展新模式。 6 | 7 | 通过以上可以看出,Token(通证)在区块链的发展中起到了决定性的作用。那Token(通证)到底是什么呢? 对于大部分人来说它就是一种代币,如果去年眼光比较好的话,应该也都通过这种代币的发行赚到了一笔。但这仅仅是从代币交易的角度在理解Token(通证),很显然,Token(通证)的真正价值不仅仅在此。 8 | 9 | 如果我们把某个区块链看成一个社群的话,那么Token(通证) 就是这个生态下衡量价值的标准。社群的组织有可能是因为某种兴趣,也可能是因为某种目的,大部分类似的社群都符合如下的特点:绝大多数人仅仅作为内容获取者,少数人充当优质内容提供者,极少数人充当社群管理者和投资者。也就是说,虽然大部分人都对此社区感兴趣,加入了社区,但只有很少的人愿意贡献,社群人员之间更是一种弱关系,即大家之前的关系非常松散,不太可能为了某一件事情而牺牲自己的利益,协同去完成目标。 10 | 11 | 出现这种情况的主要原因在于,大部分人会认为在这个社区上做贡献并没有给自己带来任何利益,仅仅只是从兴趣出发,很难调动起社群用户的潜在的积极性。现在很多虚拟社群都有积分体系,这些积分在社区内部会是一种身份的象征,但离开这个虚拟社群,就没有任何价值了,这就意味着个人在社区的贡献对于他的现实生活没有任何利益。但如果社群的积分能够在二级市场上流通,能够把这些积分兑换成法币,那社群贡献就和真实社会的价值打通了,相信这将从根本上激励更多的社区人员做出贡献。而Token(通证)正是起到了这样的作用,它就类似于虚拟社群的积分,但它可以通过交易所在二级市场流通,从而能够更有效的调动起社群人员的参与度。 12 | 13 | 从我们刚才介绍的Token(通证)的价值来看,它明明就是一个可以脱离区块链独立存在的概念。从某种意义来说,Q币,游戏币等等,都是原始的通证,他们都是数字话的权益证名。它们现在都运行在中心化的系统中,虽然没有密码学的安全保证,在流通上也受限制,但总体来说还不错,那为何现在的大部分人还是把Token(通证)和区块链绑在一起?这可能主要是因为区块链为Token(通证)提供了坚实的信任基础,它所达到的可信度,是任何传统中心化基础设施都提供不了的,它是大家所认可的“信任机器“。 14 | 15 | 我们对以上内容进一步提炼可知,通过Token(通证),区块链演变成为一种人类大规模协作的工具,它通过经济的正向和反向激励来实现人与人之间的强协作。它使我们第一次出现了没有信任中心就可以大规模协作的结构,这也许会意味着现在大家所熟悉的,已经流行近五百年的公司体制要面临转型,甚至是被颠覆,解体。从这个角度来说,区块链通过Token(通证)还真是重建了生产关系,相信在新的去中心化的,大规模协同合作的基础之上,能够产生出真正加速人类社会发展和变革力量。 16 | 17 | 本章我们就会重点介绍在EOS系统中Token(通证) 如何是如何被定义的。 18 | 19 | ## links 20 | * [目录]() 21 | * 上一章: [恢复被盗窃的密钥](<03.3.md>) 22 | * 下一节: [通证模型和资源使用](<04.1.md>) 23 | 24 | -------------------------------------------------------------------------------- /02.1.md: -------------------------------------------------------------------------------- 1 | # 钱包工具 2 | 钱包的主要功能就是存储私钥,从而在生成交易的时候可以进行签名。它一般是一个运行在你本地机器的程序。 3 | 在EOS系统中,钱包功能是以插件的方式提供的,这使得它可以很容易的集成在EOS节点中运行,也可以作为一个独立的程序运行; 4 | 5 | - 集成在EOS节点中 6 | 在eosd 所引用的config.ini 文件中加入钱包支持:`plugin = eosio::wallet_api_plugin`, 增加以上配置后,节点就支持钱包接口调用了 7 | - 独立的程序运行 8 | 钱包应用的路径为:`path-to-eos/build/programs/eos-walletd`,直接运行此程序即可 9 | 10 | ## 钱包所支持的命令 11 | `eos-walleted`是一个后台程序,它不直接支持命令行参数,但它支持RPC调用,你可以通过`eosc` 程序与其进行交互,此程序的路径为:`eos/build/programs/eosc`。其提供的命令如下: 12 | 13 | ### Create 14 | ``` 15 | $ eosc wallet create ${options} 16 | ``` 17 | 18 | Options: 19 | -n, --name TEXT=default 钱包的名称,默认名称为default 20 | 21 | ### Open 22 | 打开已创建的钱包。钱包只有处于打开状态,才能对其进行进一步的操作。 23 | 24 | ``` 25 | $ eosc wallet open ${options} 26 | ``` 27 | Options: 28 | -n,--name TEXT 所要打开钱包的名称 29 | 30 | ### Lock 31 | 对钱包进行加锁,一旦加锁后,就不能再对钱包进行其他操作了,解锁后才可进一步操作。 32 | 33 | ``` 34 | $ eosc wallet lock ${options} 35 | ``` 36 | 37 | Options: 38 | -n,--name TEXT 需要加锁的钱包名称 39 | 40 | ### Unlock 41 | 对钱包进行解锁。 42 | 43 | ``` 44 | $ eosc wallet unlock ${options} 45 | ``` 46 | Options: 47 | -n,--name TEXT 需要解锁的钱包名称 48 | --password TEXT 钱包密码,这个密码是在创建钱包时生成的 49 | 50 | ### Import private key into wallet 51 | 把私钥导入到钱包中,如果你想使用某一账号进行转账等操作,则此账号对应的私钥必须导入到钱包中才能进行。 52 | 53 | ``` 54 | $ eosc wallet import ${options} key 55 | ``` 56 | Positionals: 57 | key TEXT 将要导入的私钥,格式为 WIF。 58 | 59 | Options: 60 | -n,--name TEXT 钱包名称 61 | 62 | ### List 63 | 罗列出所有打开的钱包, *号标示的钱包表示其状态为 unlocked 64 | 65 | ``` 66 | $ eosc wallet list 67 | ``` 68 | 69 | ### Keys 70 | 罗列出所有unlocked状态钱包中的私钥,格式为 WIF。 71 | 72 | ``` 73 | $ eosc wallet keys 74 | ``` 75 | ## links 76 | * [目录]() 77 | * 上一节: [EOS 钱包](<02.0.md>) 78 | * 下一节: [钱包密钥](<02.2.md>) -------------------------------------------------------------------------------- /09.0.md: -------------------------------------------------------------------------------- 1 | # 治理 2 | 治理是人们在主观问题上达成共识的过程,这无法完全用软件算法来处理。之前的区块链(例如比特币,以太坊)都缺少了确定的治理流程,它们依赖于临时的,非正式的,充满争议的治理方式,这直接导致了不可预知的结果,例如,比特币和以太坊社区的分叉就是因为没有管理好这种主观共识导致的。在这些区块链的分叉过程中,区块生产者(矿工)扮演了重要的角色,他们根据自己的利益,而不是币持有者的利益,决定着区块链是否要分叉,为了避免这种情况,EOS系统实现了一种能够有效管理这种主观共识的方式,他能够通过控制区块生产者对系统的影响力来促进主观共识的达成。 3 | 4 | EOS认为区块链的权力应该来源于Token持有人,而不应该是区块生产者。区块生产者被授予有限和可控的权力去执行冻结账户,升级有缺陷的应用程序,对底层协议提出硬分叉的改进建议等功能。 5 | 6 | 对区块生产者的选举是集成在EOS系统中的,任何对区块链的变更都需要区块生产者的同意。如果区块生产者拒绝Token持有者想要的变更,那么他将被投票出局。如果区块生产者所实行的变更没有经过Token持有人的同意,那么其他非区块生产者的全节点(例如交易所)将会拒绝该改变。 7 | 8 | ## 冻结账户 9 | 有时智能合约可能会出现异常从而无法按照预期执行,有时应用或者账号将会出现导致资源消耗不在合理范围内的漏洞。当这些问题不可避免出现的时候,区块生产者有权力纠正这种情况。 10 | 11 | 任何区块链上的区块生产者都有权力选择哪些交易会被执行,因此他们也就有了冻结账号的权力,也就是说,当你要冻结某个账号的时候,你可以选择这个账号的所有交易拒不执行。EOS 系统直接支持这种账户冻结的能力,只要有21分之17的活跃区块生产者同意,就可以冻结某个账户。如果区块生产者滥用这种权力,它们将会被投票出局,被冻结的账户也会恢复。 12 | 13 | ## 变更账户代码 14 | 如果所有其他办法都无效,不受控制的应用已经造成了不可预料的后果的话,EOS 允许区块生产者可以直接替换账号的智能合约代码,这样可以避免整个区块的硬分叉。当然,这种代码替换操作也需要21分之17 的活跃区块生产者同意后才能执行。 15 | 16 | ## 宪法 17 | 像Facebook和Twitter这样的传统平台都有服务条款,这些条款规定了用户行为。这些服务条款也创建了一种“中枢辐射”模式,Facebook和Twitter是中枢,用户则是轮辐。而去中心化的平台应该有一个点对点的服务条款。 18 | 19 | EOS 系统就允许建立一个点对点的服务协议或用户签署的绑定合约,简称“宪法”。这份宪法的内容定义了仅仅依靠代码无法在用户间履行的义务,同时,通过建立司法权和法律选择以及其他相互接受的规则来加速争端的解决。每个在网络广播的交易都必须将宪法的哈希值作为签名的一部分,从而显性的将签名者绑定在合约中。 20 | 21 | 宪法还定义了人类能够理解的源码层协议的意图。当错误发生的时候,可以通过这个来区分哪些是真正的bug,哪些是系统的特性,从而能够帮助社区确定哪些修复是合适的,哪些是不合适的。 22 | 23 | ## 升级协议和宪法 24 | EOS 定义了升级协议和宪法的流程,具体如下: 25 | 26 | 1. 区块生产者提出对宪法的修改,并获得17/21的批准 27 | 2. 区块生产者连续30 天保持17/21的批准 28 | 3. 所有的用户都需要使用新宪法的hash来对交易进行签名 29 | 4. 区块链生产者通过变更代码的方式来影响宪法,并提交一个git记录的哈希值。 30 | 5. 区块生产者连续30 天保持17/21的批准 31 | 6. 对代码的更改会在7天以后生效,在正式批准元代码之后给予所有完整节点一周的时间升级。 32 | 7. 所有未升级为新版本代码的节点都将自动的关闭 33 | 34 | 按照EOS的默认配置,对区块链添加新特性需要2~3个月的时间,而修复一般的,无需修改宪法的bug需要1~1个月时间。 35 | 36 | ## 紧急变更 37 | 当系统出现严重的bug或安全漏洞时候,区块生产者可以加速软件更新的流程。当然,如果更新仅仅是因为一些不太严重的bug或为了增加新功能,这就不应该进行加速处理,否则就违反了宪法的章程。 38 | 39 | ## links 40 | * [目录]() 41 | * 上一章: [带宽](<08.0.md>) 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /04.1.md: -------------------------------------------------------------------------------- 1 | # 通证模型和资源使用 2 | 所有区块链的资源都是有限的,系统需要防止这些资源被滥用。使用EOS作为底层区块链系统的应用,一般都会使用到以下三种资源: 3 | 4 | 1. 带宽和存储(Disk)资源 5 | 2. 计算和计算积压(所谓积压,就是积累下来等待处理的任务) 6 | 3. 状态存储(主要保存在RAM中) 7 | 8 | 带宽和计算资源的使用有两种方式,瞬时使用和长期的使用。区块链对所有的消息都进行了日志记录,这些日志最终被下载和保存在所有的全节点(Full nodes)中。由于是全部消息的日志,这些日志能够帮助恢复所有应用的状态。 9 | 10 | 计算债务是一种必须通过消息日志重新构建状态的计算,如果可计算债务增长变得臃肿,则有必要通过快照方式记录区块链状态,并丢弃区块链历史。如果可计算债务增长过快,则它需要花费6个月时间来重放一年的交易,这很不可取,因此,可计算债务需要被细心管理。 11 | 12 | 区块链状态存储信息是可以在应用逻辑中被访问的。它包括诸如挂单和账户余额等信息。如果某个状态信息从来都不会被应用逻辑所读取,那它就不应该被存储在区块链上。例如,博客发布的内容和评论无需被应用逻辑读取,所以他们就不应该存储在区块链中,但是,发布和评论是否存在,投票的数量,以及其他的一些属性则需要被存储为区块链的状态。 13 | 14 | 区块生产者对外发布他们可用的带宽,计算和状态信息。EOS.IO 允许账户根据EOS币持有比例来消耗相应的资源。例如,如果账号中持有通证(Token)总发行量的1%,则这个账号就可以使用1%的状态存储空间。 15 | 16 | 带宽和计算资源是短暂的,未使用的部分也没有办法保存下来以供将来使用,但同时,也要控制他们被某些应用消耗完毕,因此,采用的策略是在保留的基础上进行分配。其具体算法与Steem(Steamit, EOS项目CTO 的前一个项目)中带宽速率限制算法类似。也就是说对于这种瞬时资源,如果你持有1%的通证,那么你最少可以使用1%的资源,如果系统比较空闲,则你可以使用的更多,如果系统非常繁忙,那么系统至少可以保证1% 的资源是专门分配给你的。 17 | 18 | ## 客观和主观度量 19 | 如前所属,检测计算使用量对性能和优化的影响很大;因此,所有资源的约束最终都是主观的,根据区块生产者各自的算法和评估来执行。 20 | 21 | 也就是说,这里还有一些事情很容易进行客观的衡量,例如,消息发送的数量和数据存储空间就很容易客观衡量。EOS系统允许区块生产者对这些能够客观衡量的因素实行统一的算法进行分配,而对于必须主观衡量的因素则选择更严格的主观算法。 22 | 23 | ## 接收方付费 24 | 传统上来说,企业为办公场地,计算力和其他为了运行企业而需要的成本买单。客户从企业购买具体的产品,产品销售产生的利润来支付运营的成本。同样的,没有那个网站强制他的访问者为其网站访问成本买单,因此,去中心化应用也不应该因为用户使用了区块链而强制他们付费。 25 | 26 | 使用EOS软件搭建的区块链项目也不会要求用户为其使用区块链而买单,而是允许企业制定更适合自己产品的收费策略。 27 | 28 | ## 委托能力 29 | EOS币的持有者未必是开发者,可能不会立即使用链上的资源,他们可以把这些资源出租给其他需要使用的用户,区块链生产者能够识别这样的授权,并相应的分配资源。通过这个设计,EOS的持有者就可以通过出租通证(Token)来得到持续的盈利。 30 | 31 | ## 分离交易成本与通证(Token)价值 32 | 使用EOS的一个主要的好处在于,应用所能使用的带宽资源仅和其持有的通证(Token)数量有关系,而和通证(Token)价格没有关系。如果应用开发者持有一定数量的通证,则它就能够在固定的状态和带宽下无限期的使用下去。在这种情况下,开发者和用户不受通证(Token)市值波动的影响。也就是说,区块链生产者会自发的提升每个通证(Token)可用的带宽,计算和存储资源,而不用考虑通证(Token)的价值。 33 | 34 | EOS区块链每次产生区块的时候都会奖励区块生产者Token,Token的价值将影响生产者能够购买的带宽,存储和计算量。这个模型自然会利用上升的Token价值来提升网络的性能。 35 | 36 | ## 状态存储成本 37 | 带宽和计算虽然可以通过委托的方式租用,但应用程序状态的存储要求开发人员持有通证(Token),直到该状态被删除。如果状态从未被删除,则通证(Token)不能进行流通。 38 | 39 | 每一个用户账户都需要一定数量的存储,因此,每个账号必须保存一个最小的余额。随着网络存储能力的不断提升,这个最小余额数量将会减少。 40 | 41 | ## 块奖励 42 | EOS系统在每次创建新区块的时候都会奖励区块生产者一些通证(Token),在这种情况下,产生的通证(Token)数量由所有区块生产者公布的期望收益的中值所决定。EOS系统可以配置限定区块生产者回报的上限,从而确保通证(Token)的每年增长比例不会超过5%。 43 | 44 | ## 社区受益应用 45 | 除了选举区块生产者,用户还可以选取3个社区受益应用(也就是智能合约)。这三个应用每年能够获取一定的通证(Token)奖励,其数额等于配置的通证(Token)供应量减去区块生产者的所得。在这三个应用之间,则根据用户对其投票来决定通证(Token)分配比例。并且,这三个应用并非固定不变的,当用户选择出新的应用时,这三个应用将被新应用替换。 46 | 47 | 这条策略应该是对EOS区块链上好的应用予以奖励,从而能够吸引更多的好应用移植到EOS上,推进EOS 生态的发展和完善。 48 | 49 | ## links 50 | * [目录]() 51 | * 上一章: [Token](<04.0.md>) 52 | * 下一节: [共识算法](<05.0.md>) 53 | 54 | -------------------------------------------------------------------------------- /02.2.md: -------------------------------------------------------------------------------- 1 | # 钱包密钥 2 | 在上一章中我们介绍了钱包中其实保存的就是密钥信息,在本章中我们具体介绍这些密钥是如何生成的。 3 | 4 | ### 私钥 5 | #### 私钥的重要性 6 | 私钥非常重要,可以说你账户的安全性就是通过私钥保证的。如果其他人知道了你的私钥信息,则他可以对你的EOS 账号进行任何操作。在大部分区块链系统中,如果丢失了私钥,就意味着丢失了私钥所对应的账户余额信息,你是无法通过其他方式找回的,因此网上提供了很多热备份,冷备份,硬件备份等私钥备份方案。在EOS系统中,虽然存在着账号恢复的手段,但私钥泄密后,账户上的余额也随时可能会被转走,因此,妥善保管私钥是保存区块链数字资产的关键。 7 | 8 | #### 私钥的生成 9 | 那私钥到底是什么东西?其实它就是一个数字,是一个由256位的二进制组成的数字。这个数字是随机产生出来的,随机产生的目的是为了避免出现重复。既然是256个二进制数据,那产生方式就有很多了,如果你足够有耐心,甚至可以通过抛掷256次硬币的方式来产生,将硬币的正反面转换为0和1,由此得到一个256位的二进制数字。其本质是在1~2^256之间选择一个数字。计算机的实现一般是通过一个密码学安全的随机源中取出一长串随机字节,对其使用SHA256哈希算法进行运算,这样就可以方便的产生一个256位的数字。 10 | 私钥在EOS中的保存是使用WIF(Wallet Import Format)格式的,这种格式广泛的应用在钱包之间密钥的输入和输出。WIF还有一个压缩版本的格式,所谓的压缩主要是用来区分其公钥是否进行压缩,在区块链交易过程中,公钥大量被使用,因此对其压缩可以缩减交易的字节数。 11 | #### 私钥不同格式的转换 12 | 通过以上介绍,你已经了解了三种私钥的形式,他们分别是256位二进制格式,WIF未压缩格式和WIF压缩格式,他们之间如何相互转换? 13 | 14 | 假设随机生成的私钥如下: 15 | 16 | ``` 17 | P = 0x9B257AD1E78C14794FBE9DC60B724B375FDE5D0FB2415538820D0D929C4AD436 18 | ``` 19 | 20 | 添加前缀0x80 21 | 22 | ``` 23 | WIF = Base58(0x80 + P + CHECK(0x80 + P) + 0x01) 24 | = Base58(0x80 + 25 | 0x9B257AD1E78C14794FBE9DC60B724B375FDE5D0FB2415538820D0D929C4AD436 + 26 | 0x36dfd253 + 27 | 0x01) 28 | ``` 29 | 其中CHECK表示两次sha256哈希后取前四个比特。前缀0x80表示私钥类型,后缀0x01表示公钥采用压缩格式,如果用非压缩公钥则不加这个后缀。WIF格式的私钥的首字符是以“5”,“K”或“L”开头的,其中以“5” 开头的是WIF未压缩格式,其他两个是WIF压缩格式。 30 | 31 | #### 加密私钥 32 | 正应为私钥在区块链中格外的重要,因此促进了加密私钥标准BIP0038 的出台,该标准能够被众多不同的钱包和比特币客户端理解,实现私钥的加密。 33 | 34 | BIP0038 加密方案是:输入一个私钥,使用WIF对私钥进行编码,此外,让用户再输入一个长密码作为口令,通常是由多个单词或者一段复杂的数字字母字符串组成。通过加密之后,最终得到的结果是一个加密私钥,前缀为6P。 35 | 36 | 因此,当你看到了一个以6P开头的密钥,说明该密钥被加密过,需要一个口令来将其转换为WIF格式的私钥。 37 | 38 | ### 公钥 39 | 公钥的设计就是为了在网络中传输的,它可以保证使用者即便没有私钥,仍然可以通过公钥证明交易就是公钥所对应的账号产生的。其重要的三个特性如下: 40 | 41 | 1. 公钥是由私钥计算出来的,使用公钥加密的数据,私钥可以解码 42 | 2. 公钥无法逆向计算出私钥 43 | 3. 用私钥计算的签名,可以通过公钥进行验证 44 | 45 | #### 公钥的生成 46 | 在椭圆加密算法(ECC)流行之前,绝大多数的公钥加密算法都是使用RSA,DSA这些基于模运算的替代加密系统,这些加密算法在今天依然占据非常重要的位置。但相比于这些算法,椭圆加密算法有其特殊的优势: 47 | 48 | 1. 安全性能更高, 如160位ECC与1024位RSA,DSA有相同的安全强度 49 | 2. 计算量小,处理速度快,在私钥的处理速度上(解密和签名),ECC远比RSA,DSA快得多 50 | 3. 存储空间占用小,ECC的密钥尺寸和系统参数与RSA,DSA相比要小得多 51 | 4. 带宽要求低使得ECC具有广泛的应用前景 52 | 53 | 因此,区块链的公钥生成算法一般都使用了椭圆加密算法,EOS也不例外。 54 | 55 | 椭圆曲线的定义非常简单,满足下面公式的所有(x,y)坐标的集合,就是我们所说的椭圆曲线: 56 | 57 | `y² mod p = (x³ + 7) mod p` 58 | 59 | 上面的公式中,mod 是取余符号,而 P 是一个很大的素数。因此公钥的几何意义,其实就是椭圆曲线上的一个点,由一对坐标(x,y)组成。公钥通常表示为前缀04紧接着两个256比特的数字。04是类型标记,表示无压缩公钥。之后的两个256位分别对应着x和y坐标,共计65字节。 60 | 61 | 而公式中的P 取不同素数的时候,椭圆曲线会呈现出完全不同的形态,P越大,这个椭圆也就越大,可承载的数值范围也就越大,冲突率会降低,乃至于更安全,所以出于安全性考虑,比特币中采用的是一个特定的椭圆曲线,我们叫它spec256k1,它是由NIST(National Institute of Standards and Technology)这个组织确定的。spec256k1所选取的P有多大呢? 我们可以看一下: 62 | 63 | ``` 64 | p = 115792089237316195423570985008687907853269984665640564039457584007908834671663 65 | ``` 66 | 67 | 根据P 的选取,椭圆曲线相当于被定义在一个素数阶的有限域内,而不是定义在实数范围,他的函数图像看起来像分散在两个维度上的散点图。针对曲线上的点,我们可以定义加法和乘法运算,而公钥的产生正是使用了乘法运算,如下: 68 | 69 | ``` 70 | {K = priv * G} 71 | ``` 72 | 其中priv是随机生成的私钥,G是椭圆曲线上的某一个点,而K 则是生成的公钥。G这个点称作生成点,它是spec256k1标准的一部分,可以认为是规定的一个固定的值。因此,根据私钥priv就可以生成公钥K,priv 和K 之间的关系是固定的,但只能单向运算,即从priv得到K。 73 | 74 | 75 | #### 公钥的格式 76 | 公钥常见的有两种格式,一种是未压缩格式公钥,另一种是压缩格式公钥。引入压缩格式公钥是为了减少区块链交易的字节数。其中,未压缩格式公钥使用04作为前缀,之后是两个256比特,分别对应椭圆曲线点的x和y坐标,示例如下: 77 | 78 | ``` 79 | x = 97FCFAA24237514FD4C00A33491F835D7D019DE4E9CEB0E24916371BAE329E62 80 | ``` 81 | 82 | ``` 83 | y = 2260575B83A1542D93418DABBBE65109B4E27A1A0737B2FD980698C3D0188839 84 | ``` 85 | 86 | 则未压缩的公钥表示为: 87 | 88 | ``` 89 | K = 0x0497FCFAA24237514FD4C00A33491F835D7D019DE4E9CEB0E24916371BAE329E622260575B83A1542D93418DABBBE65109B4E27A1A0737B2FD980698C3D0188839 90 | ``` 91 | 92 | 以上公钥共需65个字节来表示。 93 | 94 | 由于公钥就表示椭圆曲线上的一个点,我们从椭圆曲线的公式可以看到,在已知x 的情况下,我们可以求算出y 的两个解,在实数域它们显然是一正一负两个值;而在spec256k1椭圆曲线上则是一奇一偶两个数。那么只需记录x坐标和y的奇偶性(而不是y本身),这样我们就能砍掉近一半的空间表示同样的公钥,如下: 95 | 96 | ``` 97 | K' = 0x0397FCFAA24237514FD4C00A33491F835D7D019DE4E9CEB0E24916371BAE329E62 98 | ``` 99 | 这个K'被称为压缩公钥,首字节是0x02(对应偶数y)或0x03(对应奇数y),公计33字节。 100 | 101 | ### EOS 公钥 102 | 103 | ## links 104 | * [目录]() 105 | * 上一节: [钱包工具](<02.1.md>) 106 | * 下一章: [EOS账号](<03.0.md>) -------------------------------------------------------------------------------- /01.3.md: -------------------------------------------------------------------------------- 1 | # 1.3 EOS案例分析 2 | EOS 项目在建构了一套去中心化的可信网络的同时,提供的最重要的功能就是智能化合约,智能合约能够使用一种透明的方式来转移和交换资金或财产,而不需要通过中间人,接下来我们就一起通过一个案例分析下如何在EOS上建立智能合约。 3 | 4 | ## 运行EOS节点 5 | 智能合约是在EOS节点中运行的,因此要首先把EOS节点运行起来,在这里,我们运行一个本地节点,命令如下: 6 | 7 | ``` 8 | cd path-to-eos/build/programs/eosiod/ 9 | ./eosd 10 | ``` 11 | 12 | ## 创建默认钱包 13 | - 创建钱包 14 | 由于智能合约是与账号相关联的,因此在创建智能合约前,我们首先要创建账号,而账号的Key需要通过钱包来创建和保存,因此需要先创建钱包,如下: 15 | 16 | ``` 17 | cd path-to-eos/build/programs/eosioc/ 18 | ./eosioc wallet create # Outputs a password that you need to save to be able to lock/unlock the wallet 19 | ``` 20 | 上面的命令会创建一个名称为default 的默认钱包,在创建钱包时,你也可以指定名称。钱包对应的密码需要保存,后续操作钱包状态的时候需要使用。 21 | 22 | - 导入测试账号的Private key 23 | 钱包创建好之后,还不能直接创建账号,每个账号的创建需要一个Creator账号,在这里,我们使用`genesis.json`中的 `inita`账号作为Creator账号。作为Creator的账号,必须要把它的`Private key`导入到钱包中,否则在创建其他账号时,会提示权限不够,命令如下: 24 | 25 | ``` 26 | ./eosioc wallet import 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3 27 | ``` 28 | 29 | 30 | ## 创建账号 31 | ### 创建账号所需的key 32 | 每个账号的创建都需要`owner_key` 和`active_key` 两个key,我们通过以下命令创建key: 33 | 34 | ``` 35 | cd path-to-eos/build/programs/eosioc/ 36 | ./eosioc create key # owner_key 37 | ./eosioc create key # active_key 38 | ``` 39 | 40 | 以上命令会分别输出两组 `private key` 和 `public key`,如下: 41 | 42 | ``` 43 | Private key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 44 | Public key: EOSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 45 | ``` 46 | **千万保存好以上的key,后续需要使用**。 47 | 48 | ### 创建账号 49 | 创建账号的所有准备都已经齐备,现在可以开始创建账号了,账号创建的命令如下: 50 | 51 | ``` 52 | ./eosioc create account inita currency PUBLIC_KEY_1 PUBLIC_KEY_2 53 | ``` 54 | 在以上命令中,创建的当前账号名称为`currency`,创建当前账号的`Creator` 账号指定为 `inita`, 最后的两个`public key` 分别对应`currency`账号的 `owner_key`和`active_key`。当账号创建成功后,你将得到一个附带 `transaction ID`的 `JSON`反馈。 55 | 56 | 如果你之前没有导入过`inita`账号的`private key`,则会出现如下错误提示: 57 | /Screen Shot 2018-02-21 at 10.36.38 PM.png 58 | 59 | 这主要是因为以上这条命令必须要有`inita`的`active`权限才能执行,如果没有导入私钥,则权限不够,从而会给出以上错误提示。 60 | 61 | 你也可以通过查询此账户的信息来确认账号是否创建成功: 62 | 63 | ``` 64 | ./eosioc get account currency 65 | ``` 66 | 以上命令将会返回如下结果: 67 | 68 | ``` 69 | { 70 | "account_name": "currency", 71 | "eos_balance": "0.0000 EOS", 72 | "staked_balance": "0.0001 EOS", 73 | "unstaking_balance": "0.0000 EOS", 74 | "last_unstaking_time": "2035-10-29T06:32:22", 75 | ... 76 | ``` 77 | 78 | `currency`账号已经创建成功,但你目前还不能使用此账号进行智能合约等操作,因为系统中目前只有此账号的`public key`,而进行交易和智能合约等操作需要用到此账号的`active`权限,因此,我们需要把此账号对应的`active private key`导入到系统中,如下: 79 | 80 | ``` 81 | ./eosioc wallet import XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 82 | ``` 83 | 请使用你之前创建的`active private key` 替代以上命令中的 `xxx` 字符串。 84 | 85 | ## 部署智能合约 86 | ### 准备工作 87 | 在上传以前,首先确认`currency`账号下是没有智能合约的 88 | 89 | ``` 90 | ./eosioc get code currency 91 | code hash: 0000000000000000000000000000000000000000000000000000000000000000 92 | ``` 93 | ### 部署智能合约 94 | 上传智能合约到currency 账号,此处的智能合约是EOS系统自带的测试合约 95 | 96 | ``` 97 | ./eosioc set contract currency ../../contracts/currency/currency.wast ../../contracts/currency/currency.abi 98 | ``` 99 | 当你得到一个带有`transaction_id`字段的JSON反馈后,说明智能合约已经上传成功。你还可以通过以下命令来验证合约是否上传成功。 100 | 101 | ``` 102 | ./eosioc get code currency 103 | ``` 104 | 以上命令应该会返回这样的结果: 105 | 106 | ``` 107 | code hash: 9b9db1a7940503a88535517049e64467a6e8f4e9e03af15e9968ec89dd794975 108 | ``` 109 | 110 | ### 发行货币 111 | 在使用`currency`智能合约以前,你首先要发行货币,以下命令将向`currency`中发行10,000,000 的货币 112 | 113 | ``` 114 | ./eosioc push action currency issue '{"to":"currency","quantity":"1000.0000 CUR"}' --permission currency@active 115 | ``` 116 | 通过以下命令可以验证 currency 账号中目前确实已经有 10,000,000 的余额了 117 | 118 | ``` 119 | ./eosioc get table currency currency account 120 | { 121 | "rows": [{ 122 | "currency": 1381319428, 123 | "balance": 10000000 124 | } 125 | ], 126 | "more": false 127 | } 128 | ``` 129 | 130 | ### 转账 131 | 任何账号都可以在任何时间向任何智能合约发送消息,但如果权限不够的话,智能合约会拒绝消息的执行。更加准确的来说,消息并不一定是从某个账号发出来的,只要这条消息所关联的账号和权限等级是满足的,这条消息就能被执行。以下命令展示了如何向`currency`账号发送`transfer`消息,在这条命令中,需要从`currency`账号转账到其他账号,因此,需要`currency`账号权限才能完成此操作,具体命令如下: 132 | 133 | ``` 134 | ./eosioc push action currency transfer '{"from":"currency","to":"inita","quantity":"20.0000 CUR","memo":"my first transfer"}' --permission currency@active 135 | ``` 136 | 137 | 上面这条命令中,出现了三次`currency`, 第一次出现表示的是智能合约`currency`,第二次出现表示的转账账号`currency`,第三次出现则表示`currency`账号的权限; 如果我们换一个其他转出账号,则比较通用的命令格式应该如下: 138 | 139 | ``` 140 | ./eosioc push action currency transfer '{"from":"${usera}","to":"${userb}","quantity":"20.0000 CUR","memo":""}' --permission ${usera}@active 141 | ``` 142 | 以上命令是从usera 向userb转账,因此权限上面需要使用usera 的权限。此命令中`currency`只出现了一次,在这里表示智能合约的名称。 143 | 144 | ## links 145 | * [目录]() 146 | * 上一节: [EOS运行](<01.2.md>) 147 | * 下一节: [小结](<01.4.md>) 148 | 149 | -------------------------------------------------------------------------------- /03.1.md: -------------------------------------------------------------------------------- 1 | # 权限管理 2 | ## 基于角色的权限管理 3 | 所谓权限管理,简单的来说就是判定某条消息是否被正确的授权,此处的消息泛指EOS中一切调用,包括交易和对智能合约的调用。在区块链中,比较常见的一种权限管理方式是判定一笔交易是否包含有效的签名,比特币中每笔交易都会做类似的判定,这种权限管理方式属于很简单的一种类型,它的审查范围是针对每笔交易,没有细化到账号级别,并且在这类判定中,操作所需权限(签名)都是已知的,而在实际情况中,权限一般都会绑定到账号或者多人账号级别,并且账号所拥有的权限和操作所需要的权限是分别控制的,EOS 提供的这种声明式的权限系统可以在账户级别提供细粒度和高纬度的控制,它可以有效的管理什么账号可以在什么时间做什么事情。 4 | 5 | 认证和权限管理必须标准化,并且与应用程序的业务逻辑分开,这样可以通过开发工具以通用的方式来管理权限,并且为性能优化提供可能。 6 | 7 | 每个账号都能被其他多个账号和私钥按照权重组合进行控制,这就创造了一种分层级的权限结构,它真实反映了现实中的权限分配方式,并且让多用户共同管理资产变得从未如此简单。这种多账户控制机制,能对账户的安全性提供保障,减少被黑客攻击而造成的资金损失风险。EOS甚至还允许定义某种多账户和私钥的组合可以发送特定的消息类型给另外一个账号。举个例子,可以指定一个密钥给一个用户的社交媒体账号,同时另一个密钥访问交易所。甚至可以授权其他账号来代表本账号而无需把自己的密钥分配给他们。 8 | 9 | ## 命名的权限级别 10 | EOS 中每个账号都会有两个固有的命名权限,如下: 11 | 12 | - `owner` 13 | `owner` 表示账户的所有权(是账户最高权限),此权限能够对账号做所有的操作,甚至可以重新恢复那些已经被泄漏的权限,一般只有很少的操作需要此权限。通常情况下,建议你把此权限对应的私钥进行冷存储,不要把它与任何人分享。 14 | - `active` 15 | `active`权限可以用来进行转币,投票和其他的一些高级别的操作。 16 | 17 | 除了系统固有的这两种命名权限外,账号还可以添加定制的命名权限来扩充账号管理功能,并且这种权限可以从更高级别的命名权限继承。每一个命名权限都支持多重签名阀值校验,其中的多重签名可以包含密钥和/或其他账户的命名权限级别。 18 | 19 | 针对上面所说的权限级别,这里举一个例子。在Steem区块链应用中,包含了三个硬编码的命名权限级别,分别是`owner`, `active`和`posting`, `posting` 权限只能进行如投票和发帖的社交活动,`active`权限可以做除了变更拥有之外的所有操作。`owner`权限则可以做包括冷存储在内的所有的事情。 20 | 21 | ## 命名的消息处理群组 22 | EOS允许账号可以根据命名的嵌套群组来定义其消息处理函数。这个命名的消息处理群组可以在其他账号配置他们权限级别时被引用。 23 | 24 | 最高级别的消息处理群组是账户名称,最低级别的是一个账户所接收到的单独的消息类型,这个群组可以被这样引用: 25 | `@accountname.groupa.subgroupb.MessageType` 26 | 27 | 在这样的模型下,交易所合约可以通过将挂单的创建和取消分组,从而与充值提现分离开。交易所合约的这种分组对用户而言带来了方便。 28 | 29 | ## 签名 30 | ### 单签(默认账户配置) 31 | 账号在创建的时候,默认会有两个权限,分别是`owner` 和`active`,每个权限对应一套密钥(一个公钥,一个私钥),每套密钥对应的权重都是1,权限的验证阀值也是1,因此消息的授权只需要某一个权限的单独签名即可,如下: 32 | 33 | | Permission | Account | Weight | Threshold | 34 | |:--|:--|:--|:--| 35 | | owner | | | 1 | 36 | | | EOS5EzTZZQQxdrDaJAPD9pDzGJZ5bj34HaAb8yuvjFHGWzqV25Dch | 1 | | 37 | | active | | | 1 | 38 | | | EOS61chK8GbH4ukWcbom8HgK95AeUfP8MBPn7XRq8FeMBYYTgwmcX | 1 | | 39 | 40 | 在以上@bob账号中,bob的`owner`的权限权重是1,交易签名所需要的授权阀值也是1,因此当bob需要发送交易消息的时候,只需要使用owner的key对交易消息进行签名即可通过验证。 41 | 42 | ### 多签与定制权限 43 | 以下我们虚构一个需要多签名的账户@multisig. 在这个场景中,@multisig 账号的`owner`和`active`权限分别有需要两个账户的授权,`publish`权限则需要三个签名,包括两个账户和一个`key`,并且这三个签名的权重是不一样的,具体如下: 44 | 45 | | Permission | Account | Weight | Threshold | 46 | |:--|:--|:--|:--| 47 | | owner | | | 2 | 48 | | | @bob | 1 | | 49 | | | @stacy | 1 | | 50 | | active | | | 1 | 51 | | | @bob | 1 | | 52 | | | @stacy | 1 | | 53 | | publish | | | 2 | 54 | | | @bob | 2 | | 55 | | | @stacy | 2 | | 56 | | | EOS7Hnv4iBWo1pcEpP8JyFYCJLRUzYcXSqtQBcEnysYDFTEbUpi6y | 1 | | 57 | 58 | 在以上场景中,由于`owner`的权限阀值是2,而`owner`权限下的两个账号的权重都是1,因此,当需要对交易消息进行签名的时候,需要这两个账号同时授权才可以。 59 | 60 | 如果所发送的交易消息需要`active`权限,由于此权限的阀值是1,这就意味着只需要`active`权限下任何一个账号授权就可以了。 61 | 62 | 这里还有一个自定义的命名权限叫做`publish`, 此权限的阀值是2,而其下的账号@bob和@stacy的权重都是2,另外一个key的权重是1,这就意味着@bob和@stacy都可以独立的进行签名,而key则需要另外一个签名一起才可以进行授权。 63 | 64 | 在以上案例中,权限的设置同时使用了**账号**和**key** 的形式,这种形式初看起来觉得意义不大,但其实引入了一种非常灵活的维度。 65 | 66 | ## 权限映射 67 | 命名权限级别和消息处理群组这两个概念之间可以做映射,也就是说,可以将某个消息处理群组分配到某个权限级别上。举个例子:一个账户所有者可以将自己社交媒体应用与自己的“朋友”权限群组建立映射,有了这个映射,任何朋友都可以以这一账户的身份在社交媒体上发帖,但尽管他们能够以账户所有者的身份发帖,他们仍然使用自己的密钥来签名消息,这意味着总可以辨别出是哪一个朋友在以何种方式使用账户。 68 | 69 | ## 评估权限 70 | 当@alice发送一条类型为“Action”的消息给@bob 时,EOS首先会检查是否存在一条@alice权限和@bob.groupa.subgroup.Action操作之间的映射,如果没有找到,会继续检查@bob.groupa.subgroup与@alice权限之间是否存在映射,然后是@bob.groupa,最后@bob将被检查,如果都没有找到,那么就假定映射为命名权限@alice.active。 71 | 一旦某个映射被识别,则通过阀值多签名流程验证权限是否有效,如果失败了,则会找寻其父权限,直至拥有者权限@alice.owner. 72 | 73 | ![evaluating permission](images/3.1.eval-perm.png?raw=true) 74 | 75 | 请看以上事例,图中@USER是一个账户,@EXCHANGE.CONTRACT是个交易所智能合约。@USER账号对应着一组权限,分别是`OWNER`, `ACTIVE`, `FAMILY`, `FRIENDS`,`LAWYER`,其中`OWNER`,`ACTIVE`为EOS提供的账号固有权限,其他则为自定义的权限。他们之间有继承关系,`FRIENDS`权限是继承自`FAMILY`的。 76 | 77 | @EXCHANGE.CONTRACT 智能合约中定义了一些消息类型,其中`WITHDRAW MESSAGE`和`TRADE GROUP`是平行的消息类型,`BUY`,`SELL`,`CANCEL`消息都是挂在`TRADE GRAOUP`下的。 78 | 79 | 图中@User 把交易所智能合约的消息类型和账户的权限做了映射,`CONTRACT`及其下的`TRADE` 类型的消息映射到`FAMILY`权限下,此处相当于在`FAMILY`权限下有两个映射。`WITHDRAW`类型的消息映射到`LAWYER`权限下面,这样的映射形成了如下规则: 80 | 81 | 1. `FRIENDS`权限下能够做的做的事情,`FAMILY`权限都可以做,因为它是`FRIENDS`的父权限 82 | 2. `FAMILY`权限可以发送除`WITHDRAW`消息外其他任何消息,这是因为`WITHDRAW`消息在其他权限下做了特殊的映射,`FAMILY`权限无法覆盖此消息 83 | 3. `LAWYER`权限可以发送`WITHDRAW`消息,但无法发送其他消息 84 | 85 | 当用户向智能合约发送`BUY`消息的时候,系统会按照如下规则判断权限是否符合: 86 | 87 | 1. 判断是否有 @exchange.contract.buy 和账号权限映射,如果有,直接返回对应的权限,如果没有,则继续 88 | 2. 判断是否有 @exchange.contract 和账号权限映射,如果有,直接返回对应的权限,如果没有,则直接返回 @active 权限 89 | 3. 判断消息所附带的授权是否能够满足消息所需要的权限 90 | 91 | ## 并行权限评估 92 | 由于权限评估的过程是只读的,并且交易执行对权限的变更在一个区块结束之前是不会起作用的,这就意味着: 93 | 94 | 1. 所有的权限评估都是可以并行执行的 95 | 2. 无需再启动一个可能会引起回滚的高成本的应用逻辑去实现快速的权限验证,并行权限验证已经是一种快速解决方案了 96 | 3. 当收到需要等待的交易(pending transactions)时,系统可以直接对其进行权限评估,而无需等到此交易在执行时再被评估,这样可以节约交易执行时间 97 | 98 | 并且,由于权限验证的操作占据了验证类交易计算量的很大比例,因此,权限评估过程的只读和并发执行的特性将会使整体性能有一个质的飞跃。 99 | 100 | ## links 101 | * [目录]() 102 | * 上一节: [EOS 账号](<03.0.md>) 103 | * 下一节: [消息和处理程序](<03.2.md>) 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /01.2.md: -------------------------------------------------------------------------------- 1 | # 1.2 EOS 运行 2 | EOS 安装完毕后,就可以运行EOS 程序了。目前支持三种方式的运行,分别是: 3 | 4 | - 本地私有节点运行 5 | 在本地局域网中部署EOS节点,提供EOS服务,节点可以单个,也可以部署多节点 6 | - 在测试公网下运行 7 | Block.One 公司提供了测试的公网环境,你可以使自己部署的节点连接公网测试环境 8 | - Docker 中运行 9 | 10 | ## 本地私有节点运行 11 | EOS为了能够方便开发者测试,目前在公网环境下部署了一套测试网络。如果你部署的节点不与这套公网测试环境连接,那就成为本地私有节点部署。在进行本地部署的时候,可以只部署单一节点,也可以部署多个节点,下面我们会分别介绍这两种情况: 12 | 13 | ### 单节点的部署与运行 14 | 当成功编译项目后,就可以在`build/programs/eosiod` 目录下运行程序了。调用`eosiod` 命令可以运行EOS 节点程序,当你第一次运行时,很有可能会出现错误而停止运行,不管是否出现错误,都通过 `Ctrl-C` 停止程序,你需要先对程序做一些配置后,系统才能真正运行。当第一次运行程序后,会自动生成 `data-dir` 目录,里面包含了默认的配置文件(`config.ini`)和一些其他文件。你需要对配置文件做如下的修改: 15 | 16 | - 添加创世纪的block 17 | `genesis-json = /path/to/eos/genesis.json` 18 | 19 | - 在测试链上设置producers,并通过他们生产区块 20 | 21 | ``` 22 | producer-name = inita 23 | producer-name = initb 24 | producer-name = initc 25 | producer-name = initd 26 | producer-name = inite 27 | producer-name = initf 28 | producer-name = initg 29 | producer-name = inith 30 | producer-name = initi 31 | producer-name = initj 32 | producer-name = initk 33 | producer-name = initl 34 | producer-name = initm 35 | producer-name = initn 36 | producer-name = inito 37 | producer-name = initp 38 | producer-name = initq 39 | producer-name = initr 40 | producer-name = inits 41 | producer-name = initt 42 | producer-name = initu 43 | ``` 44 | - 加载区块生产插件,从而系统可以生产区块 45 | `plugin = eosio::producer_plugin` 46 | - 加载钱包插件,从而支持钱包服务 47 | `plugin = eosio::wallet_api_plugin` 48 | - 加载RPC和API插件,从而可以通过这两种接口访问EOS服务 49 | 50 | ``` 51 | plugin = eosio::chain_api_plugin 52 | plugin = eosio::http_plugin 53 | ``` 54 | 55 | 再次运行 `eosiod` 命令,当你看到如下日志的时候,说明你已经成功启动EOS服务了。 56 | 57 | ``` 58 | 1575001ms thread-0 chain_controller.cpp:235 _push_block ] initm #1 @2017-09-04T04:26:15 | 0 trx, 0 pending, exectime_ms=0 59 | 1575001ms thread-0 producer_plugin.cpp:207 block_production_loo ] initm generated block #1 @ 2017-09-04T04:26:15 with 0 trxs 0 pending 60 | 1578001ms thread-0 chain_controller.cpp:235 _push_block ] initc #2 @2017-09-04T04:26:18 | 0 trx, 0 pending, exectime_ms=0 61 | 1578001ms thread-0 producer_plugin.cpp:207 block_production_loo ] initc generated block #2 @ 2017-09-04T04:26:18 with 0 trxs 0 pending 62 | ... 63 | ``` 64 | 65 | ### 部署多节点网络 66 | 在你EOS项目的 `build/programs/eosio-launcher` 目录下,有一个专门用于EOS节点启动的应用,名称为 `eosio-launcher`,下面的命令运行了两个可以相互交互的节点: 67 | 68 | ```sh 69 | cd ~/eos/build 70 | cp ../genesis.json ./ 71 | ./programs/eosio-launcher/eosio-launcher -p2 --skip-signature 72 | ``` 73 | 74 | 上面的命令将会建立两个数据目录,每个节点对应其中一个目录,目录名称分别是:`tn_data_00` 和`tn_data_01` 75 | 76 | 你可以在命令行终端中看到如下的日志输出, 日志表示系统生成了两个子进程,每个进程对应一个运行节点: 77 | 78 | ``` 79 | spawning child, programs/eosiod/eosiod --skip-transaction-signatures --data-dir tn_data_0 80 | spawning child, programs/eosiod/eosiod --skip-transaction-signatures --data-dir tn_data_1 81 | ``` 82 | 83 | 为了进一步验证这两个节点确实在正常运行,你可以使用`eosioc`客户端工具分别连接这两个节点,如下: 84 | 85 | ``` 86 | cd path-to-eos/build/programs/eosioc 87 | ./eosioc -p 8888 get info 88 | ./eosioc -p 8889 get info 89 | ``` 90 | 上面的两条`eosioc` 分别连接两个节点,可以看到,这两个节点端口号分别是8888和8889,连接后,调用 `get info`命令,获取到不同节点的区块链信息。 91 | 92 | ## 在测试公网下运行 93 | Block.One 为测试人员和开发者提供了公网测试环境,如果你已经在本地体验过EOS节点的运行,希望能够在公网下测试你的代码,那你可以把本地的EOS节点连接到公网环境,具体操作如下: 94 | 95 | ``` 96 | cd path-to-eos/build/scripts 97 | ./start_npnode.sh 98 | ``` 99 | 100 | 系统编译后,会生成`start_npnode.sh` 脚本文件,此脚本其实也是调用了`eosd`程序,不过其使用的默认数据目录参数是`testnet_np`,此目录的`config.ini`文件中的设置了公网环境下p2p节点的连接地址,因此,程序启动后就会直接与公网进行连接了,这也是连接公网环境和在私有链下运行的主要区别,这行配置如下: 101 | `p2p-peer-address = p2p-testnet1.eos.io:9876` 102 | 103 | `p2p-testnet1.eos.io`这个域名就指向Block.One 公网环境的一个节点。`start_npnode.sh` 命令运行后,可以得到如下日志输出: 104 | 105 | ``` 106 | Launched eosd. 107 | See testnet_np/stderr.txt for eosd output. 108 | Synching requires at least 8 minutes, depending on network conditions. 109 | ``` 110 | 111 | 如果希望了解节点运行和同步的具体情况,可以运行如下命令查看: 112 | 113 | ``` 114 | tail -F testnet_np/stderr.txt 115 | ``` 116 | 117 | 当连接公网环境时,节点首先需要从公网中同步已有的区块链数据,这需要一定的时间,当你看到如下日志信息的时候,说明数据正在同步: 118 | 119 | ``` 120 | 3439731ms chain_plugin.cpp:272 accept_block ] Syncing Blockchain --- Got block: #200000 time: 2017-12-09T07:56:32 producer: initu 121 | 3454532ms chain_plugin.cpp:272 accept_block ] Syncing Blockchain --- Got block: #210000 time: 2017-12-09T13:29:52 producer: initc 122 | ``` 123 | 124 | 当同步全部完成后,你将看到如下的信息: 125 | 126 | ``` 127 | 42467ms net_plugin.cpp:1245 start_sync ] Catching up with chain, our last req is 351734, theirs is 351962 peer ip-10-160-11-116:9876 128 | 42792ms chain_controller.cpp:208 _push_block ] initt #351947 @2017-12-12T22:59:44 | 0 trx, 0 pending, exectime_ms=0 129 | 42793ms chain_controller.cpp:208 _push_block ] inito #351948 @2017-12-12T22:59:46 | 0 trx, 0 pending, exectime_ms=0 130 | 42793ms chain_controller.cpp:208 _push_block ] initd #351949 @2017-12-12T22:59:48 | 0 trx, 0 pending, exectime_ms=0 131 | ``` 132 | 133 | ## Docker 中运行 134 | 135 | ## links 136 | * [目录]() 137 | * 上一节: [EOS安装](<01.1.md>) 138 | * 下一节: [EOS案例分析](<01.3.md>) -------------------------------------------------------------------------------- /01.1.md: -------------------------------------------------------------------------------- 1 | # 1.1 EOS 安装 2 | 目前EOS 项目主要支持两类系统,分别是Ubuntu 和 MacOS Sierra,本地的EOS安装,目前有三种形式,你可以根据自己的喜好进行选择。 3 | 4 | - 下载安装包:从Dawn3.0 版本,项目直接提供了安装包,方便开发人员安装 5 | - 通过自动化安装脚本安装:项目提供了自动安装脚本,脚本会安装所需要的依赖库,并编译EOS项目 6 | - 手动安装:手动安装依赖库,并编译源代码。 7 | 8 | ## 下载安装包 9 | 从3.0 版本以后,EOS项目根据平台发布了可供直接下载安装的安装包,你可以通过[此链接](https://github.com/EOSIO/eos/releases)进行下载。目前最新的版本是3.0.1。 10 | 11 | ## 通过自动化脚本安装 12 | 针对于Ubuntu 16.10 和MacOS Sierra系统,EOS项目设置了自动化安装脚本,你可以通过此脚本自动安装项目所依赖的库并编译EOS代码。脚本放在EOS代码的根目录下,文件名称为eosio-build.sh,此脚本有两个参数,分别如下: 13 | 14 | - architecture [ubuntu|darwin] 15 | 此参数描述操作系统平台,目前只支持ubuntu 和mac 系统 16 | - optional mode [full|build] 17 | 如果参数为full,脚本会先下载所依赖的库,然后再进行编译。如果没有填写此参数,默认情况下是full 18 | 19 | 命令格式如下: 20 | ```./eosio-build.sh ``` 21 | 22 | 完整的自动化脚本安装命令如下: 23 | 24 | ``` 25 | 1) git clone https://github.com/eosio/eos --recursive 26 | 27 | 2) cd eos 28 | 3) ./eosio_build.sh ubuntu 29 | ``` 30 | 31 | 以上代码具体解释如下: 32 | 33 | - 第一行是从github 上Copy EOS代码到本地; 34 | - 第二行代码进入到 EOS主目录; 35 | - 第三行代码是切换到dawn-2.x 分支上;目前github 上主分支下是3.0 的代码,但是测试公网上是2.x 的代码,因此,如果你只是希望搭建一个本机版本,则无需切换到2.x分支,但如果是希望能够链接测试公网的话,需要切换到2.x 分支下。后续等测试公网上版本也全部切换到3.0 之后,就无需再执行这句代码了。 36 | - 第四行代码是运行自动部署脚本。如果你本机是ubuntu 系统,则第一个参数是ubuntu,如果是在mac 上编译,则需要把此参数修改为darwin 37 | 38 | ## 手动安装 39 | EOS 项目的主要开发语言是C++,采用的是C++14 标准,编译系统使用CMake,项目编译所需要的依赖库如下: 40 | 41 | - Clang 4.0.0 42 | - CMake 3.5.1 43 | - Boost 1.64 44 | - OpenSSL 45 | - LLVM 4.0 46 | - [secp256k1-zkp (Cryptonomex branch)](https://github.com/cryptonomex/secp256k1-zkp) 47 | - [binaryen](https://github.com/WebAssembly/binaryen) 48 | 49 | ### Ubuntu 16.10 安装 50 | 安装开发工具包: 51 | 52 | ``` 53 | sudo apt-get update 54 | wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add - 55 | sudo apt-get install clang-4.0 lldb-4.0 libclang-4.0-dev cmake make \ 56 | libbz2-dev libssl-dev libgmp3-dev \ 57 | autotools-dev build-essential \ 58 | libbz2-dev libicu-dev python-dev \ 59 | autoconf libtool git 60 | ``` 61 | 62 | 安装Boost 1.64 63 | 64 | ``` 65 | cd ~ 66 | wget -c 'https://sourceforge.net/projects/boost/files/boost/1.64.0/boost_1_64_0.tar.bz2/download' -O boost_1.64.0.tar.bz2 67 | tar xjf boost_1.64.0.tar.bz2 68 | cd boost_1_64_0/ 69 | echo "export BOOST_ROOT=$HOME/opt/boost_1_64_0" >> ~/.bash_profile 70 | source ~/.bash_profile 71 | ./bootstrap.sh "--prefix=$BOOST_ROOT" 72 | ./b2 install 73 | source ~/.bash_profile 74 | ``` 75 | 76 | 安装[secp256k1-zkp (Cryptonomex branch)](https://github.com/cryptonomex/secp256k1-zkp): 77 | 78 | ``` 79 | cd ~ 80 | git clone https://github.com/cryptonomex/secp256k1-zkp.git 81 | cd secp256k1-zkp 82 | ./autogen.sh 83 | ./configure 84 | make 85 | sudo make install 86 | ``` 87 | 88 | 安装WASM 编译器[binaryen](https://github.com/WebAssembly/binaryen): 89 | 90 | ``` 91 | cd ~ 92 | git clone https://github.com/WebAssembly/binaryen.git 93 | cd ~/binaryen 94 | git checkout tags/1.37.14 95 | cmake . && make 96 | ``` 97 | 98 | 把 BINARYEN_ROOT环境变量添加到 .bash_profile文件中: 99 | 100 | ``` 101 | echo "export BINARYEN_ROOT=~/binaryen" >> ~/.bash_profile 102 | source ~/.bash_profile 103 | ``` 104 | 105 | 默认情况下LLVM 和 Clang 是不支持WASM 编译的,可以通过以下命令编译支持版本: 106 | 107 | ``` 108 | mkdir ~/wasm-compiler 109 | cd ~/wasm-compiler 110 | git clone --depth 1 --single-branch --branch release_40 https://github.com/llvm-mirror/llvm.git 111 | cd llvm/tools 112 | git clone --depth 1 --single-branch --branch release_40 https://github.com/llvm-mirror/clang.git 113 | cd .. 114 | mkdir build 115 | cd build 116 | cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=.. -DLLVM_TARGETS_TO_BUILD= -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly -DCMAKE_BUILD_TYPE=Release ../ 117 | make -j4 install 118 | ``` 119 | 120 | 编译环境已经设置完毕,可以进行[EOS代码编译](####EOS代码编译)了; 121 | 122 | ### MacOS Sierra 10.12.6 安装 123 | Mac 上安装依赖库前需要安装另外两个软件: 124 | 125 | - Brew 126 | > 安装命令如下: 127 | > ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 128 | - 最新版本的 XCode 129 | > 安装命令如下: 130 | > xcode-select --install 131 | 132 | 安装依赖库: 133 | 134 | ```sh 135 | brew update 136 | brew install git automake libtool boost openssl llvm@4 gmp ninja gettext 137 | brew link gettext --force 138 | ``` 139 | 140 | 安装[secp256k1-zkp (Cryptonomex branch)](https://github.com/cryptonomex/secp256k1-zkp): 141 | 142 | ```sh 143 | cd ~ 144 | git clone https://github.com/cryptonomex/secp256k1-zkp.git 145 | cd secp256k1-zkp 146 | ./autogen.sh 147 | ./configure 148 | make 149 | sudo make install 150 | ``` 151 | 152 | 安装 [binaryen v1.37.14](https://github.com/WebAssembly/binaryen): 153 | 154 | ```sh 155 | cd ~ 156 | git clone https://github.com/WebAssembly/binaryen.git 157 | cd ~/binaryen 158 | git checkout tags/1.37.14 159 | cmake . && make 160 | ``` 161 | 162 | 把 BINARYEN_ROOT环境变量添加到 .bash_profile文件中: 163 | 164 | ``` 165 | echo "export BINARYEN_ROOT=~/binaryen" >> ~/.bash_profile 166 | source ~/.bash_profile 167 | ``` 168 | 169 | 默认情况下LLVM 和 Clang 是不支持WASM 编译的,可以通过以下命令编译支持版本: 170 | 171 | ```sh 172 | mkdir ~/wasm-compiler 173 | cd ~/wasm-compiler 174 | git clone --depth 1 --single-branch --branch release_40 https://github.com/llvm-mirror/llvm.git 175 | cd llvm/tools 176 | git clone --depth 1 --single-branch --branch release_40 https://github.com/llvm-mirror/clang.git 177 | cd .. 178 | mkdir build 179 | cd build 180 | cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=.. -DLLVM_TARGETS_TO_BUILD= -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly -DCMAKE_BUILD_TYPE=Release ../ 181 | make -j4 install 182 | ``` 183 | 184 | 添加环境变量 `WASM_LLVM_CONFIG` 和 `LLVM_DIR` 到 `.bash_profile`: 185 | 186 | ```sh 187 | echo "export WASM_LLVM_CONFIG=~/wasm-compiler/llvm/bin/llvm-config" >> ~/.bash_profile 188 | echo "export LLVM_DIR=/usr/local/Cellar/llvm/4.0.1/lib/cmake/llvm" >> ~/.bash_profile 189 | source ~/.bash_profile 190 | ``` 191 | 192 | 编译环境已经设置完毕,可以进行[EOS代码编译](####EOS代码编译)了; 193 | 194 | ### EOS代码编译 195 | #### 下载项目代码 196 | 获取EOS 项目代码,命令如下: 197 | 198 | ```sh 199 | git clone https://github.com/eosio/eos --recursive 200 | ``` 201 | 202 | 如果调用以上命令是忘记输入 `--recursive` 参数的话,可以调用以下命令下载所有子模块代码: 203 | 204 | ```sh 205 | git submodule update --init --recursive 206 | ``` 207 | 208 | #### 编译代码 209 | 在编译前,请确保 `WASM_LLVM_CONFIG` 环境变量已经设置了 WASM 编译器,智能合约的编辑需要用到此编辑器。完整的下载和编译命令如下: 210 | 211 | ```sh 212 | cd ~ 213 | git clone https://github.com/eosio/eos --recursive 214 | mkdir -p ~/eos/build && cd ~/eos/build 215 | cmake -DBINARYEN_BIN=~/binaryen/bin -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -DOPENSSL_LIBRARIES=/usr/local/opt/openssl/lib .. 216 | make -j4 217 | ``` 218 | 219 | 编译完成后,在 `~/eos/build/programs` 目录下,会生成以下几个执行文件: 220 | 221 | - eosiod : 服务器端区块链节点组件,各EOS节点运行此程序,构建一个去中心化的服务网络 222 | - eosioc : 客户端命令行程序,通过 RPC 连接 eosiod 223 | - eosiowd : EOS 钱包 224 | - eosio-launcher : 区块链节点网络的配置和部署 225 | 226 | ## links 227 | * [目录]() 228 | * 上一节: [EOS简介](<01.0.md>) 229 | * 下一节: [EOS运行](<01.2.md>) --------------------------------------------------------------------------------