## 区块链领域最具人气的平台以太坊 文/汪晓明 ### 以太坊是什么? 以太坊是一个全新开放的区块链平台,它允许任何人在平台中建立和使用通过区块链技术运行的去中心化应用。就像比特币一样,以太坊不受任何人控制,也不归任何人所有——它是一个开源项目,由全球区块链爱好者共同创建。和比特币协议有所不同的是,以太坊的设计十分灵活,极具适应性。 #### 比特币 vs 以太坊 如果对比特币和以太坊,一个形象的比喻是计算器和智能手机,计算器只有一些内置的加减乘除功能,智能手机可以安装实现各种功能的 App。因此,比特币会在金融支付等特定领域发挥价值,而以太坊可以为各行各业提供解决方案。 ### 以太坊发展历史回顾 2013年末以太坊创始人 Vitalik Buterin 第一次描述了这个项目,作为他研究比特币的成果。不久后,Vitalik 发表了以太坊白皮书,书中详细描述了以太坊协议的技术设计和基本原理,以及智能合约的结构。2014年1月,Vitalik 在美国佛罗里达州迈阿密举行的北美比特币会议上正式宣布了以太坊。 与此同时,Vitalik 开始和 Gavin Wood 博士合作共同实现以太坊。2014年4月,Gavin 发表了以太坊黄皮书,作为以太坊虚拟机的技术说明。按照黄皮书中的具体说明,以太坊客户端已经有8种编程语言实现。 从2014年6月开始,以太坊借助42天公开的以太币预售活动对第一批以太币进行了分配,共筹集31591个比特币,当时价值1843万美元,交换出大约6000万以太币。众筹所得主要用于回报开发者们数月以来的努力,以及资助以太坊的持续开发。这笔资金为以太坊后续的发展提供了充足的的资金保证。 经过两年的快速发展,在以太坊平台上创立新的应用十分简便,随着 Homestead 的发布,任何人都可以安全地使用该平台上的应用。 ### 以太坊核心概念之虚拟机(EVM) 以太坊是可编程的区块链。它并不是给用户一系列预先设定好的操作(例如比特币交易),而是允许用户按照自己的意愿创建复杂的操作。这样一来,它就可以作为多种类型去中心化区块链应用的平台,包括加密货币在内,但并不仅限于此。 以太坊狭义上是指一系列定义去中心化应用平台的协议,它的核心是以太坊虚拟机 Ethereum Virtual Machine(EVM),可以执行任意复杂算法的编码。在计算机科学术语中,以太坊是“图灵完备的”。开发者能够使用现有的以 JavaScript 和 Python 等语言为模型的其他友好的编程语言,创建出在 EVM 上运行的应用。熟悉JVM的同学很好理解,EVM 就是一个程序运行的容器。 和其他区块链一样,以太坊也有一个点对点网络协议。以太坊区块链数据库由众多连接到网络的节点来维护和更新。每个网络节点都运行着EVM并执行相同的指令。因此,人们有时形象地称以太坊为“世界电脑”。 ### 以太坊如何工作? 以太坊合并了对比特币用户来说熟悉的特征和技术,同时自己也进行了修正和创新。比特币区块链纯粹是一个关于交易的列表,而以太坊的基础单元是账户。以太坊区块链跟踪每个账户的状态,所有以太坊区块链上的状态转换都是账户之间价值和信息的转移。账户分为两类: 1. 外部账户(EOA),由私钥控制; 2. 合约账户,由它们的合约编码控制,只能由外部账户“激活” 对于大部分用户来说,两者基本的区别在于外部账户是由人类用户掌控——因为他们能够控制私钥,进而控制外部账户。而合约账户则是由内部编码管控。如果他们是被人类用户“控制”的,那也是因为程序设定它们被具有特定地址的外部账户控制,进而被持有私钥控制外部账户的人控制着。“智能合约”这个流行的术语指的是在合约账户中编码——交易被发送给该账户时所运行的程序。用户可以通过在区块链中部署编码来创建新的合约。 只有当外部账户发出指令时,合约账户才会执行相应的操作。所以合约账户不可能自发地执行诸如任意数码生成或应用程序界面调用等操作——只有受外部账户提示时,它才会做这些事。这是因为以太坊要求节点能够与运算结果保持一致,这就要求保证严格确定执行。 和比特币一样,以太坊用户必须向网络支付少量交易费用。这可以使以太坊区块链免受无关紧要或恶意的运算任务干扰,比如分布式拒绝服务(DDoS)攻击或无限循环 。交易的发送者必须在激活的“程序”每一步付款,包括运算和记忆储存。费用通过以太坊自有的有价代币,以太币的形式支付。 交易费用由节点收集,节点使网络生效。这些“矿工”就是以太坊网络中收集、传播、确认和执行交易的节点。矿工们将交易分组(包括许多以太坊区块链中账户“状态”的更新),分成的组被称为“区块”,矿工们会互相竞争,以使他们的区块可以添加到下一个区块链上。矿工们每挖到一个成功的区块就会得到以太币奖励。这就为人们带来了经济激励,促使人们为以太坊网络贡献硬件和电力。 和比特币网络一样,矿工们有解决复杂数学问题的任务以便成功地“挖”到区块,这被称为“工作量证明(POW)”。一个运算问题如果在算法上解决比验证解决方法需要更多数量级的资源,那么它就是工作证明的极佳选择。为防止比特币网络中已经发生的,专门硬件(例如特定用途集成电路 ASIC)造成的中心化现象,以太坊选择了难以存储的运算问题。如果问题需要存储器和 CPU,事实上理想的硬件是普通的电脑。这就使以太坊的工作量证明具有抗特定用途集成电路性,和比特币这种由专门硬件控制挖矿的区块链相比,能够带来更加去中心化的安全分布。 ### 以太坊基础使用指南 以太坊上线之前计划的初始开发路线图主要有以下几个里程碑: 1. 预发布:Olympic testnet —— 2015年5月 2. 发布第一版:Frontier —— 2015年7月30日 3. 发布第二版: Homestead —— 2016年3月14日(π日) 4. 发布第三版: Metropolis —— 预计2017年上半年 5. 发布第四版:Serenity——未知 通过本节可以获取用户参与以太坊项目中的基本方法。首先,要想成为网络中的节点,需要运行一个以太坊客户端。 #### 以太坊客户端的选择与安装 为什么有多个以太坊客户端? 以太坊客户端与 Java 虚拟机和 .NET 运行环境类似,能够让你在电脑上运行“以太坊程序”。以太坊客户端按照书面说明(黄皮书)执行,可以彼此协作,因此,你可以使用 Go、C++、Java 等熟悉的语言来参与以太坊网络。 项目早期,在众多不同的操作系统中就有多个可以彼此协作的客户端实现,客户端的多样性对于整个生态系统来说是巨大的成功。它使我们能够证明协议是明确清晰的,为后续创新打开了空间,也让我们都保持诚实。但是对终端用户来说,没有通用的“以太坊安装程序”可供他们使用,可能引起他们的困惑。 进入到 Homestead 阶段以后,Go 客户端占据了主导地位,但情况并不一直是这样,将来也说不定。除了 EthereumH,其他客户端都有 Homestead 兼容的版本。目前有8种客户端:C++、Go、Python、Java、JavaScript、Haskell、Rust、Ruby。 ### 公有链、联盟链、私有链介绍 当今大多数以太坊项目都选择了以太坊公有链,公有链可以接触到更多用户、网络节点、货币和市场。但有些领域则更偏好私有链或联盟链(在一群值得信任的参与者中)。例如,银行、保险领域的很多公司都希望以太坊作为他们私有链的平台。 三种区块链在许可方面的区别: 1. 公有链:所有人都可以阅读和发送交易,合法信息都会被包括在内。任何人都能参与到共识形成过程——决定在链条上添加什么区块以及现状是怎样的。作为中心化或准中心化信任的替代品,公有链受加密经济的保护,加密经济是经济激励和加密验证的结合,用类似工作量证明或权益证明的机制,遵循的总原则是人们影响共识形成的程度与他们能够影响的经济资源数量成正比。这类区块链通常被认为是“完全去中心化”。 2. 联盟链:共识形成过程由预先选择的一系列的节点所掌控,例如,设想一个有15个金融机构的团体,每个机构都操作一个节点,为了使区块生效,其中的10个必须签署那个区块。阅读区块链的权利可能是公开的,或仅限于参与者,也有混合的路径,比如区块的根哈希和应用程序编程接口一起公开,使公共成员可以进行一定量的查询,重获一部分区块链状态的加密证明。这类区块链被认为是“部分去中心化”。 3. 私有链:写入权限对一个组织保持中心化。读权限可能是公开的或者限制在任意程度。应用很可能包含对单个公司内部的数据库管理,审查等,因此公共的可读性在很多情况下根本不必要,但在另一些情况下人们又想要公共可读性。 在未来的区块链行业解决方案领域,联盟链可能会扮演很重要的角色。 ### 以太坊账户管理 账户在以太坊中发挥着中心作用。前面我们讲了共有两种账户类型:外部和合约账户。这里重点讲一下外部账户,以下会简称为账户。如果我们把以太坊限制为只有外部账户,只允许外部账户之间进行交易,我们就会进入到“代币”系统,这样就类似于一个比特币网络。 #### 钥匙文件 每个账户都由一对钥匙定义,一个私钥和一个公钥。 账户以地址为索引,地址由公钥衍生而来,取公钥的最后20个字节。每对私钥和地址都编码在一个钥匙文件里。钥匙文件是 JSON 文本文件,可以用任何文本编辑器打开和浏览。钥匙文件的关键部分是账户私钥,通常用你创建帐户时设置的密码进行加密。钥匙文件可以在以太坊节点数据目录的 keystore 子目录下找到,一定要确保经常给钥匙文件备份。 创建钥匙和创建帐户是一样的,在此过程中: 1. 不必告诉任何人你的操作 2. 不必和区块链同步 3. 不必运行客户端 4. 不必连接到网络 当然新账户不包含任何以太币,但它将会是你的,大可放心,没有你的钥匙和密码,没有人能进入。转移备份整个目录或任何以太坊节点之间的个人钥匙文件都是安全的。 #### 创建账号 ##### 使用 geth account new 一旦安装了 geth 客户端,创建账号就只在终端执行 geth account new 指令就可以了。 注意不必运行 geth 客户端或者和区块链同步来使用 geth account 指令。 ``` $ geth account new Your new account is locked with a password. Please give a password. Do not forget this password. Passphrase: Repeat Passphrase: Address: {168bc315a2ee09042d83d7c5811b533620531f67} ``` **警告:记住密码并“备份钥匙文件 ”。你必须同时有钥匙文件和密码才能从账号发送交易,包括发送以太币。确保钥匙文件有个备份并牢记密码,尽可能安全地存储它们。如果钥匙文件丢失或忘记密码,就会丢失所有的以太币。没有密码不可能进入账号,也没有忘记密码选项,所以一定不要忘记密码。** 要列出目前在你的 keystore 文件夹中的钥匙文件的所有账号,使用 geth account 指令的 list 子指令: ``` $ geth account list account #0: {a94f5374fce5edbc8e2a8697c15331677e6ebf0b} account #1: {c385233b188811c9f355d4caec14df86d6248235} account #2: {7f444580bfef4b9bc7e14eb7fb2a029336b07c9d} ``` ##### 使用 geth 控制台 也可以通过控制台创建新账号,我们必须先在控制台模式开启 geth ``` > geth console 2>> file_to_log_output ``` 控制台使你能够通过发出指令与本地节点互相作用。比如,试一下这个列出账号的指令: ``` > eth.accounts { code: -32000, message: "no keys in store" } ``` 这就表明你没有账号。你可以从控制台创建一个账号: ``` > personal.newAccount() Passphrase: Repeat passphrase: "0xb2f69ddf70297958e582a0cc98bce43294f1007d" ``` 我们刚刚创建了第一个账号。如果再次试着列出账号,就可以看到新创建的账号了。 ``` > eth.accounts ["0xb2f69ddf70297958e582a0cc98bce43294f1007d"] ``` ### 案例演示:通过命令行做转账操作 安装完以太坊客户端,就可以使用命令了,以 Go 语言客户端为例。 查看帮助命令: ``` geth -h ``` 列出账户: ``` geth account list ``` 指定目录启动一个节点: ``` geth --datadir "~/ethdev" —dev ``` 进入控制台: ``` geth --dev console 2>> file_to_log_output ``` 列出账户: ``` > eth.accounts ``` 指定密码为123456,创建一个账户 ``` > personal.newAccount('123456') > eth.accounts ``` 创建第二个账户 ``` > personal.newAccount('123456') > eth.accounts ``` 取出第一个账户,赋值给 user1 ``` > user1 = eth.accounts[0] ``` 取出第二个账户,赋值给 user2 ``` > user2 = eth.accounts[1] ``` 查看 user1 初始余额 ``` > eth.getBalance(user1) 0 ``` 查看 user2 初始余额 ``` > eth.getBalance(user2) 0 ``` 查看当前区块号 ``` > eth.blockNumber 0 ``` 启动挖矿 ``` > miner.start() ``` 查看当前区块号 ``` > eth.blockNumber ``` 查看 user1 当前余额 ``` eth.getBalance(user1) ``` 查看 user2 当前余额 ``` eth.getBalance(user2) ``` 停止挖矿 ``` > miner.stop() ``` 查看当前区块号 ``` > eth.blockNumber ``` user1 转账给 user2(会报错,请看下一步) ``` > eth.sendTransaction({from: user1, to: user2, value: web3.toWei(3, "ether")}) ``` 转账涉及到资金支出,需要提供密码解锁转出账户 ``` > personal.unlockAccount(user1, "123456”) ``` 重新执行转账操作: ``` > eth.sendTransaction({from: user1, to: user2, value: web3.toWei(3, "ether")}) ``` 转账成功以后,查看 user1 和 user2 余额 ``` > eth.getBalance(user1) > eth.getBalance(user2) ``` 好了,一个完整的命令行转账功能就完成了。 ### 15分钟编写一个区块链 Web 应用:truffle 开发入门 以太坊是区块链开发领域最好的编程平台,而 truffle 是以太坊最受欢迎的一个开发框架。实战是最重要的事情,这一节不讲原理,只搭建环境,并运行一个区块链程序。 #### 安装 truffle ``` $ npm install -g truffle ``` #### 依赖环境 访问 https://nodejs.org 官方网站下载安装 NodeJS。 推荐 Mac OS 系统,不建议使用 Windows,会碰到各种各样的问题,导致放弃。 需要安装 Ethereum 客户端来支持 JSON RPC API 调用开发环境,推荐使用 EthereumJS TestRPC: https://github.com/ethereumjs/testrpc 安装命令: ``` $ npm install -g ethereumjs-testrpc ``` #### 新建第一个项目 ``` $ mkdir zhaoxi $ cd zhaoxi $ truffle init ``` 默认会生成一个 MetaCoin 的 demo,可以从这个demo中学习 truffle 的架构 项目一级目录结构如下: /Users/bob/workspace/zhaoxi/ → app/
→ contracts/
→ migrations/
→ test/ truffle.js 项目所有文件目录如下: /Users/bob/workspace/zhaoxi/ ↓ app/
↓ images/
↓ javascripts/
app.js
↓ stylesheets/
app.css
index.html
↓ contracts/
ConvertLib.sol
MetaCoin.sol
Migrations.sol
↓ migrations/
1 _ initial_migration.js
2 _ deploy_contracts.js
↓ test/
metacoin.js
truffle.js
#### 编译项目 ``` $ truffle compile bob@192 zhaoxi % truffle compile Compiling ConvertLib.sol... Compiling MetaCoin.sol... Compiling Migrations.sol... Writing artifacts to ./build/contracts ``` #### 部署项目 部署之前先启动 TestRPC ``` $ testrpc $ truffle deploy bob@192 zhaoxi % truffle migrate Running migration: 1_initial_migration.js Deploying Migrations... Migrations: 0x43d6a4e2196dcc73fe146edc73d2ebd8f15b5a7a Saving successful migration to network... Saving artifacts... Running migration: 2_deploy_contracts.js Deploying ConvertLib... ConvertLib: 0x57625b35460974b61c5e2862f1fcb463e2500b7b Linking ConvertLib to MetaCoin Deploying MetaCoin... MetaCoin: 0xd90058c2b73fa50403b1368d2f48c601576b8b40 Saving successful migration to network... Saving artifacts... ``` #### 启动服务 ``` $ truffle serve ``` 启动服务后,可以在浏览器访问项目: http://localhost:8080/ ,网页界面如图1所示。 图1  网页服务界面 图1 网页服务界面 好了,第一个 Web 区块链程序跑起来了,后面可以不断地实践深入学习了。 **** ##### 参考资料 以太坊官方网站:https://ethereum.org/
汪晓明的博客:http://wangxiaoming.com/
以太坊开发视频:http://ethcast.com/
以太坊爱好者:http://ethfans.org/