以太坊(Ethereum) Homestead 参考文档¶

这份参考文档是以太坊 社区 的志愿者们经年累月持续合作的产物。尽管还没有得到 以太坊基金会(The Ethereum Foundation) 的正式认证,我们仍然希望你发现它是很有用的,我们也衷心地欢迎新的 撰稿人(Contributors)。
这份中文版文档由 Rivers Yang 翻译制作。
目录¶
引言¶
以太坊是什么?¶
以太坊(Ethereum)是一个开放的区块链平台,可以让任何人都能够创建和使用基于区块链技术的去中心化应用程序。与比特币一样,没有人控制或拥有以太坊,它是一个由全世界的许多人所共通创建的开源项目。 不同于比特币的是,以太坊被设计成灵活的、可根据需求修改的模式。在以太坊平台上创建应用是很容易的,在Homestead这个版本中,所有人使用这些应用程序都已经很安全了。
下一代的区块链¶
区块链技术是比特币的基础技术,在神秘的作者中本聪(Satoshi Nakamoto)于2008年发表的的白皮书”Bitcoin: A Peer-to-Peer Electronic Cash System”中被首次描述。尽管在这篇最初的论文中已经提及了区块链技术的泛用性,但区块链作为通用术语出现,还是在几年之后的事。区块链是一个分布式的计算架构,每个网络节点都执行和记录同样的交易流水,这些流水数据被组织到所谓区块之中。在同一时间,只有一个区块可以被添加到区块链中;每个区块都包含一个数学证明,来证实它是在它之前的所有区块之后产生的。用这种方法,使区块链的“分布式数据库”在整个网络中达到共识。用户与账本(交易流水)的交互通过强大的加密方式保证其安全性。负责维持和校验整个网络状态的节点,将获得基于编码到协议中的经济学奖励算法计算得出的奖励。
对于比特币而言,分布式数据库被设想成通过比特币代币在账户间的转移来使个人用户间的去信任金融变为可能的一种账户结算表、账本和交易流水的集合。但随着比特币吸引了越来越多的开发者和技术专家,一些新奇的项目开始用比特币网络来做一些代币价值转移以外的工作。其中一些项目采用了”alt coins”的模式,通过改进原始的比特币协议形成自己的加密货币,从而将区块链分离以增加新的特性和功能。在2013年底,以太坊(Ethereum)的发明人Vitalik Buterin正式提出了一个设想,这是一个具有再编程能力的、用来执行任意复杂计算的单一区块链,可以将很多其他的项目纳入其内。
在2014年,以太坊(Ethereum)的创始人Vitalik Buterin, Gavin Wood和Jeffrey Wilcke就开始致力于构建下一代的区块链技术的工作,以实现一个通用的、完全去信任的智能合约平台(smart contract platform)。
以太坊虚拟机¶
以太坊是一个可编程的区块链。以太坊允许用户根据自己的设想创建任意复杂的操作,而不是只给用户一些预设好的操作(例如比特币的交易操作)。用这种方法,它成为了一个支撑许多不同类型的去中心化区块链应用的平台,包含但不仅限于加密货币。
狭义上说,以太坊是定义了去中心化应用平台的一套协议。其核心就是可以运行任意的复杂计算代码的 以太坊虚拟机(“EVM”)。用计算机科学术语来讲,以太坊是“图灵完备”的。开发者可以使用友好的编程语言在EVM上创建应用程序,比如使用JavaScript或Python。
与其他任何区块链一样,以太坊也包含一个P2P(peer-to-peer)网络协议。以太坊区块链数据库,由众多的连接到此网络的节点维护和更新。每个节点都会运行EVM并执行相同的操作序列。因此,以太坊有时也被形象的描述为“全球计算机”(“world computer”)。
这种跨越整个以太坊网络的超大规模并行计算,并不会使计算更加高效。事实上,这样的过程,使在以太坊上进行的普通的计算远比使用传统的“计算机”来的更慢、更昂贵。但是,由于每个以太坊节点都会运行EVM来在区块链上达成共识,这种去中心化的共识,也给了以太坊极致的容错性(fault tolerance)、零宕机时间(zero downtime)、使存储在区块链上的数据永远无法更改(forever unchangeable)和抗审查(censorship-resistant,即不怕审查,因为数据一直是真实的,无法篡改的,译者注)。
以太坊平台本身是无特性(featureless)或价值未知(value-agnostic)的。与编程语言一样,是企业家和开发者决定它应该用来做什么。然而根据以太坊本身的能力,某些特定的应用显然要比其他类型更能受益。具体来讲,以太坊 适合于那些旨在解决点到点之间直接交互,或者跨网络的团体协作问题的应用程序。 例如特定的点到点(peer-to-peer)交易市场应用,或者自动化的复杂金融合约应用等等。 比特币,允许个人在不引入任何中介,像金融机构、银行或政府的情况下进行货币交易。而以太坊的影响会更加深远。从理论上讲,任意复杂度的金融交互或交易(financial interactions or exchanges)都可以使用以太坊上的代码来自动化的、可靠的实现。而除金融应用以外,任何注重信任、安全、持久性的场合,比如资产注册、投票、管辖和物联网,都可以大范围的嵌入以太坊平台。
以太坊是如何运作的?¶
以太坊中包含了很多比特币用户很熟悉的特性和技术,同时它也引入了很多的修改和创新。
与比特币区块链中单纯的交易流水不同, 以太坊区块链中的基础单元是账户(account)。以太坊区块链跟踪每个账户的状态;以太坊区块链上的所有状态转换,都是账户间的价值或者信息的转移。以太坊中的账户有两种类型:
- 由私钥控制的外部账户(Externally Owned Account,即EOA)
- 由自身的合约代码控制的合约账户,这种账户只能由EOA“激活”(Activate)
对大多数用户来讲,它们最基础的区别就是人控制EOA,因为人能通过私钥控制EOA上的行为;而合约账户则由它们内部的代码来管理。对于合约账户,我们也可以说他们是有人“控制”的,因为他们 被编制为 由一个有特定地址的EOA所控制,而这个EOA则由掌握其私钥的“人”所控制。当一个交易发送到合约账户上时,合约账户中的特定代码会被触发并执行,这些代码即是通常意义上的“智能合约”。用户可以在区块链上发布代码来创建新的合约。
仅当合约账户接到一个EOA的指示的时候,它才会去执行一个操作。所以合约账户不可能去做一些自发的操作,比如生成随机数或调用API,除非被EOA指定去做。这是因为以太坊中的节点需要一个严格确定的执行确认,来认证外来的计算要求。
与比特币一样,用户为了完成一个交易,需要向网络支付小额的交易费。这个机制是用来保护以太坊网络不被一些无价值或恶意的计算任务所影响,比如DDoS攻击或者无限循环。交易的发送者必须为他们所激活的每一步“程序”支付相应的费用,包括计算和存储。这些费用是用一定量的以太坊原生代币——以太币来体现的。
这些交易费用,是由验证整个网络的节点们所收取的。这些以太坊网络中接受、传播、验证和执行交易的节点,即是所谓的“矿工”。包含了以太坊区块链中账户“状态”变动的所有交易信息,由矿工们归集到“区块”中,然后开始互相竞争,以使 他们自己产生的 区块成为区块链中的下一个区块。矿工每成功挖到一个矿(即把自己生成的区块添加到区块链上,译者注),都将获得奖励。这就是对那些为以太坊网络贡献硬件和算力的人的经济上的激励。
与比特币网络一样,矿工们想要成功“挖到”一个区块也需要解决一个复杂的数学问题。这就是被熟知的“工作量证明”(”Proof of Work”)。任何一个通过算法解决问题所消耗的资源大于验证结果所消耗的资源的计算问题,都是工作量证明的良好选择。为了弱化比特币网络中使用特定硬件(比如 ASICs,一种专门用于计算的集成电路硬件,译者注)所带来的中心化趋势,以太坊选择了一个强内存需求(memory-hard)的计算问题。如果解决一个问题就像需求CPU一样需求内存,那可以支撑的硬件会更趋近于通常的计算机。这使以太坊的工作量证明“抗ASIC”;并且与比特币的可能受制于特定硬件的挖矿过程相比,这种工作量证明更加有利于去中心化分布的安全性。
学习以太坊¶
[待续]
区块链和以太坊基础¶
- Explain bitcoin like I’m five - an excellent introduction to blockchain technology and bitcoin to the mildly techsavvy layperson.
- https://medium.com/@creole/7-a-simple-view-of-ethereum-e276f76c980b
- http://blog.chain.com/post/92660909216/explaining-ethereum
- Explain Ethereum to non-technical people Q&A on stackexchange
- Reddit threads on ELI5-ing Ethereum:
[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19]
图解资讯¶
如何使用这份指南?¶
Homestead版本¶
Homestead是以太坊平台的第二个主要版本,也是第一个产品级的发布。 它包含了很多协议和网络上的变动以支持未来的网络升级。以太坊的第一个版本,Frontier版本,本质上是一个beta版本,供开发者学习和体验并开始初步构建去中心化的应用和工具。
以太坊开发路线图中的里程碑¶
在以太坊上线前发表的 初始的开发路线图 指出了以下几个里程碑:
- 预发布 步骤 0: Olympic测试网络 - 2015年5月
- 发布 步骤 1: Frontier - 2015年7月30日
- 发布 步骤 2: Homestead - 2016年3月14日(圆周率日,Pi Day)
- 发布 步骤 3: Metropolis - 待定
- 发布 步骤 4: Serenity - 待定
尽管以上里程碑仍然有效,但它们的实质已经从某种程度上改变了。 Olympic测试网络 发现了很多重大改进点,于是 Frontier版本 在其后很快就发布了。而Homestead则是由beta产品阶段退出进入稳定版本的标志。Homestead已经被于2016年3月14日(圆周率日)左右产生的1,150,000号区块所自动引入了。
如果你正在运行一个已连接到网络的节点,你需要尽快升级到兼容Homestead版本的客户端。这些客户端可以在 以太坊客户端 找到。否则你将会在一个错误的分叉上终止,无法再与整个网络同步。
一旦以太坊区块链达到1,150,000号区块,以太坊网络将经历一次硬分叉来使以下几个重大变动生效。
Homestead硬分叉变动¶
以太坊从狭义上讲就是一组协议。Homestead包含几个向前兼容的协议变动,故而需要一次硬分叉。这些变动用它们特定的方式实现了 以太坊改进建议 包含以下几点:
- EIP 2:
- cost for creating contracts via a transaction is increased from 21000 to 53000. Contract creation from a contract using the
CREATE
opcode is unaffected. - transaction signatures whose s-value is greater than
secp256k1n/2
are now considered invalid - If contract creation does not have enough gas to pay for the final gas fee for adding the contract code to the state, the contract creation fails (ie. goes out-of-gas) rather than leaving an empty contract.
- Change the difficulty adjustment algorithm
- cost for creating contracts via a transaction is increased from 21000 to 53000. Contract creation from a contract using the
- EIP 7: DELEGATECALL: Add a new opcode,
DELEGATECALL
at0xf4
, which is similar in idea toCALLCODE
, except that it propagates the sender and value from the parent scope to the child scope, ie. the call created has the same sender and value as the original call. This means contracts can store pass through information while following msg.sender andmsg.value
from its parent contract. Great for contracts which create contracts but don’t repeat additional information which saves gas. See comments on EIP 7 - EIP 8: devp2p Forward Compatibility compliance with the Robustness Principle Changes to the RLPx Discovery Protocol and RLPx TCP transfer protocol to ensure that all client software in use on the Ethereum network can cope with future network protocol upgrades. For older versions of an Ethereum client, updates to the network protocol weren’t being accepted by older clients and would refuse communication if the hello packets didn’t meet expectations. This update means all future versions of the client will accept incoming network upgrades and handshakes.
这些变动有如下一些优点:
- EIP-2/1 eliminates the excess incentive to create contracts via transactions, where the cost is 21000, rather than contracts, where the cost is 32000.
- EIP-2/1 also fixes the protocol “bug” that with the help of suicide refunds, it is currently possible to make a simple ether value transfer using only 11664 gas.
- EIP-2/2 fixes a transaction malleability concern (not a security flaw, but a UI incovenience).
- EIP-2/3 creates a more intuitive “success or fail” distinction in the result of a contract creation process, rather than the current “success, fail, or empty contract” trichotomy
- EIP-2/4 eliminates the excess incentive to set the timestamp difference to exactly 1 in order to create a block that has slightly higher difficulty and that will thus be guaranteed to beat out any possible forks. This guarantees to keep block time in the 10-20 range and according to simulations restores the target 15 second blocktime (instead of the current effective 17s).
- EIP-7 makes it much easier for a contract to store another address as a mutable source of code and ‘’pass through’’ calls to it, as the child code would execute in essentially the same environment (except for reduced gas and increased callstack depth) as the parent.
- EIP-8 makes sure that all client software in use on the Ethereum network can cope with future network protocol upgrades.
参考资源: - Reddit discussion on Homestead Release - 以太坊改进建议(EIPs)
Web 3.0:一个去中心化应用的平台¶
Web 3.0,指的是一个像DNS、数字身份标识之类的核心互联网服务已经去中心化的、使人们可以通过与他人进行经济上的交往而紧密的结合起来的,新一代的互联网。而越来越多的事实使我们相信,像以太坊这样开放的、去信任的区块链平台,已经可以完美的适合作为去中心化的安全互联网,Web 3.0,的共享“后端”支撑平台了。
就像以太坊的开发者设想的那样,以太坊是一个空白的画布,可以使你用它创造任何你想要的东西。以太坊协议是抽象设计的,以便使核心特性可以随意的进行组合。 理论上讲,以太坊上的去中心化应用(dapp)项目,将借助以太坊区块链去创造那些先前不可能实现的、基于去中心化共识的新产品或服务。
也许对以太坊最合适的描述是将其视为一个生态系统:由各种各样的基础设施、代码和社区所共同支持的核心协议构成了以太坊项目。以太坊也可以被理解为使用它的那些项目的集合。 现在,像Augur、Digix、Maker和其他很多(参考 Dapps)备受瞩目的项目已经在以太坊上构建了起来。另外还有很多开发团队也已经创建了很多开源组件供人们使用。尽管这些组织是独立于以太坊基金会之外的、都有他们自己的目标,但他们毫无疑问的都已经从以太坊的生态系统中获益了。
进一步了解:
- Vitalik Buterin - TNABC 2015: https://www.youtube.com/watch?v=Fjhe0MVRHO4
- Gavin Wood - DEVCON 1 - Ethereum for Dummies: https://www.youtube.com/watch?v=U_LK0t_qaPo
- Ethereum London Meetup (best detailed here): https://www.youtube.com/watch?v=GJGIeSCgskc
智能合约¶
来自Alex:
你会加入某个陌生人的合约么?你会同意把钱借给埃塞俄比亚的某个农场主么?你会成为战乱地区的小众报纸的投资人么?你会花费精力写一个合法绑定的合约在互联网上申请5美元么?
回答显然是:不。其原因也很简单:一个合约,需要很多的基础设施来支撑。有时需要合约双方有互信的联系,有时需要依赖于一个合法的系统,乃至警察、律师的介入。
在以太坊中,你不再需要那么多其他的支持。如果合约中的所有要素都能被放到区块链中,那么他们就将进入一个去信任的环境,也将几乎不会花费任何成本。
原先那些不计其数的小型合约,因为没有经济上的可行性或者没有足够的法律保护,而使我们永远不能接受,现在它们有了实现的可能。但这并不是说要去考虑将我们现有的合约全都迁移到区块链上。
DAO(Decentralized Autonomous Organizations,即去中心化自治组织,译者注)¶
这里正好有个例子:想象你和你的朋友们共同拥有一个小业务。雇佣律师和会计师是很昂贵的,但信任一个单独的合伙人来监督账簿也是个令人紧张的因素(有时甚至是给别有用心的人提供机会)。严格的遵从一个系统,是比信任一个合伙人对账簿的监管更值得尝试的;然而,当系统中的协议没有被正确遵守的时候,就有了一种变相欺诈的倾向。
这时,使用一个由你的公司掌握的智能合约来解释所有资金的支出,就成为了一个很好的开端。这个智能合约可以被设定为仅当取得其大多数所有者的同意才能被支出。像这样的智能合约可以通过开源软件的方式轻易地获得,你甚至不需要去雇佣你自己的程序员去代替会计师或律师。
像这样的智能合约是可以直接度量的。几个年轻人可以透明的分配从他们经营的水吧中获得的收入;就像一个主权财富基金为其有资格的上亿成员发放资金一样透明。在这两种情况下,这种透明化的成本都不足1%。
以太坊的历史¶
最新的历史记述, 请参考 Taylor Gerring的博客 。
开端¶
作为Vitalik Buterin在比特币社区中工作和研究的成果,他在2013年底首次提出了以太坊的设想。不久之后他就发表了 以太坊白皮书。在文中他描述了以太坊协议和智能合约架构的技术设计和基本原理。 2014年1月,在美国佛罗里达州迈阿密举行的北美洲比特币会议上,Vitalik正式宣布了以太坊。
在那段时间,Vitalik也已经开始和Gavin Wood博士一起工作,共同创建以太坊。到2014年4月,Gavin发布了 以太坊黄皮书 ,也就是以太坊虚拟机(EVM)的技术手册。基于黄皮书的详尽说明,以太坊客户端已经有了7种编程语言的技术实现(C++, Go, Python, Java, JavaScript, Haskell, Rust),这也是使它成为了更加优秀的软件。
- Ethereum launches Cryptocurrency 2.0 network - Coindesk article of 2014 Jan on the beginnings
- Ethereum announcement on bitcointalk Vitalik’s original announcement to the bitcoin community. Forum thread with 5000 replies.
以太坊基金会和以太币的预售¶
除了为以太坊开发软件以外,发布新的加密货币和区块链的能力,需要巨大的持续工作来整合所需的资源使其启动和运转。为了启动一个由开发者、矿工、投资人和其他权益人所组成的巨大网络,以太坊宣布了对其基础货币单位-以太币的预售计划。管理预售资金所带来的法律和财务上的复杂性,也使相关法律实体的建立成为必然。2014年6月, 以太坊基金会 (Stiftung Ethereum) 在瑞士的Zug设立。
在2014年7月初,以太坊开始了为期42天的以太币公开预售以进行其初始分配;来自网络上的31,591比特币,当时价值18,439,086美元,被兑换为60,102,216以太币。 这笔销售资金被用来偿还合法的负债,补偿开发者为此前数月工作所进行的付出,并作为未来以太坊开发的财务支持。
- Launching the ether sale - original official announcement on the Ethereum blog
- Concise information-rich stats page about the presale by (since then inactive) Ether.Fund
- Overview: Ethereum’s initial public sale - Blogpost by slacknation - all stats about the ether presale
- Terms and Conditions of the Presale
ETH/DEV和以太坊的开发¶
伴随着以太币的成功预售,以太坊的开发也在一个非盈利组织ETH DEV的管理下正常化的开展了起来。Vitalik Buterin,Gavin Wood和Jeffrey Wilcke也作为该组织的三位总监来统一管理具体的开发工作。开发者对以太坊的兴趣在2014年间持续的增长,ETH DEV团队发布了一系列概念验证(PoC)版本供开发者社区进行评估。这些发布由ETH DEV团队频繁的发表在 以太坊博客 上,这也保持了以太坊前进的激情和动力。以太坊论坛和以太坊subreddit上与日俱增的回复量和用户基础也证实了这个平台对那些快速成长的专业开发者社区的吸引力。这种势头一直持续到现在。
开发者大会(DEVCON-0)¶
2014年11月,ETH DEV组织了 开发者大会(DEVCON-0),将全世界的以太坊开发者带到了德国柏林,一起探讨了以太坊技术的各种延伸应用。DEVCON-0上的很多的演讲和话题都成为了使以太坊更加可靠、安全和可伸缩的重要启蒙。总体而言,这次大会激励了开发者们为以太坊的正式发布继续工作。
DEVgrants计划¶
2015年4月 DEVgrants计划 公布。这是一个旨在为以太坊和基于以太坊的项目提供资金的计划。成百上千的开发者,已经在以太坊项目或相关开源项目上贡献了大量的时间和创意,这项计划就是用来支持和奖励他们的贡献的。这项计划直到今天依然在持续的操作,其资金也在2016年1月进行了补充。
Olympic测试网络、问题赏金和安全审计¶
在2014到2015年间,以太坊开发经历了一系列概念验证发布,直到第9个被称为Olympic的PoC开放测试网络。开发者社区 被邀请来测试网络的限制 ,一个大额的奖励基金也被分配出来奖励那些成功地用某种方式在网络上得到不同的数据记录或者中断了系统运行的行为。在Olympic发布一个月之后,官方公布了这个 奖励计划 。
2015年初, 以太坊赏金计划 启动。该计划为在以太坊软件的任意部分找到弱点的行为提供比特币的奖励。这对于以太坊的可靠性和安全性无疑是个很大的贡献,也从技术上给了以太坊社区很大的信心。这个赏金计划目前仍在执行并且没有终止计划。
以太坊安全审计,开始于2014年底并持续到了2015年上半年。以太坊邀请了多家第三方软件安全机构来对所有关键协议组件(以太坊虚拟机、网络和工作量证明)进行一个端到端的审计。这些审计发现了很多安全问题,经过反复的定位和测试解决,最终使以太坊变成了一个更为安全的平台。
- Olympic testnet prerelease - Vitalik’s blogpost detailing olympic rewards
- Olympic rewards announced - Vitalik’s blogpost detailing the winners and prizes
- Bug bounty program launch
- Ethereum Bounty Program website
- Least Authority audit blogpost - with links to the audit report
- Deja Vu audit blogpost
以太坊Frontier发布¶
以太坊Frontier网络于2015年7月30日发布,自此,开发者们开始在以太坊网络上构建智能合约和去中心化应用。除此之外,矿工们也开始加入以太坊网络来支持其安全性并从挖到的区块中赚取以太币。尽管作为以太坊项目的第一个里程碑,Frontier版本仅是面向开发者的一个beta版本,但它超出所有人预期的能力和可靠性,使开发者们趋之若鹜,争相开始构建自己的解决方案和改进以太坊的生态系统。
- Original announcement of the release scheme by Vinay Gupta
- Frontier is coming - Frontier launch announcement by Stephan Tual
- Frontier launch final steps - Follow-up post to announcement
- Ethereum goes live with Frontier launch
- The frontier website
开发者大会(DEVCON-1)¶
第二次开发者大会 DEVCON-1 于2015年11月初在伦敦举行。这次为期5天的盛会,诞生了100多个报告、圆桌讨论和启发性的交流,吸引了包括开发者、企业家、思想家及业务经理在内的超过400位参与者。
所有的讨论都进行了录制,可以 免费观看
像UBS、IBM和微软这样的大公司的出席,也表明了企业界对这些技术的兴趣。微软也宣布将在其云计算平台Azure上提供 以太坊区块链服务(Blockchain as a Service,BaaS) 。这也与DEVCON-1一起成为一个标志着以以太坊为中心的区块链技术变为主流的重要时刻。
- DEVCON-1 talks Youtube playlist
- DEVCON-1 website full listing of presentations with links to the slides if available.
社区¶
当你开始讨论或提出问题的时候,请聪明的选择论坛,以帮助我们保持不同论坛的清晰和整洁。
Reddit¶
Ethereum subreddit 是范围最宽泛的以太坊论坛,绝大多数社区讨论都发生在这里,并且核心开发者在其中也很活跃。这里是你进行关于新闻、媒体报道、公布消息和头脑风暴等等一般性讨论的良好选择。总体上讲,与以太坊有关的所有事情都可以在这里交流。
这里是严格的无偿讨论。
当然,这里不是寻求手把手的帮助或者希望得到快速回复的好地方。(如果有这些需求,请使用 Gitter Rooms 或 Stack Exchange )
在发帖之前,请阅读 Ethereum subreddit rules
其他特定领域的subreddit:
- /r/EthTrader - Ether trading, price and market
- /r/EtherMining - Ether mining discussion
- /r/Ethmarket - Marketplace for individuals looking to exchange goods and services for Ether
- /r/Ethinvestor - News and prospects for Ethereum investors. Following the long term trends in the Ethereum marketplace.
- /r/ethereumism/ - A bit more ism, ostic, ical, ist and tinfoil hats, pyramids and crystal ball type of views - the ethereal side of Ethereum
Stack Exchange¶
以太坊Stack Exchange 是StackExchange网络问答社区的一部分。StackExchange是一个免费的问答网站,所有的问题和回复都会被长久的保存。
这里是询问技术问题的最佳地点。你可以在这里通过回答问题来帮助其他的以太坊参与者,并积累声望。
Gitter Rooms¶
Gitter是我们选择来做日常交流的论坛。当开发遇到麻烦时,这里就是一个虚拟的协作空间,你可以得到帮助,如果需要的话甚至有可能是手把手的指导。
Gitter使用的是Github账户,提供了Github集成(比如pull请求的通知等) 、私有频道,并提供markdown(一种标记语言,可以是普通文本具备一定的格式,译者注)格式化等功能。
大多数Gitter频道都被组织到特定的库或一个一般性的主题,比如研究或管理。请选择合适的房间并保持与其主题相关的讨论。
参考 the full list of gitter rooms for the Ethereum organisation。以下是一些活跃的公共频道列表:
- go-ethereum - about geth (and tools related to the go implementation)
- cpp-ethereum - about eth (and tools related to the C++ implementation)
- web3.js - about web3.js, Ethereum JavaScript API library
- Solidity - The Solidity Contract-Oriented Programming Language
- serpent - The Serpent language for contract development
- mist - GUI dapp browser, official wallet app
- light-client - about light client and the LES protocol
- research - Ethereum research
- governance - about dev governance
- whisper - anonymous datagram publishing
- swarm - decentralised content storage and distribution network
- EIPs - discussion of Ethereum Improvement Proposals (EIPs)
- ethereumjs-lib - a JavaScript library of core Ethereum functions
- devp2p - ÐΞV’s p2p network protocol & framework
以太坊改进建议(EIPs)¶
EIP体系,旨在设计为一个框架和用来协调针对协议的改进的非正式业务流程。大家需要先把各自的想法作为问题提出,或发起一个对EIP资料库的pull请求(在Github上,译者注)。经过初步筛选,具体的建议会被指定一个顺序号并加入草案表。想要激活一个EIP,需要社区内的共同批准。那些建议改动的最终批准,将取决于以太坊的用户是否能达成共识。关于EIP的讨论,请使用 gitter channel for EIP discussions。
Meetups(一个用来组织线下社交聚会的网站,译者注)¶
以太坊基金会(The Ethereum Foundation)¶
以太坊基金会是一个在瑞士注册的非盈利组织。它的目标是管理以太币销售带来的资金以更好支持以太坊和去中心化技术生态系统。
2014年7月在瑞士成立的以太坊基金会,其宗旨是促进新技术和应用形式的发展,特别是在新的开放的去中心化软件架构领域。
它的目标是使去中心化开放技术可以被开发、培养、升级和保持。一个居于首要地位,但不唯一的中心任务就是对以太坊协议及相关技术发展的推进,以及对使用以太坊技术和协议的应用的推进和支持。除此之外,以太坊基金会还以各种不同的形式支持和倡导一个去中心化的互联网。
更多关于基金会的信息请参考 基金管理团队官方网站
以太坊基金会所面向的社区¶
- Official Homestead website - main entrypoint
- Reddit - see 社区
- Blog
- Youtube
- Facebook - largely unused
- Email - use if you must
以太坊基金会的官方交流,通常是以在 Ethereum blog 上发表博客的方式来展开的。这些文章中包含技术上的、组织上的乃至个人的内容。所有博客的发表都会在 Twitter 和 Reddit 上公布。
基金会的 Youtube频道 上可以看到我们的视频,包括开发者大会DEVCON0和DEVCON1上的所有开发者讨论。
关于社区论坛,请参见 社区
撰稿人(Contributors)¶
作为 Homestead Documentation Initiative 项目的一部分,这份文档由以太坊社区所共同编纂,由以下两位作为协调:
我们想感谢在编纂过程中做出贡献的 撰稿人们 :
- Ricardo de Azevedo Brandao
- Santanu Barai
- Brooks Boyd
- RJ Catalano
- Joseph Chow
- Keri Clowes
- François Deppierraz
- Bertie Dinneen
- Gregg Dourgarian
- Raghav Dua
- Erik Edrosa
- Andrey Fedorov
- Rocky Fikki
- Alex Fisher
- Enrique Fynn
- Arno Gaboury
- Taylor Gerring
- Dave Hoover
- Joël Hubert
- Makoto Inoue
- Keith Irwin
- Matthias Käppler
- Bas van Kervel
- Michael Kilday
- Chandra Kumar
- Guangmian Kung
- Hugh Lang
- Yann Levreau
- Roman Mandeleil
- Kévin Maschtaler
- Andrew Mazzola
- Dominik Miszkiewicz
- John Mooney
- Steven Natera
- Chris Peel
- Craig Polley
- Colm Ragu
- Laurent Raufaste
- Christian Reitwiessner
- Josh Stark
- Scott Stevenson
- Bob Summerwill
- Alex van de Sande
- Paul Schmitzer
- Afri Schoedon
- Sudeep Singh
- Conor Svensson
- Giacomo Tazzari
- Ben Tannenbaum
- Dean Alain Vernon
- Daniel Weinmann
- Paul Worrall
- Haoyu Yang
- Luca Zeug
- Weiyang Zhu
- Will Zeng
以及这些匿名的撰稿人:
中文版翻译:
以太坊客户端¶
选择客户端¶
为什么有这么多以太坊客户端?¶
从这个项目的最早期就已经存在多个客户端实现,用以支持很多不同的操作系统。就生态系统的整体而言,客户端的多样性是个巨大的成就。它使我们可以验证基础协议(就像 黄皮书 描述的那样)是清晰明确的。它也保留了新的创新的可能,使我们保持坦诚。但这对最终用户而言确实有些头疼,因为并没有一个统一的“以太坊安装程序”。
截止到2016年9月,领先的实现是 go-ethereum 和 Parity.
Client | Language | Developers | Latest release |
---|---|---|---|
go-ethereum | Go | Ethereum Foundation | go-ethereum-v1.4.18 |
Parity | Rust | Ethcore | Parity-v1.4.0 |
cpp-ethereum | C++ | Ethereum Foundation | cpp-ethereum-v1.3.0 |
pyethapp | Python | Ethereum Foundation | pyethapp-v1.5.0 |
ethereumjs-lib | Javascript | Ethereum Foundation | ethereumjs-lib-v3.0.0 |
Ethereum(J) | Java | <ether.camp> | ethereumJ-v1.3.1 |
ruby-ethereum | Ruby | Jan Xie | ruby-ethereum-v0.9.6 |
ethereumH | Haskell | BlockApps | no Homestead release yet |
我应该在台式电脑/笔记本电脑上安装什么?¶
绝大多数用户只需要安装 Mist / Ethereum Wallet(以太坊钱包) 就够了。
以太坊钱包是一个 Mist浏览器 的独立dapp(去中心化应用)实现。它是继Homestead之后到来的大规模开发的核心部分。
Mist是与 go-ethereum 和 cpp-ethereum 可执行库捆绑的。如果在启动Mist的时候还没有运行一个命令行以太坊客户端,那么Mist会使用一个内置的客户端(默认为 geth)来同步区块链数据。如果你想让Mist使用Parity或者想在一个私有网络中使用Mist,你需要在启动Mist之前先启动你自己的节点,这样Mist将会连接到已启动的节点上,而不是再自己启动一个。
将Parity和其他客户端添加为Mist优先使用的实体的工作也已经在进行中了。
如果你希望在命令行与Ethereum进行交互,享受JavaScript控制台带来的便利,那你应该直接安装客户端程序,就像安装Mist一样。请参考前文表格中的链接获得更多详细信息。
如果你想挖矿,那Mist确实就不够了。请参考 挖矿 。
我应该在智能手机/平板电脑上安装什么?¶
我们对于移动设备的支持还处于起步阶段。Go语言团队正在研发iOS和安卓的底层程序,一些开发者开始使用它们引入移动应用。但以太坊还没有一个可用的移动设备客户端。
在移动设备上使用以太坊的主要障碍是由于对轻量级客户端的支持还不完备。已经完成的工作在一个私有的分支上关闭了,并且其仅支持Go语言的客户端。doublethinkco将基于授权的资助在未来数月中开始C++语言轻量级客户端的开发。
Status.im 是一个最初使用基于 Ethereum(J) 的 ethereumj-personal 构建,近来转而使用Geth混合构建的轻量级客户端。
我应该在我的SBC(Single Board Computer,即单板机,译者注)上安装什么?¶
基于你的技能水平和你想做的事,这里有几个选择。
- 下载一个完整的镜像(链接到一个有详细的下载和安装手册的页面)
- 如果你是个对以太坊和像Raspberry Pi这样的单板机主板的新手的话,用这个就对了。下载一个对应你现在使用的主板的镜像,把它烧录到SD卡上,重启你的设备使用以太坊吧。
- 下载预编译应用(链接到一个有详细的下载和安装手册的页面)
- 如果你已经做好了一个SBC,使用了特定的OS或者你想保持一些既有的设置,那这是你的最佳选择。取决于不同的平台,你可以简单地下载合适的可执行程序,只需要最少的运行库和PATH设置,你就可以在你的既存环境中运行以太坊了!
- 使用定制的脚本从源码构建(链接到一个有更多详情和独立的SBC链接 https://github.com/ethembedded)
- 正在进行一个定制的安装么?我们有一些可以“在设备上”编译源码的脚本。这些脚本包含对相关依赖的自动安装,就像客户端一样。这将允许你安装某个特定版本的以太坊客户端(比如“develop”、“master”等),编译你自己fork下来的某个客户端版本,来完全地享受错综复杂的构建过程。
cpp-ethereum¶


Quick Start¶
- Welcome to the Ethereum C++ project :-)
- The GitHub repository for this project is ethereum/cpp-ethereum
- Automation runs on Appveyor and TravisCI.
- We have instructions for Installing binaries and Building from source.
- Most project communication happens in our User and Developer Gitter channels.
- Issues are tracked in our Github issue tracker.
- cpp-ethereum is extremely portable and is used on a very broad range of platforms.
Details¶
Current status¶
We blog about the codebase periodically on the Official Ethereum blog and elsewhere. Here are some recent articles from the development team:
- Ethereum DEV Update: C++ Roadmap (February 2016)
- C++ DEV Update: Announcing Remix (May 2016)
- C++ DEV Update – July edition (July 2016)
- Ethereum Everywhere (July 2016)
- C++ re-licensing plan (July 2016)
We simplified the project naming at Homestead (March 2016), although some naming shadows of the past still linger. With the homecoming we have another name to retire - webthree-umbrella.
At the time of writing (August 2016), we are just completing our “Homecoming”, where the code has been reconsolidated into the ethereum/cpp-ethereum repository. From October 2015 until August 2016 it was split across multiple repositories under ethereum/webthree-umbrella
The re-licensing plan is the culmination of a very long-term plan to liberalize the core. An effort was begun in 2015 to re-license the cpp-ethereum core as MIT, but it was never completed.
This is a revival of that effort, especially with a view towards the potential for collaboration with the Linux Foundation’s Hyperledger project, and with other corporations outside of Hyperledger who wish to build Ethereum private/consortium chain solutions similar to HydraChain. The Rubix by Deloitte project is an example of that approach.
Building from source¶
Overview¶
The cpp-ethereum codebase lives on Github.com in the cpp-ethereum repository.
Between October 2015 and August 2016 it was split into various repositories which were grouped as sub-modules under the webthree-umbrella repository, and you will likely see many references to webthree-umbrella online. Those all refer to the cpp-ethereum codebase during that period of its development.
We use a common CMake build system to generate platform-specific build files, meaning that the workflow is very similar whatever operating system you use:
- Install build tools and external packages (these are platform dependent)
- Clone the source code from the webthree-umbrella git repository
- Run CMake to generate a build file (makefile, Visual Studio solution, etc)
- Build it
Platform-specific instructions¶
We use git and GitHub to maintain the source code. Clone the repository by:
git clone --recursive https://github.com/ethereum/cpp-ethereum.git
cd cpp-ethereum
The --recursive
option is important. It orders git to clone additional submodules
which are required to build the project.
If you missed it you can correct your mistake with command git submodule update --init
.
We use CMake to control the build configuration of the project. Quite recent version of CMake is required (at the time of writing 3.4 is the minimum). We recommend installing CMake by downloading and unpacking the binary distribution of the latest version available on the download page:
Alternative method
The repository contains the script install_cmake.sh that downloads a fixed version of CMake and unpacks it to the given directory prefix. Example usage
scripts/install_cmake.sh --prefix /usr/local
.
The following libraries are required to be installed in the system:
- boost
- leveldb
- curl
- microhttpd
- miniupnp
- gmp
They usually can be installed using distribution-specific package manager. For example on Debian-based systems:
sudo apt-get install libboost-all-dev libleveldb-dev libcurl4-openssl-dev libmicrohttpd-dev libminiupnpc-dev libgmp-dev
or on RedHat-based systems:
dnf install boost-devel leveldb-devel curl-devel libmicrohttpd-devel miniupnpc-devel gmp-devel
Linux has a horror-show of fragmentation when it comes to packaging systems.
We support a “one-button” bash script which attempts to make this minefield more navigable for users of common distros. It identifies your distro and installs the external packages which you will need, using whatever combination of package servers and build-from-source is required for your specific distro version. This is a non-trivial task, but by that token is also something which we don’t want anybody to have to replicate themselves.
scripts/install_deps.sh
We use the same script for automated builds and continuous integration, so it is continuously tested, which is especially important on MacOS, where Homebrew is a constantly moving target.
If you try it, and it doesn’t work for you, please report the problem with details of your distro, your version number and any other important details and we can work together to get it working for your use-case.
We have manual instructions for Fedora, openSUSE and Arch Linux (see below). If you using some other distro then please contact us and we’ll see if we can get you going.
Steps:
dnf install git automake autoconf libtool cmake gcc gcc-c++ xkeyboard-config \
leveldb-devel boost-devel gmp-devel cryptopp-devel miniupnpc-devel \
qt5-qtbase-devel qt5-qtdeclarative-devel qt5-qtquick1-devel qt5-qtwebkit-devel \
mesa-dri-drivers snappy-devel ncurses-devel readline-devel curl-devel \
python-devel jsoncpp-devel argtable-devel libmicrohttpd-devel
Make sure you have cloned the repository recursively. If not please clone the submodules of the respository as well. It may happen that after # make install, you might not be able to run eth because of linking errors. In that case you have to add the shared objects of eth into your load path for shared objects.
Here is how to get the dependencies needed to build the latest webthree-umbrella on OpenSUSE. This was done on Leap 42.1 and 42.2, but there should be equivalent packages available for Tumbleweed and 13.x.
First install dependencies provided by the main repos:
zypper in git automake autoconf libtool cmake gcc gcc-c++ \
xkeyboard-config leveldb-devel boost-devel gmp-devel \
libcryptopp-devel libminiupnpc-devel libqt5-qtbase-common-devel \
libqt5-qtdeclarative-devel libQtWebKit-devel libqt5-qtwebengine-devel \
libQt5Concurrent-devel Mesa ncurses-devel readline-devel libcurl-devel \
llvm llvm-clang llvm-clang-devel llvm-devel libLLVM binutils \
libmicrohttpd-devel jsoncpp-devel opencl-headers-1.2 zlib-devel
- If Opencl-headers-1.2 is not found, you can install it manually from the CLI:
- zypper addrepo http://download.opensuse.org/repositories/home:valmar73:crystfel-releases/openSUSE_13.1/home:valmar73:crystfel-releases.repo zypper refresh zypper install opencl-headers-1.2
It may be possible to use the generic libOpenCL1, but I have only tested with the AMD proprietary package from the AMD drivers repo fglrx64_opencl_SUSE421
These packages are not in the standard repos but can be found using the OpenSUSE build service package search and YaST 1-Click Install:
- libargtable2-devel
- libv8-3
- v8-devel
If you also have v8 from the chromium repo installed the devel package will default to the 4.x branch which will not work. Use YaST or zypper to downgrade this package to 3.x
Note that Opencl-headers is used to mine the chain with GPU. If this is not a requirement, you can bypass it when creating the makefile (cmake -DETHASHCL=0 .. ) instead of (cmake ..)
Compiling webthree-umbrella on Arch Linux requires dependencies from both the official repositories and the Arch User Repository (AUR). To install packages from the official repositories pacman is used. For installation of packages from the AUR, a number of AUR helpers is available. For this guide, yaourt AUR helper is used.
# from official repositories sudo pacman -Sy git base-devel cmake boost crypto++ leveldb llvm miniupnpc libcl opencl-headers libmicrohttpd qt5-base qt5-webengine
# from AUR yaourt -Sy libjson-rpc-cpp
During this step, an installation folder for the Ethereum can be specified. Specification of the folder is optional though. If not given, the binary files will be located in the build folder. However, for this guide, it is assumed that the Ethereum files will be installed under /opt/eth. The reason for using /opt is that it makes much easier to delete the Ethereum files later on, as compared to having them installed under, e.g., /usr. Also /opt is commonly used to install software that is not managed by packaging systems, such as manually compiled programs.
# enter webthree-umbrella folder after cloning its github repository
cd webthree-umbrella
# make a build folder and enter into it
mkdir -p build && cd build
# create build files and specify Ethereum installation folder
cmake .. -DCMAKE_INSTALL_PREFIX=/opt/eth
# compile the source code
make
# alternatively it is possible to specify number of compilation threads
# for example to use 4 threads execute make as follows:
# make -j 4
# install the resulting binaries, shared libraries and header files into /opt
sudo make install
After successful compilation and installation, Ethereum binaries can be found in /opt/eth/bin, shared libraries in /opt/eth/lib, and header files in /opt/eth/include.
Since Ethereum was installed in /opt/eth, executing its binaries can result in linker error due to not being able to find the Ethereum shared libraries. To rectify this issue, it is needed to add the folder containing Ethereum shared libraries into LD_LIBRARY_PATH environmental variable:
# update ~/.bashrc
echo "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/eth/lib" >> ~/.bashrc
# reload ~/.bashrc
source ~/.bashrc
When you have installed your dependencies you can build.
mkdir build Make a directory for the build output
cd build Switch into that directory
cmake .. To generate a makefile.
make To build that makefile on the command-line
make -j<number> (or) Execute makefile with multiple cores in parallel
We have cpp-ethereum building and running successfully on many 32-bit Linux distros, with the main constraint being the availability of external dependencies in 32-bit variants. Probably the most active demand here is for single-board computers like the Raspberry Pi family.
You will need to disable the JIT and the heavy-weight LLVM dependency which comes with that. EVMJIT only supports x86_64. Other than that, cpp-ethereum should “just work” on 32-bit platforms. To disable JIT, you will need to use the following command for the Makefile generation phase:
cmake .. -DEVMJIT=Off
We support only 64-bit builds and only for the following versions of Windows:
It may be possible to get the client working for Windows 32-bit, by disabling EVMJIT and maybe other features too. We might accept pull-requests to add such support, but we will not put any of our own development time into supporting Windows 32-bit builds.
You will need to install the following dependencies
Software | Notes |
---|---|
Git for Windows | Command-line tool for retrieving source from Github. |
CMake | Cross-platform build file generator. |
Visual Studio 2015 | C++ compiler and dev environment. |
Clone the git repository containing all the source code by executing the following command:
git clone --recursive https://github.com/ethereum/cpp-ethereum.git
cd cpp-ethereum
Execute the CMake script that downloads and unpacks pre-built external libraries needed to build the project:
scripts\install_deps.bat
Then execute the following commands, which will generate a Visual Studio solution file using CMake:
mkdir build
cd build
cmake -G "Visual Studio 14 2015 Win64" ..
Which should result in the creation of cpp-ethereum.sln in that build directory.
NOTE: We only support Visual Studio 2015 as of cpp-ethereum-v.1.3.0.
Double-clicking on that file should result in Visual Studio firing up. We suggest building RelWithDebugInfo configuration, but all others work.
Alternatively, you can build the project on the command-line, like so:
cmake --build . --config RelWithDebInfo
It is impossible for us to avoid OS X build breaks because Homebrew is a “rolling release” package manager which means that the ground will forever be moving underneath us unless we add all external dependencies to our Homebrew tap, or add them as git sub-modules. End-user results vary depending on when they are build the project. Building yesterday may have worked for you, but that doesn’t guarantee that your friend will have the same result today on their machine. Needless to say, this isn’t a happy situation.
If you hit build breaks for OS X please look through the Github issues to see whether the issue you are experiencing has already been reported. If so, please comment on that existing issue. If you don’t see anything which looks similar, please create a new issue, detailing your OS X version, cpp-ethereum version, hardware and any other details you think might be relevant. Please add verbose log files via gist.github.com or a similar service.
The cpp-ethereum-development gitter channel is where we hang out, and try to work together to get known issues resolved.
We only support the following OS X versions:
The cpp-ethereum code base does not build on older OS X versions and this is not something which we will ever support. If you are using an older OS X version, we recommend that you update to the latest release, not just so that you can build cpp-ethereum, but for your own security.
To clone the source code, execute the following command:
git clone --recursive https://github.com/ethereum/cpp-ethereum.git
cd cpp-ethereum
Ensure that you have the latest version of xcode installed. This contains the Clang C++ compiler, the xcode IDE and other Apple development tools which are required for building C++ applications on OS X. If you are installing xcode for the first time, or have just installed a new version then you will need to agree to the license before you can do command-line builds:
sudo xcodebuild -license accept
Our OS X builds require you to install the Homebrew package manager for installing external dependencies. Here’s how to uninstall Homebrew, if you ever want to start again from scratch.
We now have a “one button” script which installs all required external dependencies on macOS and on numerous Linux distros. This used to a multi-step manual process:
./scripts/install_deps.sh
From the project root:
mkdir build
cd build
cmake ..
make -j4 (or different value, depending on your number of CPU cores)
You can also use the same Makefile to install your own build globally on your machine:
make install
This will install binaries into /usr/local/ and /usr/bin/.
From the project root:
mkdir build_xc
cd build_xc
cmake -G Xcode ..
This will generate an Xcode project file called cpp-ethereum.xcodeproj, which you can then open with xcode and build/debug/run.
NOTE - Once the packages are in the FreeBSD main ports this guide should be changed to something much more simple
For some of this steps you must require a root access to modify the ports directory.
The webthree-umbrella depends on [libjson-rpc-cpp.shar](https://raw.githubusercontent.com/enriquefynn/webthree-umbrella-port/master/libjson-rpc-cpp.shar) that is also not in the ports system.
First you need to download the shar file and place it on your ports directory under the “devel” session, usually /usr/ports/devel
curl https://raw.githubusercontent.com/enriquefynn/webthree-umbrella-port/master/libjson-rpc-cpp.shar > /usr/ports/devel/libjson-rpc-cpp.shar
Now we execute the script with:
cd /usr/ports/devel
sh libjson-rpc-cpp.shar
This will create the libjson-rpc-cpp port. Now you should do the same for the webthree-umbrella port, we should get the [webthree-umbrella](https://raw.githubusercontent.com/enriquefynn/webthree-umbrella-port/master/webthree-umbrella.shar) file and create the port under “net-p2p” directory.
curl https://raw.githubusercontent.com/enriquefynn/webthree-umbrella-port/master/webthree-umbrella.shar> /usr/ports/net-p2p/webthree-umbrella.shar
cd /usr/ports/net-p2p
sh webthree-umbrella.shar
Now you can navigate to the webthree-umbrella directory and install the port:
cd /usr/ports/net-p2p/webthree-umbrella
make install clean
We don’t currently have a working Android build, though that is on the roadmap for doublethinkco. Android uses the Linux kernel, but has a different API than the ARM Linux cross-builds, meaning that specific binaries will be required.
ARM Linux distros use the GLIBC runtime library, where Android uses bionic.
We don’t currently have a working iOS build, though that is on the roadmap for doublethinkco. iOS is a UNIX-like operating system based on Darwin (BSD) using ARM chips. This is a different API than the ARM Linux cross-builds, meaning that specific binaries will be required.
EthEmbedded maintain build scripts for all Raspberry Mi models. They are on Github in the Raspi-Eth-Install repository. It is also possible to cross-build for these platforms.
EthEmbedded maintain build scripts for both of these Odroid models. Support for a broader range of Odroid devices is likely in the future. They are on Github in the OdroidXU3-Eth-Install repository. It is also possible to cross-build for these platforms.
EthEmbedded maintain build scripts for BBB on Github in the BBB-Eth-Install repository. It is also possible to cross-build for this platform.
EthEmbedded maintain build scripts for the WandBoard on Github in the WandBoard-Eth-Install repository. It is also possible to cross-build for this platform.
doublethinkco maintain a Docker-based cross-build infrastructure which is hosted on Github in the cpp-ethereum-cross repository.
At the time of writing, these cross-built binaries have been successfully used on the following devices:
- Jolla Phone (Sailfish OS)
- Nexus 5 (Sailfish OS)
- Meizu MX4 Ubuntu Edition (Ubuntu Phone)
- Raspberry Pi Model B+, Rpi2 (Raspbian)
- Odroid XU3 (Ubuntu MATE)
- BeagleBone Black (Debian)
- Wandboard Quad (Debian)
- C.H.I.P. (Debian)
Still TODO:
- Tizen
- Android
- iOS
Installing binaries¶
The cpp-ethereum development team and the broader Ethereum community publish binary releases in many different forms for a variety of platforms. This aims to be a complete list of those releases.
If you are aware of other third-party packaging efforts, please let us know on the cpp-ethereum gitter channel, and we will add them to this list.
Docker¶
We are hosting latest development snapshots (and in the future also releases) at docker hub. You can run these images as follows:
Before running the image, you should pull the latest version and prepare the data directories:
# get the lastest version from dockerhub (redo for updates).
docker pull ethereum/client-cpp
# create mountable datadirs; blockchain/account data will be stored there
mkdir -p ~/.ethereum ~/.web3
These steps need to be done only once. For upgrading to a new version do
the docker pull ...
again.
The simplest version is to run:
docker run --rm -it \
-p 127.0.0.1:8545:8545 \
-p 0.0.0.0:30303:30303 \
-v ~/.ethereum:/.ethereum \
-v ~/.web3:/.web3 \
-e HOME=/ \
--user $(id -u):$(id -g) \
ethereum/client-cpp
This will write data to ~/.ethereum
and ~/.web3/
on your host and run
the client with your user’s permissions. For most cases this should be
sufficient and the client should behave exactly as if run from a local build.
If you want the rpc port reachable from the network (not recommended, never do this
if you have valuable data or private keys on your machine), replace
-p 127.0.0.1:8545:8545
by -p 0.0.0.0:8545:8545
.
For convenience, you can create the file /usr/local/bin/docker-eth
with the
following content:
#!/usr/bin/env sh
mkdir -p ~/.ethereum ~/.web3
if ! id -nG $(whoami)|grep -qw "docker"; then SUDO='sudo'; else SUDO=''; fi
$SUDO docker run --rm -it \
-p 127.0.0.1:8545:8545 \
-p 0.0.0.0:30303:30303 \
-v ~/.ethereum:/.ethereum \
-v ~/.web3:/.web3 \
-e HOME=/ \
--user $(id -u):$(id -g) \
ethereum/client-cpp $@
And make it executable with chmod +x /usr/local/bin/docker-eth
. Now you can
start the client with:
docker-eth
Note: The docker-eth
command will accept the same flags as the raw eth
command.
Due to https://github.com/docker/libnetwork/issues/552 multicast is not working
yet without --net=host
. You can still run the client with network isolation
and use -p 127.0.0.1:8545:8545 -p 30303:30303 -p 30303:30303/udp
for
publishing the rpc, discovery and p2p ports. If you want to be discoverable
from the outside, you will need to
- add your public ip address with the
--public-ip
flag, - create a port forwarding with your NAT
(syncing will still work without it).
Ubuntu PPA (Personal Package Archive)¶
NOTE - At the time of writing (31st August 2016), the PPAs are broken, following significant repository reorganizations and a change of automation process. We have not hooked the PPA generation steps back together yet, though this will happen in the very near future. In the meantime, please follow the Building for Linux instructions.
We have set up PPA instances for the following Ubuntu versions:
- Ubuntu Trusty Tahr (14.04)
- Ubuntu Utopic Unicorn (14.10)
- Ubuntu Vivid Vervet (15.04)
- Ubuntu Wily Werewolf (15.10)
- Ubuntu Xenial Xerus (16.04)
We only support 64-bit builds. It may be possible to get the client working for Ubuntu 32-bit, by building from source and disabling EVMJIT and maybe other features too. We might accept pull-requests to add such support, but we will not put any of our development time into supporting Ubuntu 32-bit builds.
For the latest stable version:
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install cpp-ethereum
If you want to use the cutting edge developer version:
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:ethereum/ethereum
sudo add-apt-repository ppa:ethereum/ethereum-dev
sudo apt-get update
sudo apt-get install cpp-ethereum
Windows Chocolatey NuGet packages¶
We aren’t generating Chocolatey packages at the time of writing, though we have done so in the past.
For anybody who isn’t already familiar with the technology, this is essentially apt-get for Windows - a global silent installer for tools.
We would like to support Chocolatey again in the near future for all the same reasons we support Homebrew on OS X and have PPAs for Ubuntu. For technically competent users, doing command-line operations like so would be very convenient:
choco install cpp-ethereum
choco update cpp-ethereum
OS X Homebrew packages¶
We generate Homebrew packages within our automated build system for the following OS X / Mac versions:
We only support 64-bit builds.
If your system does not support these OS X versions then you are out of luck. Sorry!
All OS X builds require you to install the Homebrew package manager before doing anything else. Here’s how to uninstall Homebrew, if you ever want to start again from scratch.
To install the Ethereum C++ components from Homebrew, execute these commands:
brew update
brew upgrade
brew tap ethereum/ethereum
brew install cpp-ethereum
brew linkapps cpp-ethereum
Here is the Homebrew Formula which details all the supported command-line options.
Raspberry Pi, Odroid, BeagleBone Black, Wandboard¶
John Gerryts of EthEmbedded builds binary images for a variety of SBCs at major milestones, in addition to testing and maintaining build scripts for these devices. EthEmbedded was a devgrant recipient in May 2015. He builds binaries for both eth and geth.
Here are the Homestead binaries from EthEmbedded
Linux ARM cross-builds for mobile, wearables, SBCs¶
Bob Summerwill, of doublethinkco cross-builds ARM binaries which work on a very broad variety of hardware, from mobile and wearables Linux distros (Sailfish OS, Tizen OS, Ubuntu Touch) to the same SBCs which EthEmbedded target - and more. doublethinkco was a BlockGrantX recipient in Feb 2016.
See the cpp-ethereum-cross README for a full matrix of platforms and known status.
Here are the cross-build binaries from doublethinkco: RELEASED – Cross-build eth binaries for Homestead.
ArchLinux User Repository (AUR)¶
Arch Linux packages are community maintained by Afri Schoedon.
Check out the following packages on aur.archlinux.org.
- ethereum (stable, latest release)
- ethereum-git (unstable, latest develop)
To build and install the package, follow the AUR installing package instructions:
- Acquire the tarball which contains the PKGBUILD
- Extract the tarball
- Run
makepkg -sri
as simple user in the directory where the files are saved - Install the resulting package with
pacman -U
as superuser
You can also use AUR helpers
like yaourt
or pacaur
to install the packages directly on your system.
Mageia Cauldron (6) RPMs¶
Luis Daniel Lucio Quiroz has created RPMs for Mageia Cauldron (6).
cpp-ethereum is available in the non-free repository of Mageia 6. You will need to enable it. Once this is done, to install you just need to run the URPMI command (or RPMDRAKE if you are using GUI):
urpmi cpp-ethereum
Contributing¶
Help in whatever form is always more than welcome.
You can just start by Building from source and familiarizing yourself with the Architecture. If something strange happens, please report an issue (see below).
Once you get to know the technology, you can try to answer questions from other users (we do not always have time for that) either on cpp-ethereum gitter, stackexchange or just comment on issues.
If you are a C++ developer, you can help by submitting pull requests (see below).
We try to keep a list of good tasks to start with. Please get in contact on gitter if you have any questions or suggestions.
The backlog is kept in github issues with an overview in our waffle board.
The waffle board is also useful to keep track of pull requests pending reviews (if you switch the filter on the top right to “pull requests only”).
How to Report Issues¶
Please report issues against the specific projects using GitHub Issues:
Try to mention which version of the software you used and on which platform (Windows, MacOS, Linux, …), how you got into the situation (what did you do), what did you expect to happen and what actually happened.
How to Submit Pull Requests / Workflow¶
Set up your workspace using the Building from source instructions. To contribute you will need to fork/clone the repositories.
Please also respect the Coding Standards.
If you encounter any problems, please ask on gitter.
Create pull requests against the develop branch of the repository you made changes in. Try not to include any merges with the pull request and rebase if necessary. If you can set labels on a pull request, set it to please review and also ask for a review in gitter.
You can also do reviews on others’ pull requests. In this case either comment with “looks good” or set the label if you can. If at least one core developer apart from the author is confident about the change, it can be merged. If the reviewer thinks that corrections are necessary, they put he label got issues. If the author addressed all comments, they again put please review or comment appropriately.
Automation runs on Appveyor and TravisCI.
Thanks for helping and have fun!
Architecture¶
- bench: trie benchmarking
- cmake: cmake files for build system, contains specification of inter-dependencies
- eth A command-line Ethereum full-node that can be controlled via RPC.
- ethkey: stand-alone key management
- ethminer: stand-alone ethash miner
- ethvm: stand-alone EVM execution utility
- evmjit: library for the EVM just-in-time compiler
- libdevcore: data structures, utilities, rlp, trie, memory db
- libdevcrypto: crypto primitives. Depends on libsecp256k1 and libcrypto++.
- libp2p: core peer to peer networking implementation (excluding specific sub-protocols)
- libethash: ethash mining POW algorithm implementation
- libethash-cl: ethash mining code for GPU mining (OpenCL)
- libethashseal: generic wrapper around the POW block seal engine. Also contains the genesis states for all ethash-based chains.
- libethcore: collection of core data structures and concepts
- libethereum: main consensus engine (minus EVM). Includes the State and BlockChain classes.
- libevm: Ethereum Virtual Machine implementation (interpreter).
- libevmasm: EVM assembly tools, also contains the optimizer.
- libevmcore: elementary data structures of the EVM, opcodes, gas costs, …
- libweb3jsonrpc: json-rpc server-side endpoint, provides http and IPC (unix socket, windows pipe) connectors
- libwebthree: service connectors for ethereum, swarm/ipfs and whisper.
- libwhisper: whisper implementation
- rlp: stand-alone rlp en-/decoder
- testeth: tests for the modules formerly within the libethereum repo
- testweb3core: tests for the modules formerly within the libweb3core repo
- testweb3: tests for the modules formerly within the webthree repo
- utils/json_spirit: JSON parser written for Boost’s Spirit library.
- utils/libscrypt: scrypt implementation
- utils/secp256k1: implementation of the SECP 256k1 ECDSA signing algorithm.
Portability¶
The Ethereum C++ client code is exceedingly portable, and is being successfully used on a huge range of different operating systems and devices.
We continue to expand our range and are very open to pull-requests which add support for additional operating systems, compilers or devices.
Operating systems verified as working¶
- Linux
- Alpine Linux
- Arch Linux
- Debian 8 (Jessie and Stretch)
- Fedora 20
- Fedora 21
- Fedora 22
- openSUSE Leap 42.1
- PureOS 2.1
- Raspbian
- Sailfish OS 2.0
- Ubuntu 14.04 (Trusty)
- Ubuntu 14.10 (Utopic)
- Ubuntu 15.04 (Vivid)
- Ubuntu 15.10 (Wily)
- Ubuntu 16.04 (Xenial)
- Ubuntu Touch
- Ubuntu 15.04 MATE
- BSD
- FreeBSD
- OS X
- OS X Yosemite (10.10)
- OS X El Capitan (10.11)
- OS X 10.10 (Yosemite Server 4.0)
- OS X 10.11 (Yosemite Server 5.0)
- OS X 10.11 (Yosemite Server 5.1)
- Windows
- Windows 7
- Windows 8
- Windows 8.1
- Windows 10
- Windows Server 2012 R2
Operating systems - work in progress¶
- Linux
- Maemo
- MeeGo
- Tizen
- BSD
- iOS
- tvOS
- WatchOS
- Android
Devices verified as working¶
- All varieties of desktop and laptop devices (Windows, OS X, Desktop Linux)
- 64-bit (with rebuilt binaries)
- 32-bit (not official supported, but they work)
- Smartphones
- Linux
- Jolla Phone
- Meizu MX4 Ubuntu Edition
- Nexus 5 (SailfishOS 2.0)
- SBCs
- Linux
- BeagleBone Black
- Odroid XU3
- Project C.H.I.P.
- Raspberry Pi Model A
- Raspberry Pi Model B+
- Raspberry Pi Zero
- Raspberry Pi 2
- Raspberry Pi 3
- Wandboard Quad
Devices - work in progress¶
- Smartwatches
- Linux
- Samsung Gear S2
- BSD
- Apple Watch
- Smartphones
- Linux
- Nokia N9 (MeeGo)
- Nokia N900 (Meemo)
- Samsung Z1
- Samsung Z3
- Android
- Samsung Galaxy S3
- Samsung Galaxy S4
- BSD
- iPhone 3GS
- iPhone 5
- Developer phones
- Linux
- Samsung RD-210
- Samsung RD-PQ
- Samsung TM1
- Tablets
- Android
- Samsung Galaxy Tab S 10.5
- Nexus 7
- BSD
- iPad Air 2
- SBCs
- Linux
- DragonBoard 410c
- Intel Curie
- Intel Edison
- Intel NUC
- Minnowboard Max
- Odroid XU4
Running¶
Running eth without any argument will synchronise your node to the public blockchain. It is also possible to create or synchronise to another blockchain (see custom blockchain using eth).
Interacting with your node can be done using either geth or the ethereum console:
Using geth
> geth attach //attach geth to a running eth node.
Using the ethereum console
The ethereum console is a node.js application which connect to a running eth/geth node and provide access to the web3 object.
It can be installed using npm:
注解
注解
go-ethereum¶
go-ethereum客户端就是通常所说的 geth,它是一个用Go语言实现的以运行完整的以太坊节点的命令行接口。通过安装和运行geth,你可以加入以太坊Frontier网络进行以下活动:
- 通过挖矿得到ether(以太坊代币,译者注)
- 在各个地址之间转移资金
- 创建合约并发送交易数据
- 查阅区块历史数据
- 更多其他事情
相关资源:
pyethapp¶
pyethapp 是一个以太坊加密经济学状态机的基于python语言的实现。它旨在提供一个可以轻松破解和扩展的代码库。
pyethapp 基于以下两个以太坊核心组件实现:
- pyethereum - 核心库,提供区块链特性、以太坊虚拟机(EVM)和挖矿功能
- pydevp2p - p2p网络代码库,提供基于多路复用加密连接的节点发现和多种服务传输
相关资源:
ethereumjs-lib¶
ethereumjs-lib 是一个实现了 黄皮书 中描述的 以太坊 主要功能的JavaScript库。这是一个提供了以下模块入口的元模块。绝大多数js模块都在 ethereumjs 中跟踪记录。
- VM - 以太坊虚拟机和状态处理功能
- Blockchain - 区块链管理
- Block - 区块概要定义和校验
- Transaction - 交易概要定义和校验
- Account - 账户概要定义和校验
- rlp - 递归段前缀序列化(Recursive Length Prefix serialization)
- Trie - 改进的梅克尔前缀树(Modified Merkle Patricia Tree)
- Ethash - 以太坊的工作量证明算法
- utils - 多种工具辅助函数
- devp2p - 网络协议
- devp2p-dpt - 竞争节点表(The disputed peer table)
相关资源:
- GitHub: https://github.com/ethereumjs/ethereumjs-lib
- Join the Gitter chat: https://gitter.im/ethereum/ethereumjs-lib
Ethereum(J)¶
Ethereum(J) 是以太坊协议的纯Java实现。它提供了一个支持以太坊协议和所有子服务的库,可以嵌入任何Java/Scala(一种类似于Java的多范式编程语言,译者注)项目。Ethereum(J) 起初由 Roman Mandeleil 开发,现在由 <ether.camp> 资助。
Ethereum(J) 支持CPU挖矿,它由纯Java语言实现,可以在私有或测试网路中使用。你甚至可以用它在实际的以太坊网络中进行挖矿,虽然效率上并不优秀。
相关资源:
- 博客: http://ethereumj.io/
- GitHub: https://github.com/ethereum/ethereumj
- Gitter chat: https://gitter.im/ethereum/ethereumj
ethereumH¶
这是一个用Haskell语言写的工具包,你可以用它连接到以太坊区块链。
相关资源:
- GitHub: https://github.com/blockapps/ethereumH
- BlockApps: http://www.blockapps.net/
Parity¶
Parity 生成是世界上最快、最轻量的以太坊客户端。它有Rust语言写成,提供了改良的可靠性、性能和代码清晰度。Parity由 Ethcore 开发,由以太坊基金会的多个成员资助。
- 官网: https://ethcore.io/parity.html
- GitHub: https://github.com/ethcore/parity
- Gitter chat: https://gitter.im/ethcore/parity
Arch Linux版本的包由 Afri Schoedon 和quininer(一个Github项目,译者注)进行社区维护。
- https://aur.archlinux.org/packages/parity/ (stable, latest release)
- https://aur.archlinux.org/packages/parity-git/ (unstable, latest develop)
也有报道提到一些人在Raspberry Pi 2(一款基于Linux的单板机电脑,译者注)上成功运行了Parity。
ruby-ethereum¶
ruby-ethereum 是一个用Ruby语言写的 以太坊虚拟机 实现。
相关资源:
其他:
- ruby-serpent: Ruby binding to the Ethereum Serpent compiler.
- ethereum-ruby: a pure-Ruby JSON-RPC wrapper for communicating with an Ethereum node.
连接到以太坊客户端¶
以太坊客户端通过 JSON-RPC 的方式暴露了很多方法来与应用程序进行交互。然而对于应用开发者而言,直接通过JSON-RPC进行交互会有一些额外的负担,比如:
- JSON-RPC协议的实现
- 创建智能合约和与智能合约交互所需的二进制码的编码/解码
- 256位的数值类型处理
- 一些管理功能的支持 - 比如创建/管理地址、对交易进行签名等
于是一些相关功能库被开发出来帮助解决这些问题,使应用开发者能专注于他们的应用程序,而不是去花时间进行与以太坊客户端乃至生态系统交互管道疏通上的一些基础性工作。
Library | Language | Project Page |
---|---|---|
web3.js | JavaScript | https://github.com/ethereum/web3.js |
web3j | Java | https://github.com/web3j/web3j |
Nethereum | C# .NET | https://github.com/Nethereum/Nethereum |
ethereum-ruby | Ruby | https://github.com/DigixGlobal/ethereum-ruby |
每个工具库的介绍请参考以下章节:
web3.js¶
web3.js
这是实现了 Generic JSON RPC 的以太坊兼容 JavaScript API 。它可以作为npm上的node模块,作为bower的可嵌入js模块以及meteor.js的一个包。
相关资源:
web3j¶
web3j
web3j是一个轻量级的Java库以支持与以太坊网络上的客户端(节点)进行集成。
- 核心特性:
- 以Java语言的类型,通过JSON-RPC与以太坊客户端进行交互
- 支持所有的JSON-RPC方法类型
- 支持所有的Geth和Parity中用于管理账户及签署交易的方法
- 传输客户端请求时支持同步和异步两种方式
- 可以根据Solidity ABI文件自动生成Java智能合约方法的包装(Java smart contract function warpper)
现在支持 go-ethereum 和 Parity 客户端。
相关资源:
- GitHub: https://github.com/web3j/web3j
- Website: http://web3j.io
- Wiki: https://github.com/web3j/web3j/wiki
- Gitter: https://gitter.im/web3j/web3j
Nethereum¶
Nethereum
Nethereum是以太坊的.Net集成库,它使你可以通过RPC与 go-ethereum 、 cpp-ethereum 或 Parity 等以太坊客户端进行交互。
这个库,从功能上与javascript语言的Web3 RPC客户端库非常接近。
随着JSON RPC/IPC方法在客户端上出现,它们就会在这里实现。
geth客户端是被严格的支持和测试的,包含它在管理员、个人、调试和挖矿等功能的管理扩展。
像发布、方法调用、交易、事件过滤以及出题解码等与合约的交互都已经被简化了。
这个库在所有平台上都进行了测试,包括.Net Core、Mono、Linux、iOS、Android、Raspberry PI和Xbox,当然也有Windows。
相关资源:
- GitHub: https://github.com/Nethereum/Nethereum
- Website: http://nethereum.com
- Documentation: https://nethereum.readthedocs.io/en/latest/
- Gitter: https://gitter.im/Nethereum/Nethereum
ethereum-ruby¶
ethereum-ruby 用来与以太坊节点通信的纯Ruby的JSON-RPC包装。要是用这个库,你需要运行一个打开了IPC(Inter-Process Communication,即进程间通信,译者注)支持(默认的)的以太坊节点。目前支持 go-ethereum 客户端。
相关资源:
关于通过使用web3.js进行智能合约的创建和交互的总体介绍,请参考 访问合约和交易 。
账户管理¶
账户¶
账户在以太坊中扮演了一个核心角色。账户有两种类型: externally owned accounts (EOAs,即外部拥有的账户,译者注)和 contract accounts (合约账户,译者注)。这里我们聚焦在外部拥有的账户上,简称为 账户 。合约账户将被简称为 合约 ,在 合约的章节里详细讨论 。结合外部拥有的账户和合约,这个概念上的账户实体可以归结为 状态对象 。 这些实体是有状态的:账户有余额,合约账户既有余额也有合约数据的存储。所有账户的状态,就是一个以太坊网络中伴随着每个区块的更新所达成共识的状态。账户就是所有的实际用户通过交易与以太坊进行交互的必需媒介。
如果我们把以太坊限定为只有外部拥有的账户,只允许它们之间的交易,那我们就做成了一个“altcoin”(即山寨币,译者注)系统,本身并不如比特币网络强大,只能用来交易以太币。
账户代表着外部代理人的实体(比如真人用户、挖矿的节点或自动化的代理等)。账户使用公钥加密的方法对交易进行签名,以便EVM可以安全的校验交易发送者的身份。
秘钥文件¶
每个账户都由一对秘钥所定义,就是私钥和公钥。账户根据由其公钥的后20字节导出的 地址 进行索引编排。每一个私钥/地址对被编码在一个 秘钥文件 中,这个文件是JSON格式的文本文件,可以用任意文本编辑器修改。你账号的私钥是你的秘钥文件中最紧要的内容,它会由你创建账号时输入的密码进行加密处理。秘钥文件保存在你本地节点的data目录的 keystore
子目录下。请确保有定期备份你的秘钥文件。更多信息请参考 备份和恢复账户 。
创建一个秘钥就相当于创建了一个账户。
- 你不需要告诉任何人你做了这件事
- 你不需要和区块链做任何同步
- 你不需要运行一个客户端
- 你甚至不需要接入互联网
当然,你的新账户不会包含任何以太币;但它已经是你的了。没有你的秘钥和密码,任何人都无法访问它。
在以太坊节点间拷贝单独的秘钥文件乃至整个目录是安全的。
警告
请注意,如果你从其他节点添加了秘钥文件,账户的顺序可能会变化。所以请确保你没有在脚本或代码段中依赖或改变账户的索引。
创建账户¶
警告
记住你的密码并备份你的秘钥文件。 你必须同时拥有秘钥文件和密码才能从一个账户中发起交易,包括发送以太币。请绝对地确保你有一个秘钥文件的拷贝并记住它的密码,把它们尽可能安全的保存。如果你丢失了秘钥文件或者忘记了你的密码,你将会失去账户中的所有以太币,这里没有任何迂回的方法。没有密码,想访问你的账户是不可能的,这里并没有 忘记密码 这样的选项。所以请别忘了它。
使用 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}
你也可以使用非交互方式来使用这个命令,只需要为 --password
选项增加一个纯文本密码文件的参数即可。文件内容直接为密码文本,也可以在最后加一个换行。
$ geth --password /path/to/password account new
警告
--password
选项应该仅在可信环境中做测试或自动化时使用。把你的密码存到文件里或用其他方式暴露,通常不是个好主意。如果你一定要使用这个选项,请保证没有其他人能访问保存密码的文件。你可以在Mac/Linux系统中用以下方法实现这点。
touch /path/to/password
chmod 600 /path/to/password
cat > /path/to/password
>I type my pass
在 geth account
命令后加上 list
子命令,即可列出你的 keystore
目录下保存的所有账户信息。
$ geth account list
account #0: {a94f5374fce5edbc8e2a8697c15331677e6ebf0b}
account #1: {c385233b188811c9f355d4caec14df86d6248235}
account #2: {7f444580bfef4b9bc7e14eb7fb2a029336b07c9d}
账户信息文件的文件名格式为: UTC--<created_at UTC ISO8601>-<address hex>
。列表中数据的显示顺序是以字母为序,但因为时间戳是在最前边的,所以实际上就是以创建时间为序。
使用geth控制台¶
要使用geth,我们必须先用控制台模式启动geth。(或者你可以使用 geth attach
把geth关联到一个已经运行的控制台。)
> geth console 2>> file_to_log_output
instance: Geth/v1.4.0-unstable/linux/go1.5.1
coinbase: coinbase: [object Object]
at block: 865174 (Mon, 18 Jan 2016 02:58:53 GMT)
datadir: /home/USERNAME/.ethereum
控制台是你可以通过命令行的方式访问你的本地节点的地方。例如,你可以用以下命令列出你的账户。
> eth.accounts
{
code: -32000,
message: "no keys in store"
}
以上结果显示出你还没有账户。你可以在控制台创建账户。
> personal.newAccount()
Passphrase:
Repeat passphrase:
"0xb2f69ddf70297958e582a0cc98bce43294f1007d"
注解
记住:要使用安全性高、最好有随机性的密码。
我们刚刚创建了第一个账户。如果再尝试列出账户的话,我们就能看到这个新账户。
> eth.accounts
["0xb2f69ddf70297958e582a0cc98bce43294f1007d"]
使用Mist以太坊钱包¶
由于普通用户对命令行的厌恶,现在有了个基于GUI(图形用户界面)的方法:“官方的”Mist以太坊钱包。Mist以太坊钱包和它的双亲Mist项目是由以太坊基金会所资助的,所以也就有了“官方的”说法。钱包应用程序支持Linux、Mac OS X和Windows操作系统。
警告
Mist钱包仍是个Beta版本,请意识到你需要自行承担相关风险。
使用GUI的Mist以太坊钱包创建账户不能再简单了。事实上,你的第一个账户已经在安装过程中创建出来了。
1、为你的操作系统 下载最新版的钱包应用 。因为实际上你是在运行一个geth全节点,所以第一次打开钱包应用时会触发一次与以太坊区块链的完全同步过程。
2、解压下载的文件,运行以太坊钱包可执行文件。

3、等待区块链的完全同步,然后跟随页面向导完成设置,你的第一个账户也会被创建出来。
4、当你第一次运行Mist以太坊钱包的时候,你会看到在安装过程中创建的账户。它会被默认的命名为 MAIN ACCOUNT (ETHERBASE)。

5、创建额外的账户很容易,你只需要在应用界面中点击“ADD ACCOUNT”并输入密码即可。
注解
Mist钱包还在不断开发更新中,所以以上步骤也许会有变动。
在Mist中创建一个多重签名(Multi-Signature)的钱包¶
Mist以太坊钱包有一个选项,可以使用多重签名的钱包来保护你的钱包余额。多重签名钱包的好处就是当从你的账户余额中取出较大数额的结余时,需要多个账户的共同授权。为了使用多重签名钱包,你需要创建多个账户。
在Mist中创建账户文件非常简单。在’Accounts’中点击’Add Account’,选择一个容易记住的强密码(记住,没有忘记密码的选项),确认,你的账户就创建出来了。至少创建两个账户。第二个账户也可以创建到另外一台独立的计算机上(这么做,理论上更安全)。要创建多重签名钱包,你只需要第二个账户的公钥(账户地址,最好拷贝/粘贴,不要用手工录入,以免出错)。你的主账户会被用来创建多重签名的钱包合约,它应该在你想要创建多重签名钱包的计算机上。
现在你已经安全的创建了你的账户,记得备份它们。(如果你没做备份,一旦你的计算机坏掉,你讲失去你的所有账户余额。)在顶部菜单点击’Backup’选择’keystore’文件夹,选中它用拷贝命令(不要用剪切,这非常糟糕)。然后切换到桌面,右击空白区域,选择粘贴。你也许应该把这个新的’keystore’文件夹改名为’Ethereum-keystore-backup-year-month-day’,这样你以后可以很快的找到它。这时,你也可以把这个目录添加到一个zip/rar压缩包(甚至给压缩包加上密码,如果你要把它保存到线上的话),保存到U盘、刻录到CD或者上传到云存储服务中(比如Dropbox,Google Drive之类)。
你现在应该至少添加0.02以太币到你的主账户中(就是你要用来创建多重签名钱包的账户),这是你创建多重签名钱包所需的交易费。此外还需要1以太币以上的余额,因为Mist需要这个余额来确保有足够的’gas’来执行钱包中的合约交易。所以对于新用户来讲,你至少要有1.02以上的以太币。
当你创建一个多重签名钱包时,你需要输入与其关联的所有账户地址。建议你从Mist中各个账户的详情界面中拷贝/粘贴这些地址到一个文本编辑器(用记事本、kedit之类)。请不要手工输入这些地址,以免因为输入错误致使交易被发送到错误的地址而使你损失掉你的账户余额。
我们现在已经可以来创建多重签名钱包了。在’Wallet Contracts’下选择’Add Wallet Contract’,给它起个名字,选择账户的拥有者,选择’Multisignature Wallet Contract’,你将看到类似下面这样的消息:
“This is a joint account controlled by X owners. You can send up to X ether per day. Any transaction over that daily limit requires the confirmation of X owners.”
设置你想关联到这个多重签名钱包的任意数量的拥有者(账户),设置一个每日提取的上限(单独账户的提取数额),以及需要多少账户来批准超过这个上限的提取。
现在,把刚刚拷贝/粘贴到文本编辑器中的账户地址添加进来,确认所有的设置,然后点击下方的’Create’按钮。你需要输入你的账户密码来发送交易。而后就可以在’Wallet Contracts’中看到这个新钱包的状态为’creating’。
当钱包创建成功之后,你将可以看到合约地址。选中这个地址,把它拷贝/粘贴到文本编辑器,保存成新的文本文件’Ethereum-Wallet-Address.txt’或者任何你喜欢的名字。
现在,你要做的就是备份这个文件,就像你备份账户文件一样,之后你就可以在Eth中用这个地址加载你的多重签名钱包了。
如果你要恢复你的备份,可以简单的将’Ethereum-keystore-backup’拷贝回’keystore’目录,就像本节第一段讲的那样。如果在一台没有安装过Mist的计算机上全新安装Mist的话,你可能需要手工创建’keystore’目录。当我们要恢复一个多重签名钱包时,不用像我们之前创建它那样选择’Multisignature Wallet Contract’,我们可以直接选择’Import Wallet’。
故障排除:
- Mist没有同步。一个方案是通过NTP服务同步你的本地计算机硬件时间,然后重启。
- Mist在同步之后启动了,但却显示了一个空白界面。如果你是在使用一个基于Linux的操作系统(比如Ubuntu,Linux Mint之类)在运行第三方的视频驱动程序,那你可以试试安装厂商官方的视频驱动程序。
- “Wrong password”提示。这应该是Mist当前版本的一个错误提示。重启Mist,这个问题应该就消失了(当然,你要输入正确的密码)。
使用Eth¶
geth中与秘钥管理相关选项都可以在eth中以同样的方式使用。
以下是与账户相关的选项:
> eth account list // List all keys available in wallet.
> eth account new // Create a new key and add it to the wallet.
> eth account update [<uuid>|<address> , ... ] // Decrypt and re-encrypt given keys.
> eth account import [<uuid>|<file>|<secret-hex>] // Import keys from given source and place in wallet.
以下是与钱包相关的选项:
> eth wallet import <file> //Import a presale wallet.
注解
‘account import’仅能用来导入通用的秘钥文件。’wallet import’选项只能用来导入预售的钱包。
通过集成的控制台也是可以进行秘钥管理的(比如内置的控制台或者geth关联的):
> web3.personal
{
listAccounts: [],
getListAccounts: function(callback),
lockAccount: function(),
newAccount: function(),
unlockAccount: function()
}
使用EthKey(将不再支持)¶
EthKey是个用C++实现的CLI(Command Line Interfaces,即命令行交互接口,译者注)工具,使你可以与以太坊钱包进行交互。你可以用它列出、核对、创建、删除和修改秘钥,也可以对交易进行核对、创建和签名。
我们假定你没有运行一个像eth这样的客户端或者其他的Aleth系列的客户端,如果有,你可以跳过这段。 要创建一个钱包,可以使用``ethkey``的``createwallet``命令:
> ethkey createwallet
请输入一个“超级管理员”密码来保护你的秘钥(让密码很健壮,即很难猜到,译者注): 你会被要求输出“超级管理员”密码,它将保护你的隐私,作为你的所有秘钥的缺省密码。你需要再同样输入一次以确认密码。
注解
使用一个安全性高、最好有随机性的密码。
我们可以简单地用以下命令列出所有秘钥:
> ethkey list
No keys found.
它告诉我们,还没有创建任何秘钥。我们接下来将创建一个。
我们可以用``new``命令创建秘钥。使用这个命令,我们必须指定一个名字,就是在钱包里的账户名字。让我们把它叫做“test”。
> ethkey new test
输入一个密码来保护这个账户(或者不输入,使用“超级管理员”密码)。 系统会提示你输入密码来保护这个秘钥,如果你直接按回车,它就将使用缺省的“超级管理员”密码。通常,这样的做就使你使用这个密钥时不再需要输入密码(因为系统记住了“超级管理员”密码)。 一般来讲,你应该使用不同的密码以保护你的账号,当一个密码被破解之后不会导致其他账户也被访问;但出于使用上的方便,对于一些不太重要的账户,你也许会决定使用同一个密码。
这里,让我们用一个极富想象力的密码‘123’。(除了对于临时的测试账户,永远不要使用这么简单地密码。) 输入密码之后,系统会要求你再确认,所以再输入一次‘123’。 这里还需要你提供一个密码提示信息,它将会在要求你输入密码时显示。这个提示也会保存在钱包中,并由“超级管理员”密码所保护。这里我们使用一个极其糟糕的提示“321 backwards”(把321倒过来)。
> ethkey new test
Enter a passphrase with which to secure this account (or nothing to use the master passphrase):
Please confirm the passphrase by entering it again:
Enter a hint to help you remember this passphrase: 321 backwards
Created key 055dde03-47ff-dded-8950-0fe39b1fa101
Name: test
Password hint: 321 backwards
ICAP: XE472EVKU3CGMJF2YQ0J9RO1Y90BC0LDFZ
Raw hex: 0092e965928626f8880629cec353d3fd7ca5974f
所有正常的ICAP(即Inter Exchange Client Address Protocol,译者注)地址都会由‘XE’开头,这样你可以很容易的辨认出来。同时也请注意,这个秘钥还有一个额外的标识,也就是所谓的UUID(即Universal Unique Identifier,译者注)。这是一个秘钥的统一唯一标识,不会对账户有任何影响,也不会帮助攻击者揭示任何关于你本人的信息。它也会反映到可以在~/.web3/keys(Mac or Linux)或$HOME/AppData/Web3/keys(Windows)目录下找到的秘钥文件名上。 现在我们列出钱包中的的秘钥,确认它已经创建好了。
> ethkey list
055dde03-47ff-dded-8950-0fe39b1fa101 0092e965… XE472EVKU3CGMJF2YQ0J9RO1Y90BC0LDFZ test
这里会每行显示一个秘钥。在上边的例子中,秘钥会保存在文件【055dde…】中,ICAP地址为【XE472EVK…】。显然这很难记住,于是它还有个简单的名字“test”。
导入预售钱包¶
使用Mist以太坊客户端¶
使用Mist以太坊钱包的GUI来导入预售钱包非常容易。事实上在安装过程中你就会被询问是否需要导入预售钱包。
警告
Mist钱包仍是个beta版本的软件,请意识到相关风险需要由你自行承担。
关于安装Mist以太坊钱包请参考之前的章节 使用Mist以太坊钱包创建账户 。
你可以简单地拖拽你的 .json
预售钱包文件到指定的区域,输入你的密码来导入你的预售账户。

如果你没有在安装客户端时导入预售钱包,你也可以在任何时候从 Accounts
菜单中选择 Import Pre-sale Accounts
来做这件事。
注解
Mist钱包仍然在持续开发,所以以上说明的细节可能会有所更改。
使用geth¶
如果你有个独立的geth安装,你可以通过如下命令完成预售钱包的导入:
geth wallet import /path/to/my/presale-wallet.json
你会被要求输入密码。
更新一个账户¶
你可以更新你的秘钥文件到最新的秘钥文件格式,或更改秘钥文件的密码。
使用geth¶
你可以使用 update
子命令,带上账户地址或索引作为参数来更新一个既有账户。记住,账户的索引反映了账户的创建顺序(包含了时间信息的秘钥文件名的字母顺序)。
geth account update b0047c606f3af7392e073ed13253f8f4710b08b6
或者
geth account update 2
例如:
$ geth account update a94f5374fce5edbc8e2a8697c15331677e6ebf0b
Unlocking account a94f5374fce5edbc8e2a8697c15331677e6ebf0b | Attempt 1/3
Passphrase:
0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b
account 'a94f5374fce5edbc8e2a8697c15331677e6ebf0b' unlocked.
Please give a new password. Do not forget this password.
Passphrase:
Repeat Passphrase:
0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b
账户会被用加密格式保存为新的版本,你会被询问相应的密码以解锁账户,而后要输入一个新密码来保护更新后的文件。相同的方法也适用于将一个不再支持的秘钥文件格式更新为最新,或者修改账户的密码。
你也可以使用 --password
选项来指定密码文件,而不再手工输入密码。
geth --password <passwordfile> account update a94f5374fce5edbc8e2a8697c15331677e6ebf0bs
由于只能指定一个密码文件,所以这种方式仅可用于更新账户秘钥文件格式,如果要修改密码,只能使用两次交互的方式。
注解
账户更新会有个副作用,就是会导致你的账户顺序变化。在一次更新完成之后,更新的这个秘钥所有之前版本的文件都会被删除。
备份和恢复账户¶
手工备份/恢复¶
你必须拥有一个账户的秘钥文件来使你可以从这个账户中发送交易。秘钥文件可以在以太坊节点目录下的【keystore】子目录下找到。各平台中缺省的数据目录位置如下:
- Windows:
C:\Users\username\%appdata%\Roaming\Ethereum\keystore
- Linux:
~/.ethereum/keystore
- Mac:
~/Library/Ethereum/keystore
要备份秘钥文件(账户),可以拷贝 keystore
目录下的文件,或者直接整个拷贝 keystore
目录。
要恢复秘钥文件(账户),把秘钥文件拷贝回 keystore
目录即可。
导入非加密的私钥¶
geth
支持导入一个非加密的私钥。
geth account import /path/to/<keyfile>
这个命令会从文本文件 <keyfile>
导入一个非加密的私钥,创建一个新账户并打印其地址。
这个秘钥文件应该包含转换为16进制的合法的EC(Ellipse Curve,即椭圆曲线,译者注)字节数据(也就是由椭圆曲线加密算法生成的原始私钥二进制数值的16进制表示,译者注)。
账户会被保存为加密格式,你会被要求输入一个密码。请务必记住这个密码以便以后能解锁你的账户。
以下是一个指定了数据目录的例子。如果未使用 --datadir
选项,新账户会被创建到缺省的数据目录,秘钥文件会保存在 keystore
子目录下。
$ geth --datadir /someOtherEthDataDir account import ./key.prv
The new account will be encrypted with a passphrase.
Please enter a passphrase now.
Passphrase:
Repeat Passphrase:
Address: {7f444580bfef4b9bc7e14eb7fb2a029336b07c9d}
你也可以使用 --password
选项指定密码文件。
geth --password <passwordfile> account import <keyfile>
注解
由于你可以直接拷贝你的加密账户到不同的以太坊节点,所以这种导入/导出操作在这种情况下就不需要了。
警告
当你拷贝秘钥文件到某个节点的 keystore
目录下时,账户的顺序可能会发生变化。所以请确保你没有在脚本中依赖账户的顺序,或者仔细检查并更新脚本中使用的索引。
以太币¶
以太币是什么?¶
以太币(Ether)就是以太坊中使用的虚拟货币的名字,它被用来为EVM中的计算付费。这是在为购买以太币的气(gas)时间接完成的,就像在 gas 那节中所解释的那样。
单位面额¶
为了使用以太币,以太坊有个面额计量体系。每个计量单位都有个唯一的名称(其中一些是在计算机科学及加密经济学领域中的标志性人物的姓氏)。其中,最小的计量单位,也就是以太币的 基础单位 叫做Wei。以下是已命名的面额单位以及它们与Wei的兑换关系。请注意,尽管有很多误解,但以太坊并不是个货币名称或者计量单位。
Unit | Wei Value | Wei |
---|---|---|
wei | 1 wei | 1 |
Kwei (babbage) | 1e3 wei | 1,000 |
Mwei (lovelace) | 1e6 wei | 1,000,000 |
Gwei (shannon) | 1e9 wei | 1,000,000,000 |
microether (szabo) | 1e12 wei | 1,000,000,000,000 |
milliether (finney) | 1e15 wei | 1,000,000,000,000,000 |
ether | 1e18 wei | 1,000,000,000,000,000,000 |
以太币的供给¶
- https://blog.ethereum.org/2014/04/10/the-issuance-model-in-ethereum/
- https://www.reddit.com/r/ethereum/comments/44zy88/clarification_on_ether_supply_and_cost_of_gas/
- https://www.reddit.com/r/ethereum/comments/45vj4g/question_about_scarcity_of_ethereum_and_its/
- https://www.reddit.com/r/ethtrader/comments/48yqg6/is_there_a_cap_like_with_btc_with_how_many_ether/
得到以太币¶
为了获得以太币,你需要
去信任的服务¶
请注意,有了以太坊平台,基于智能合约的去信任服务,消除了对可信的第三方货币交换机构的需求,比如非居间投资的货币兑换业务。
这样的项目有:
- BTCrelay
- More information (about ETH/BTC 2-way peg without modifying bitcoin code).
- BTCrelay audit
- EtherEx decentralised exchange.
中心化的交易市场¶
Exchange | Currencies |
---|---|
Poloniex | BTC |
Kraken | BTC, USD, EUR, CAD, GBP |
Gatecoin | BTC, EUR |
Bitfinex | BTC, USD |
Bittrex | BTC |
Bluetrade | BTC, LTC, DOGE |
HitBTC | BTC |
Livecoin | BTC |
Coinsquare | BTC |
Bittylicious | GBP |
BTER | CNY |
Yunbi | CNY |
Metaexchange | BTC |
中心化的固定比率兑换¶
Exchange | Currencies |
---|---|
Shapeshift | BTC, LTC, DOGE, Other |
Bity | BTC, USD, EUR, CHF |
交易和价格分析¶
- ETH markets exhaustive listing by volume on coinmarketcap
- Aggregating realtime stats of major ETH markets:
在线钱包、纸质钱包和冷库¶
- Mist Ethereum Wallet
- Releases to download
- Mist Ethereum Wallet developer preview - foundation blog post
- How to easily set up the Ethereum Mist wallet! - Tutorial by Tommy Economics
- Kryptokit Jaxx
- Etherwall
- MyEtherWallet
- Cold storage
- Icebox by ConsenSys - Cold storage based on lightwallet with HD wallet library integrated.
- Reddit discussion 1
- How to setup a cold storage wallet
- Hardware wallet
- Brain wallet
- brain wallets are not safe, do not use them. https://www.reddit.com/r/ethereum/comments/45y8m7/brain_wallets_are_now_generally_shunned_by/
- Extreme caution with brain wallets. Read the recent controversy: https://reddit.com/r/ethereum/comments/43fhb5/brainwallets vs http://blog.ether.camp/post/138376049438/why-brain-wallet-is-the-best
发送以太币¶
以太坊钱包 支持通过图形用户界面发送以太币。
你也可以使用 geth控制台 传送以太币。
> var sender = eth.accounts[0];
> var receiver = eth.accounts[1];
> var amount = web3.toWei(0.01, "ether")
> eth.sendTransaction({from:sender, to:receiver, value: amount})
更多详情,请参考 账户类型、气和交易 。
在加密货币领域,以太坊是唯一使用以太币作为价值媒介的,这通常也就是指的“气(gas)”。除了交易费以外,气是作为网络中的每个请求的核心部分有发送者提供,由实际计算方消费的。气的消费成本是基于请求的复杂度和当前气的价格来动态计算的。从整体来看,气的价值在于维持以太币和以太坊的稳定以及长期需求。更多信息,请参考 账户类型、气和交易 。
气和以太币¶
- https://www.reddit.com/r/ethereum/comments/271qdz/can_someone_explain_the_concept_of_gas_in_ethereum/
- https://www.reddit.com/r/ethereum/comments/3fnpr1/can_someone_possibly_explain_the_concept_of/
- https://www.reddit.com/r/ethereum/comments/49gol3/can_ether_be_used_as_a_currency_eli5_ether_gas/
气被设计为网络资源/网络使用的固定成本。我们希望发送一个交易的实际成本都是一样的,所以我们不能期待发行的气,也就是一般意义上的货币,是不稳定的。
取而代之,我们发行价格可以浮动的以太币,同时也执行一个气与以太币的兑换价格。如果以太币的价格涨了,气和以太币的比价就将降低,以保证气的真实成本是一样。
气与多个概念相关联:气的价格、气的成本、气的上限和气费。气的本质是以太坊网络中交易或者计算成本的一种稳定的衡量。
- 气的成本是一个衡量计算成本的静态的数值,它的意图是使气的价值永远不变,所以其成本也就不随时间推移而变化。
- 气的价格是气相对于其他货币或代币的成本,比如以太币。为了稳定气的价值,气的价格是会随着代币或货币价格浮动而浮动的,以保持它的真实价值。气的价格会根据有多少用户希望消费以及有多少处理节点希望接收的平衡关系而计算出来。
- 气的上限是指每个区块中最多可以使用多少气,这也是一个区块的计算负载、交易数量或区块大小的最大值。矿工们可以随着时间推移修改缓慢地修改这个数值。
- 气费就是运行一个标准的交易或程序(也就是合约)所需要花费的气。一个区块的气费可以用来标识一个区块的计算负载、交易数量或区块大小。气费会被支付给矿工(或Pos中的绑定合约账户)。
以太坊网络¶
关于网络的相关信息。
连接到网络¶
以太坊网络¶
保持和保护区块链的相互协作的节点所组成的P2P(peer-to-peer)网络,是去中心化一致性的基础。参见 挖矿 。
以太坊网络状态¶
EthStats.net 是以太坊网络实时统计数据的仪表盘。它显示了一些重要的信息,比如当前区块、哈希难度、气的价格以及气的消耗。在这个页面显示的节点,仅是网络中实际节点的一部分。任何人都可以将他们的节点添加到这个仪表盘。 Eth-Netstats README on Github 记述了如何进行连接。
EtherNodes.com 显示以太坊主网络和最新测试网络中当前及历史节点统计以及一些其他信息。
当前活动网络的一些统计信息 - EtherChain上的实时状态信息。
公链、私有链和联盟链¶
目前,大多数以太坊项目都将以太坊作为一个提供了大量用户接入、网络节点、货币和市场的公共的区块链。然而,也通常会有些特定的原因,使人们也倾向于使用一个私有链或联盟链(某些内部相互信任的团体)。例如一些垂直领域的公司团体,像银行,正把以太坊视为他们自己的私有链的基础平台。
以下是一位发表了 On Public and Private Blockchains 的专家,根据访问权限的不同所给出的以上三种区块链的区别。
- 公链(Public blockchains):公链,是一个世界上的任何人都可以读取的,任何人都可以向它发送交易,并在交易合法之后就能被记录的区块链;并且世界上的任何人都可以参与到共识过程(一个决定哪个区块会被加到链上并反映当前数据状态的过程)。作为中心化/准中心化信任体系的替代,公链基于加密经济学原理确保其安全可信,即将经济学原理与加密校验相结合,使用工作量证明或权益证明算法,并基于一个抽象概念:一个人能对共识过程施加的影响的程度,是与他可以运用的经济资源的数量相称的。这些区块链通常被认为是“完全去中心化”的。
- 联盟链(Consortium blockchains):联盟链,是一个共识过程由预先确定好的若干节点来控制的区块链。例如,我们可以想象一个由15个金融机构所组成的联盟链,需要其中10个以上机构控制的节点签名承认某个区块才能使该区块有效。读取这个区块链的权限可以是公开的,或者限制为仅联盟成员,并且还可能有混合路由来访问。这种混合路由是指联盟链上节点的根哈希与特定的API一起公开,以使公共成员可以做某些特定的查询,取得关于区块链状态的某些数据。这些区块链可以被认为是“部分去中心化”的。
- 私有链(Private blockchains):私有链,是一个写入权限由中心化的某一个组织所控制的区块链。而读取权限可以是公开的或者任意扩展的。就像现在的大多数应用程序一样,数据库的维护和审计等等工作由一个单独的公司负责。这样,在很多情况下,公开的数据读取就完全没必要了,尽管也有一些情况会希望可以有公开的审计能力。
尽管这些私有链/联盟链也许没有到公链的连接,但他们依然可以通过资助以太坊软件的开发来共建以太坊生态系统。随着时间的推移,这些终将变为软件的改进、知识的分享以及相应的工作机会。
如何连接¶
Geth会不停地尝试连接到网络上其他节点直到连接到若干端点上。如果你的路由器允许UPnP连接,或者在一个有Internet连接的服务器上运行以太坊的话,它也会接受来自其他节点的连接请求。
Geth通过 发现协议(discovery protocol) 来找到其他节点。在发现协议中,节点间会互相通信以感知网络中的其他节点。为了相应的初始化,Geth会使用一些记录在源代码中的端点来找到一些引导节点。
检查连通性和ENODE ID¶
net
模块有两个属性可以告诉你当前客户端已经与多少端点相连接,以及你是否是监听节点。
> net.listening
true
> net.peerCount
4
使用 admin
对象的 peers()
函数来获取更多信息,比如IP地址、端口号以及所支持的协议。 admin.peers()
会返回当前已连接的所有节点信息。
> admin.peers
[{
ID: 'a4de274d3a159e10c2c9a68c326511236381b84c9ec52e72ad732eb0b2b1a2277938f78593cdbe734e6002bf23114d434a085d260514ab336d4acdc312db671b',
Name: 'Geth/v0.9.14/linux/go1.4.2',
Caps: 'eth/60',
RemoteAddress: '5.9.150.40:30301',
LocalAddress: '192.168.0.28:39219'
}, {
ID: 'a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c',
Name: 'Geth/v0.9.15/linux/go1.4.2',
Caps: 'eth/60',
RemoteAddress: '52.16.188.185:30303',
LocalAddress: '192.168.0.28:50995'
}, {
ID: 'f6ba1f1d9241d48138136ccf5baa6c2c8b008435a1c2bd009ca52fb8edbbc991eba36376beaee9d45f16d5dcbf2ed0bc23006c505d57ffcf70921bd94aa7a172',
Name: 'pyethapp_dd52/v0.9.13/linux2/py2.7.9',
Caps: 'eth/60, p2p/3',
RemoteAddress: '144.76.62.101:30303',
LocalAddress: '192.168.0.28:40454'
}, {
ID: 'f4642fa65af50cfdea8fa7414a5def7bb7991478b768e296f5e4a54e8b995de102e0ceae2e826f293c481b5325f89be6d207b003382e18a8ecba66fbaf6416c0',
Name: '++eth/Zeppelin/Rascal/v0.9.14/Release/Darwin/clang/int',
Caps: 'eth/60, shh/2',
RemoteAddress: '129.16.191.64:30303',
LocalAddress: '192.168.0.28:39705'
} ]
要检查Geth使用的端口以及你的enode URI,执行:
> admin.nodeInfo
{
Name: 'Geth/v0.9.14/darwin/go1.4.2',
NodeUrl: 'enode://3414c01c19aa75a34f2dbd2f8d0898dc79d6b219ad77f8155abf1a287ce2ba60f14998a3a98c0cf14915eabfdacf914a92b27a01769de18fa2d049dbf4c17694@[::]:30303',
NodeID: '3414c01c19aa75a34f2dbd2f8d0898dc79d6b219ad77f8155abf1a287ce2ba60f14998a3a98c0cf14915eabfdacf914a92b27a01769de18fa2d049dbf4c17694',
IP: '::',
DiscPort: 30303,
TCPPort: 30303,
Td: '2044952618444',
ListenAddr: '[::]:30303'
}
更快的下载区块链¶
当你启动以太坊客户端时,以太坊区块链就开始自动下载了。下载所消耗的时间将基于你的客户端、客户端设置、网络速度以及可用节点数而有很大不同。以下是一些可选项来更快的获得以太坊区块链。
使用geth¶
如果你使用geth客户端,会有些事情可以帮你提升下载以太坊区块链的时间。如果你使用 --fast
参数来进行快速同步,你将不会获取历史交易数据。
注解
在已经开始全部或部分普通同步处理之后,你就不能使用这个参数了。也就是说使用这个参数之前,你不应该做过任何以太坊区块链的数据分配处理。 更多信息请参考 Ethereum Stack.Exchange 的文章 。
以下是一些参数可以帮你更快的同步你的客户端数据。
--fast
这个参数允许快速同步数据状态,而不是下载整个区块数据。这也会极大的降低你本地的区块链数据大小。
注意: --fast
出于安全的考虑,该参数仅在你第一次同步区块链数据时可以使用。 更多信息请参考这个Reddit帖子 。
--cache=1024
以兆字节(MB)为单位的内部缓存大小。缺省为16MB,可以根据你的计算机内存容量增加到256、512、1024(1GB)或2048(2GB),这将会有较大的区别。
--jitvm
该参数将打开JIT VM(即Just-In-Time Virtual Machine,可以提高某些高频使用指令的执行效率,译者注)模式。
完整的命令行样例:
geth --fast --cache=1024 --jitvm console
更多关于快速同步和区块链下载次数的讨论, 请参考这篇Reddit帖子 。
静态节点、信任节点和引导节点¶
Geth支持一个叫做“静态节点”的特性。当你有若干固定的节点总是希望能连接到时,你可以使用静态节点在连接断开时自动重连。你可以在 <datadir>/static-nodes.json
中加入以下设置来配置永久的静态节点。(这个目录应该与你的 chaindata
和 keystore
目录在同一个目录下。)
[
"enode://f4642fa65af50cfdea8fa7414a5def7bb7991478b768e296f5e4a54e8b995de102e0ceae2e826f293c481b5325f89be6d207b003382e18a8ecba66fbaf6416c0@33.4.2.1:30303",
"enode://pubkey@ip:port"
]
你也可以在运行时使用 admin.addPeer()
命令通过JavaScript命令行添加静态节点。
> admin.addPeer("enode://f4642fa65af50cfdea8fa7414a5def7bb7991478b768e296f5e4a54e8b995de102e0ceae2e826f293c481b5325f89be6d207b003382e18a8ecba66fbaf6416c0@33.4.2.1:30303")
关于连通性的一般问题¶
有时你就是连接不上,最常见的原因可能是:
- 你的本地时间可能不正确。在以太坊网络中需要精确的时钟。查看你的操作系统如何同步时钟(例如
sudo ntpdate -s time.nist.gov
)因为即使只是快12秒,都有可能导致一个节点都找不到。 - 有些防火墙设置会屏蔽UDP数据广播。你可以使用静态节点特性或在控制台使用
admin.addPeer()
来手工配置连接。
你可以使用 --nodiscover
参数启动geth,使之不使用节点发现协议。只有在你正运行一个测试节点或者使用测试网络中的固定节点时你才需要这么做。
测试网络¶
Morden测试网络¶
Morden是一个公开的以太坊备选测试网络。它将在以太坊的Frontier到Homestead里程碑期间一直存在。
详情¶
除了以下参数外,所有参数都与以太坊主网络相同: All parameters are the same as the main Ethereum network except:
- 网络名称: Morden
- 网络标识: 2
- genesis.json (下边会给出)
- 初始账户Nonce(
IAN
)为2^20(而不是像之前的网络那样为0)- 在状态前缀树中的所有账户Nonce均 >=
IAN
。 - 每当一个账户被加入状态前缀树时,Nonce都会被初始化为 =
IAN
。
- 在状态前缀树中的所有账户Nonce均 >=
- 初始区块哈希:
0cd786a2425d16f152c658316c423e6ce1181e15c3295826d7c9904cba9ce303
- 初始状态前缀树根:
f3f4696bbf3b3b07775128eb7a3763279a394e382130f27c21e70233e04946a9
Morden的genesis.json¶
{
"nonce": "0x00006d6f7264656e",
"difficulty": "0x20000",
"mixhash": "0x00000000000000000000000000000000000000647572616c65787365646c6578",
"coinbase": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x",
"gasLimit": "0x2FEFD8",
"alloc": {
"0000000000000000000000000000000000000001": { "balance": "1" },
"0000000000000000000000000000000000000002": { "balance": "1" },
"0000000000000000000000000000000000000003": { "balance": "1" },
"0000000000000000000000000000000000000004": { "balance": "1" },
"102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }
}
}
配置一个本地的测试网络¶
eth(C++客户端)¶
可以使用 –genesis 和 –config 参数来连接或创建一个新的网络。
> eth --private "customChain" --config config.json --genesis genesis.json
也可以同时使用 –config 和 –genesis 。在这种情况下,由 –config 提供的初始区块描述会被 –genesis 选项的设定所覆盖。
--private //defines the name of the custom chain (optional).
--config <filename>
注解
<filename> 包含了一个网络信息的JSON描述:
sealEngine (挖矿引擎)
“Ethash” 是以太坊工作量证明引擎(被当前网络使用)。
“NoProof” 挖矿时不需要工作量证明。
params (网络的一般信息,比如minGasLimit、minimumDifficulty、blockReward、networkID)
genesis (初始区块描述)
accounts (设置账户/合约的初始状态)
这里是个Config样例(使用Olympic网络):
{
"sealEngine": "Ethash",
"params": {
"accountStartNonce": "0x00",
"frontierCompatibilityModeLimit": "0xffffffff",
"maximumExtraDataSize": "0x0400",
"tieBreakingGas": false,
"minGasLimit": "125000",
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x08",
"blockReward": "0x14D1120D7B160000",
"registrar": "5e70c0bbcd5636e0f9f9316e9f8633feb64d4050",
"networkID" : "0x0"
},
"genesis": {
"nonce": "0x000000000000002a",
"difficulty": "0x20000",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x",
"gasLimit": "0x2fefd8"
},
"accounts": {
"0000000000000000000000000000000000000001": { "wei": "1", "precompiled": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } },
"0000000000000000000000000000000000000002": { "wei": "1", "precompiled": { "name": "sha256", "linear": { "base": 60, "word": 12 } } },
"0000000000000000000000000000000000000003": { "wei": "1", "precompiled": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } },
"0000000000000000000000000000000000000004": { "wei": "1", "precompiled": { "name": "identity", "linear": { "base": 15, "word": 3 } } },
"dbdbdb2cbd23b783741e8d7fcf51e459b497e4a6": { "wei": "1606938044258990275541962092341162602522202993782792835301376" },
"e6716f9544a56c530d868e4bfbacb172315bdead": { "wei": "1606938044258990275541962092341162602522202993782792835301376" },
"b9c015918bdaba24b4ff057a92a3873d6eb201be": { "wei": "1606938044258990275541962092341162602522202993782792835301376" },
"1a26338f0d905e295fccb71fa9ea849ffa12aaf4": { "wei": "1606938044258990275541962092341162602522202993782792835301376" },
"2ef47100e0787b915105fd5e3f4ff6752079d5cb": { "wei": "1606938044258990275541962092341162602522202993782792835301376" },
"cd2a3d9f938e13cd947ec05abc7fe734df8dd826": { "wei": "1606938044258990275541962092341162602522202993782792835301376" },
"6c386a4b26f73c802f34673f7248bb118f97424a": { "wei": "1606938044258990275541962092341162602522202993782792835301376" },
"e4157b34ea9615cfbde6b4fda419828124b70c78": { "wei": "1606938044258990275541962092341162602522202993782792835301376" }
}
}
--genesis <filename> (optional if the config option is provided and contains the genesis description).
注解
<filename> 包含了一个初始区块的JSON描述,内容与‘config’参数提供的genesis字段相同:
{
"nonce": "0x000000000000002a",
"difficulty": "0x20000",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x",
"gasLimit": "0x2fefd8"
}
geth(Go客户端)¶
在一个私有测试网络中,你可以通过预生成或者自己挖矿的方式获得以太币。这是个尝试以太坊的性价比最高的方式,因为你不必自己在最新的测试网络中挖矿或者去寻找以太币来源。
- 需要在私有链中指定的主要配置是:
- 自定义Genesis文件(即初始区块信息,译者注)
- 自定义数据目录
- 自定义网络ID
- (推荐)禁止节点发现
Genesis文件¶
初始区块(创世区块)是区块链的开始 - 即第一个区块,区块0,并且是唯一一个没有前导区块的区块。基于协议,不会有其他节点批准你的区块链版本,除非它们也拥有同样的初始区块。所以你想创建多少私有测试网络就可以创建多少。
CustomGenesis.json
{
"nonce": "0x0000000000000042", "timestamp": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x0", "gasLimit": "0x8000000", "difficulty": "0x400",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x3333333333333333333333333333333333333333", "alloc": { }
}
保存一个文件叫做 CustomGenesis.json
,它将用来初始化你的geth节点,通过以下命令:
geth init /path/to/CustomGenesis.json
注解
geth默认会使用与公链主网络相同的目录。所以你需要使用 --datadir
来给测试网络指定一个单独的目录以避免公链数据被重置。
针对私有网络的命令行参数¶
有一些命令行选项(也可以叫做“标志”)是用来确保你的网络保持私有状态的。我们已经看过了genesis标志,但我们还需要一些。请注意,以下命令适用于geth以太坊客户端。
--nodiscover
使用这个选项以确保除非其他人手工添加你的节点,否则你的节点不会被自动发现。如果其它某个陌生人恰好使用了跟你同样的genesis文件和网络id,不使用这个选项,你的节点可能会被无端加入他们创建的区块链网络中。
--maxpeers 0
如果你不希望其他人连接到你的区块链,请使用这个选项。当然,如果你知道有多少节点会连接到你的网络,你也可以调整这个数字。
--rpc
这个选项会在你的节点上打开RPC接口。在Geth中这个选项是缺省打开的。
--rpcapi "db,eth,net,web3"
这个选项指定了哪些API可以通过RPC方式使用。缺省情况下,Geth允许web3接口。
重要:请注意,通过RPC/IPC方式提供API接口,将允许能访问到接口的所有人使用相应API(比如dapp’s,即去中心化应用)。请慎重地打开API。缺省地,Geth客户端允许通过IPC使用所有API,而通过RPC则只能使用db、eth、net和web3的API。
--rpcport "8080"
8080可以改为任何你网络中允许的端口。Geth的缺省端口是8080。
--rpccorsdomain "http://chriseth.github.io/browser-solidity/"
这个选项指定了哪些URL可以连接到你的节点来执行RPC客户端任务。请谨慎使用这个选项,指定一个特定的URL,而不是使用通配符(*)来允许所有URL连接到你的RPC实例。
--datadir "/home/TestChain1"
这个选项是指定你的私有链数据的存储目录。请选择你的以太坊客户端主目录以外的目录。
--port "30303"
这是“网络监听端口”,你可以用它来手工连接其他节点。
--identity "TestnetMainNode"
这将会给你节点加一个标识,以使它更容易的被标识在节点列表中。
以下是一个这些标识如何在网络中显示的例子。
启动 geth
¶
当你创建了自定义初始区块的JSON文件,并为你的区块链创建了数据目录之后,就可以使用以下命令访问geth:
geth --identity "MyNodeName" --rpc --rpcport "8080" --rpccorsdomain "*" --datadir "C:\chains\TestChain1" --port "30303" --nodiscover --rpcapi "db,eth,net,web3" --networkid 1999 init /path/to/CustomGenesis.json
注解
请把相关参数修改为适合你自己的配置。
它将会初始化你的初始区块。键入以下命令,就可以与geth进行交互了:
geth --identity "MyNodeName" --rpc --rpcport "8080" --rpccorsdomain "*" --datadir "C:\chains\TestChain1" --port "30303" --nodiscover --rpcapi "db,eth,net,web3" --networkid 1999 console
你每次要访问你的自定义链之前,你都需要使用自定义命令启动geth实例。如果你只用“geth”命令启动,它不会记住你的所有自定义选项。
javascript命令行中可使用的完整方法一览,请参考 the geth wiki on github 。
如果你已经运行了一个geth节点,你可以将其他geth实例与它联结在一起:
geth attach
现在你需要在测试网路中初始化一个新账户,并把它作为你的etherbase(接收挖矿奖励的地址)。
在javascript控制台输入:
personal.newAccount("password")
注解
把password替换为你的密码。
现在将它设定为etherbase:
miner.setEtherbase(personal.listAccounts[0])
如果成功,命令行会打印“true”。
最终你就可以开始挖矿了:
miner.start()
给你的账户预分配以太币¶
一个“0x400”的难度将允许你在你的私有测试链上快速挖出以太币。在你创建了你的链并开始挖矿之后,你会在数分钟内就拥有几百以太币,这将足够你在测试网络中执行交易了。如果你仍想给你的账户预分配以太币,你可以这样做:
1、在创建私有链之后创建一个新的账户 2、拷贝新账户的地址 3、将以下命令加到你的自定义初始区块文件中
"alloc":
{
"<your account address e.g. 0x1fb891f92eb557f4d688463d0d7c560552263b5a>":
{ "balance": "20000000000000000000" }
}
注解
将 0x1fb891f92eb557f4d688463d0d7c560552263b5a
替换为你的账户地址。
保存新的初始区块文件,重新运行你的私有链。一旦geth加载完毕,使用 . 关闭它。
我们要把一个地址分配到变量 primary
中,并检查它余额。
在你的终端上执行 geth account list
以确认你的新地址被分配到哪个账户上。
> geth account list
Account #0: {d1ade25ccd3d550a7eb532ac759cac7be09c2719}
Account #1: {da65665fc30803cb1fb7e6d86691e20b1826dee0}
Account #2: {e470b1a7d2c9c5c6f03bbaa8fa20db6d404a0c32}
Account #3: {f4dd5c3794f1fd0cdc0327a83aa472609c806e99}
确认哪个账户是你预分配了以太币的。
Take note of which account # is the one that you pre-allocated ether to.
或者你可以用 geth console
启动控制台(使用与开始启动 geth
时相同的参数)。提示符出现之后,输入:
> eth.accounts
它将返回你现在掌握的账户地址。
> primary = eth.accounts[0]
注解
把 0
替换为你的账户索引。这个命令将返回你的主以太坊地址。
输入以下命令:
> balance = web3.fromWei(eth.getBalance(primary), "ether");
这将会返回 7.5
,表明你的账户有很多以太币。我们在初始区块文件中指定了那么大数字的原因是余额字段使用的单位是wei,是以太坊货币维度中最小的单位(参见 以太币 )。
挖矿¶
引言¶
挖矿一词,源自针对加密货币的淘金行为。金子或者珍贵的金属是罕见的,数字代币也是一样,而挖矿是唯一能增加其数量的方式。这也同样适用于以太坊,发布交易的唯一模式就是挖矿。然而与这些例子不同的是,挖矿也是一种通过在区块链上创建、校验、发布和广播区块来确保网络安全方式。
- 挖以太币 = 确保网络安全 = 校验计算结果 (Mining ether = Securing the Network = Verifying Computation)
什么是挖矿?¶
以太坊与其他区块链技术一样,采用了一个动机驱动(incentive-driven)的安全模型。共识是通过选择总体难度值最高的区块来实现的。矿工产出的区块,由其他节点检查其合法性。在遵从数据格式的前提之下,只有当一个区块包含给定 难度(difficulty) 的 工作量证明(Proof of Work) 时,它才是合法的。注意,在以太坊的Serenity里程碑,这将被替换为 权益证明(proof of stake)模式 。
尽管以太坊区块链在很多方面都与比特币区块链相同,但还是有些其他的区别。从区块链架构上看,以太坊和比特币的主要区别在于以太坊的区块既包含了交易列表,也包含了最新的状态信息(通过merkle patricia树的根节点哈希来对状态信息编码以使其更加精确,merkle patricia树是一种改进的二叉树,可以确保每个叶子节点的变化都会导致根节点哈希变化,从而可以精确地判断整个树上数据的状态是否有变动,译者注)。除此之外,区块号和难度值也会被存储到区块中。
以太坊使用的工作量证明(Proof of Work)算法被称为 Ethash ( Dagger-Hashimoto algorithm 的修改版本)包含了为算法找到一个 随机数(nonce) 输入以确保计算结果满足当前的难度限定。PoW算法的关键是没有比枚举所有的可能来找到这样的随机数更好的方式,尽管验证答案是简单容易的。由于输出结果有一个统一的分布(因为他们都是哈希函数的输出结果),我们可以确保平均来讲,找到这个随机数所需要的时间是依赖于当前难度限定的。这就使通过控制难度值来控制区块产生的时间成为可能。
由协议所控制,难度值会自动调整,以使整个网络产生区块的平均时间在每15秒左右。我们称之为:网络用 15秒的区块时间 来生成区块链。这个“心跳”从基础上不断同步系统状态,并确保除非攻击者拥有超过全网挖矿能力一半的算力(即所谓的 51%攻击 ),否则想要维持一个分叉(来允许双花,即double spend,一个虚拟货币交易的关键问题,译者注)或让恶意用户篡改交易历史是不可能的。
任意参与到网络中的节点都可以成为矿工,他们挖矿的收入是与他们的挖矿能力或 哈希效率(hashrate) 成比例的,也就是每秒尝试计算随机数的次数与全网整体哈希效率的比例。
Ethash工作量证明是有 存储难度(memory hard) 的,以使它具有 ASIC抗性(ASIC,即Application Specific Integrated Circuit,指为特定目的设计的集成电路,在此指那些转为提供算力设计的特殊计算单元组,译者注) 。存储难度是由一个需要选择依赖于随机数和区块头的固定资源子集的工作量证明算法提供的。这些资源(一般为若干GB大小的数据)被称为 DAG 。每30000个区块,125小时的周期(被称为 epoch ,大概5.2天)之后, DAG 会花一点儿时间重新生成,与之前完全不同。由于DAG仅依赖于区块高度,所以它可以被预生成,而如果没有预生成,客户端则需要等待这个生成过程结束才能产生新的区块。如果客户端没有超前预生成DAG缓存,那么在每个epoch周期窗口可能会导致大量的区块延迟。而当客户端验证PoW结果的时候是不需要DAG的,以使那些CPU较差或存储较小的节点也可以进行验证处理。
作为一个特殊情况,当你从scratch(一个由麻省理工学院设计开发的编程工具,译者注)中启动节点的时候,仅当当前epoch对应的DAG创建完毕之后才能开始挖矿。
挖矿奖励¶
矿工依靠成功的工作量证明确认区块之后将收到:
- 为‘获胜的’区块提供的一份*固定的区块奖励*:5.0以太币
- 包含在区块中的扩展该区块所花费的气 - 基于当前气的价格换算的一定量以太币
- 因将uncles包含到区块中所产生的一份额外奖励,以每包含一个uncle就额外获得1/32的形式
对这个区块所包含的所有交易进行的计算中消耗的气,将由每个交易的发送者支付给挖到这个区块的矿工。根据共识协议,这些计算所引起的气的消耗会被记入矿工的账号。随着时间的推移,这将会减少固定的区块奖励。
Uncles 是一些废区块,也就是一些父区块是当前区块祖先(最多回溯6个区块)的区块。有效的uncle区块将被奖励,以抵消因网络延迟所产生的挖矿奖励差值,从而增加安全性。这也被称为幽灵协议,即GHOST(Greedy Heaviest Observed SubTree,译者注) Protocol。由成功的工作量证明矿工写入区块的uncle区块,会得到7/8的静态区块奖励(即4.375以太币)。每个区块最多允许有两个uncle。
挖矿的成功依赖于给定的区块难度。这个难度会动态的调整以控制整个网络的哈希能力来产生12秒区块时间。所以你找到区块的几率是由你所拥有的针对区块难度的哈希效率所决定的。
Ethash DAG¶
Ethash为工作量证明算法使用 DAG (Directed acycle graph,即无回路有向图,译者注),它会在每个 epoch 期间生成,也就是每30000个区块(125小时|5.2天)。生成DAG会花费较长时间。如果客户端只在需要时才生成它,那么你将会在每个新的epoch周期中第一个区块产生前看到一个很长的等待。然而由于DAG只与区块号有关,所以它可以,也应该被提前生成,以免在每个epoch期间都要等待较长时间。 geth
和 ethminer
客户端实现都会自动计算并维持两个DAG以使epoch切换可以顺畅地进行。当挖矿由控制台控制的时候,自动DAG生成是可以被打开和关闭的。当用 --mine
参数启动 geth
的时候,自动生成DAG是默认打开的。注意,客户端是共享DAG资源的,如果你在同时运行多个客户端实例,请确保只有其中一个打开了DAG自动生成设置。
要为任意一个epoch生成DAG:
geth makedag <block number> <outputdir>
比如 geth makedag 360000 ~/.ethash
。 注意,ethash使用 ~/.ethash
(Mac/Linux)或 ~/AppData/Ethash
(Windows)作为DAG文件以使其能在不同的客户端实例之间共享。
算法¶
我们使用的算法 Ethash (也就是被称为Dagger-Hashimoto的算法)是基于以组成DAG的巨大的、临时的、随机生成的数据集合(也就是Dagger的部分)为数据供应,来解决一个特定的限制条件(通过一个区块的头哈希来部分决定)的算法。
它被设计为可以在一个较慢的仅CPU环境中可以快速的进行哈希验证,同时可以在一个有大量内存及高带宽支持的环境中提供针对挖矿的巨大速度提升。巨大的内存需求意味着那些大规模集成的矿工相对而言仅会获得非常小的提升。高带宽需求意味着由众多超级计算单元所组成的但共享内存的方式,其速度提升较单一计算单元并不显著。这也是个重要的特性,使矿池挖矿对于那些进行验证的节点而言没有任何益处,从而阻碍了整个网络的中心化趋势。(也就是说,这种算法可以使最终提供合法区块的节点更多的分散到网络中的各个节点上,而不是趋向于集中在那些计算能力最强的节点上,译者注。)
外部挖矿应用和以太坊伺服机(Ethereum daemon)的协同工作,是通过JSON-RPC API实现的。这两个RPC函数是 eth_getWork
和 eth_submitWork
。
这些被正式地记录在 miner 之下的wiki文章 JSON-RPC API 之中。
你需要一个完全同步的允许挖矿的以太坊客户端和一个以太坊账号来开始挖矿。这个账号是用来接受挖矿报酬并且通常会被作为 coinbase 或 etherbase 。请访问 “创建账户” 这个章节来了解如何创建一个账号。
警告
在开始挖矿之前请确保你的区块链已经和主链完全同步,否则你将无法在主链上挖矿。
CPU挖矿¶
你可以使用你的计算机的CPU来挖取以太币。由于GPU矿工在计算速度和内存上都更有效,所以这不再能帮你赚到钱。但是,你可以在Morden测试网络或者私有网络使用CPU挖矿来创造你用于测试合约和交易的以太币,而不是在当前的主网络上花费真的以太币来做这些测试工作。
注解
测试网络的以太币除了测试目的以外别无它用。(参考 测试网络 。)
使用geth¶
当你使用geth启动你的以太坊客户端时,它并不会默认开始挖矿。要以CPU挖矿模式启动它,你需要使用 --mine
命令行选项 。你也可以同时使用 -minerthreads
参数来指定并行挖矿的线程数(默认会设定为CPU内核总数)。
geth --mine --minerthreads=4
你也可以使用 控制台 在运行时启动、停止CPU挖矿。 miner.start
接受一个用以指定矿工线程数的参数。
> miner.start(8)
true
> miner.stop()
true
请注意,如果你与真实网络同步,你才可以挖到真实的以太币(因为你会在达到共识的区块顶部挖矿)。区块链的下载/同步会推迟挖矿,挖矿会在同步完成之后自动开始,除非你用 miner.stop()
取消。
为了获取以太币,你必须有你的 etherbase (或 coinbase )地址。etherbase会默认使用你的主账号。如果你没有一个etherbase地址, geth --mine
将不会开始挖矿。
你可以在命令行设置你的etherbase:
geth --etherbase 1 --mine 2>> geth.log // 1 is index: second account by creation order OR
geth --etherbase '0xa4d8e9cae4d04b093aac82e6cd355b6b963fb7ff' --mine 2>> geth.log
你也可以在控制台重置你的etherbase:
miner.setEtherbase(eth.accounts[2])
请注意你的etherbase不需要是一个本地账号地址,只需要是一个存在的账号即可。
有一个选项可以为你挖到的区块 添加额外的数据 (仅32字节)。基于协议,这会被视为一个unicode字符串,所以你可以随意设定你的虚拟标签。
miner.setExtra("ΞTHΞЯSPHΞЯΞ")
...
debug.printBlock(131805)
BLOCK(be465b020fdbedc4063756f0912b5a89bbb4735bd1d1df84363e05ade0195cb1): Size: 531.00 B TD: 643485290485 {
NoNonce: ee48752c3a0bfe3d85339451a5f3f411c21c8170353e450985e1faab0a9ac4cc
Header:
[
...
Coinbase: a4d8e9cae4d04b093aac82e6cd355b6b963fb7ff
Number: 131805
Extra: ΞTHΞЯSPHΞЯΞ
...
}
你可以使用 miner.hashrate 检查你的哈希效率(hashrate),结果的单位是H/s(每秒的哈希操作数)。
> miner.hashrate
712000
当你成功挖到区块之后,你可以检查你的etherbase中的以太币余额。假设你的etherbase是一个本地账户:
> eth.getBalance(eth.coinbase).toNumber();
'34698870000000'
为了在交易中用气(gas)消费你的收入,你需要解锁这账户。
> personal.unlockAccount(eth.coinbase)
Password
true
你可以在控制台使用以下命令检查特定的矿工(地址)挖到了哪些区块:
function minedBlocks(lastn, addr) {
addrs = [];
if (!addr) {
addr = eth.coinbase
}
limit = eth.blockNumber - lastn
for (i = eth.blockNumber; i >= limit; i--) {
if (eth.getBlock(i).miner == addr) {
addrs.push(i)
}
}
return addrs
}
// scans the last 1000 blocks and returns the blocknumbers of blocks mined by your coinbase
// (more precisely blocks the mining reward for which is sent to your coinbase).
minedBlocks(1000, eth.coinbase);
//[352708, 352655, 352559]
请注意,你挖到一个区块,然而它并没有被当前的标准链所认可的情况(即其可能没有被包含在当前网络中的最长分叉上,译者注)是经常会发生的。这意味着,当你本地包含了你挖到的区块之后,当前状态会显示相应的挖矿报酬添加到你的账户,然而过了一段时间,不包含你的区块的更好的链(即更长的、被更多节点认可的分叉,译者注)被接受并切换到其上之后,你将不会实际获得挖矿报酬。也就是说,一个矿工会发现自己的coinbase余额非常可能会有一些上下浮动。
GPU挖矿¶
硬件¶
我们的算法是强内存(memory hard)的,以在内存中适配DAG,每个GPU都需要1到2GB内存。如果你收到 Error GPU mining. GPU memory fragmentation?
这样的消息,说明你没有足够的内存。GPU矿工是由OpenCL实现的,所以AMD的GPU回比同系列的NVIDIA的GPU快一些。ASIC(即Application Specific Integrated Circuit,特定应用的集成电路,译者注)和FPGA(即Field-Programmable Gate Array,一种半定制ASIC,译者注)则相对不够有效,所以不推荐。要获取针对你的芯片和平台的openCL,可以尝试:
Ubuntu Linux上的安装¶
你需要Ubuntu 14.04或15.04以及fglrx图形驱动来使用这个快速向导。你当然也可以使用NVidia驱动和其他平台,但你就需要自己找到可用的openCL了,比如 Genoil’s ethminer fork 。
如果你使用15.04,你可以在 “Software and Updates > Additional Drivers” 中设置 “Using video drivers for the AMD graphics accelerator from fglrx” 。
如果你使用14.04,你可以在 “Software and Updates > Additional Drivers” 中设置 “Using video drivers for the AMD graphics accelerator from fglrx” 。不幸的的是,这在有些人机器上会出现问题,因为一个已知的Ubuntu 14.04.02的bug,它会阻止你切换到这个特定的GPU挖矿所需的显示驱动上。
所以如果你遇到了这个bug,在你尝试其他方法之前,进入 “Software and updates > Updates” 选择 “Pre-released updates trusty proposed” 。然后回到 “Software and Updates > Additional Drivers” 再次设置 “Using video drivers for the AMD graphics accelerator from fglrx” 。重启之后,再检查下是否所需的驱动已经被安装好了(比如再进入 “Additional Drivers” 进行检查)。
无论你做什么,如果你在使用14.04.02版本,不要在设置好驱动后再更改驱动或更改驱动的设置。例如,使用 aticonfig –initial (特别是用-f、–force选项)会影响你的安装。如果你以外的更改了他们的配置,你将需要卸载这些驱动,重启并重新安装,然后再重启。
Mac上的安装¶
wget http://developer.download.nvidia.com/compute/cuda/7_0/Prod/local_installers/cuda_7.0.29_mac.pkg
sudo installer -pkg ~/Desktop/cuda_7.0.29_mac.pkg -target /
brew update
brew tap ethereum/ethereum
brew reinstall cpp-ethereum --with-gpu-mining --devel --headless --build-from-source
你应该检查温度状态:
aticonfig --adapter=0 --od-gettemperature
在geth中使用ethminer¶
geth account new // Set-up ethereum account if you do not have one
geth --rpc --rpccorsdomain localhost 2>> geth.log &
ethminer -G // -G for GPU, -M for benchmark
tail -f geth.log
ethminer
通过8545端口(geth中默认的PRC端口)与geth通信。你可以用 geth
的 --rpcport
来修改它。Ethminer会在所有端口上查找geth。注意,你需要用 --rpccorsdomain localhost
来设置CORS header。你也可以用 ethminer
的 -F http://127.0.0.1:3301
来设置端口。如果你需要在同一台机器上用多个实例挖矿,你就需要来设置端口了,虽然这有些不得要领(因为算法的强内存限制,多个矿工在同一机器上并不会更加有效,译者注)。如果你在私链上做测试,我们建议你使用CPU挖矿。
注解
你 不 需要在控制台中给 geth
指定 --mine
选项来开启挖矿,除非你希望使用CPU挖矿而不是GPU挖矿。
如果默认的 ethminer
没有正常工作,你可以使用``–opencl-device X`` X为{0, 1, 2, …}来尝试指定特定的openCL设备。当你用 -M
(benchmark,即性能评估模式,译者注)运行 ethminer
时,你会看到类似于下边这样的消息:
Benchmarking on platform: { "platform": "NVIDIA CUDA", "device": "GeForce GTX 750 Ti", "version": "OpenCL 1.1 CUDA" }
Benchmarking on platform: { "platform": "Apple", "device": "Intel(R) Xeon(R) CPU E5-1620 v2 @ 3.70GHz", "version": "OpenCL 1.2 " }
Debug geth
:
geth --rpccorsdomain "localhost" --verbosity 6 2>> geth.log
Debug矿工程序:
make -DCMAKE_BUILD_TYPE=Debug -DETHASHCL=1 -DGUI=0
gdb --args ethminer -G -M
注解
在 geth
中使用GPU挖矿时,哈希率(hashrate)信息不可用。
可以用 ethminer
检查哈希率, miner.hashrate
将总是返回0。
在eth中使用ethminer¶
在单GPU上挖矿¶
用如下参数运行eth即可实现单GPU挖矿:
eth -v 1 -a 0xcadb3223d4eebcaa7b40ec5722967ced01cfc8f2 --client-name "OPTIONALNAMEHERE" -x 50 -m on -G
-v 1
把verbosity设置为1。我们不要那些垃圾消息。-a YOURWALLETADDRESS
设置coinbase,用来接收挖矿报酬。这里仅是个例子。这个参数非常重要,请确保这个地址是正确的,否则你将收不到挖矿报酬。--client-name "OPTIONAL"
设置一个可选的客户端名称以在网络上标识你自己。-x 50
请求较大量的节点,这有助于在初始阶段找到节点。-m on
设置为启动时即开始挖矿。-G
设置为允许GPU挖矿。
如果客户端已经在运行,你可以使用geth attach或者[ethconsole](https://github.com/ethereum/ethereum-console)与之交互。
在多GPU上挖矿¶
用多GPU和eth进行挖矿,与用多GPU和geth进行挖矿非常相近。确定一个eth节点在用你的coinbase地址运行:
eth -v 1 -a 0xcadb3223d4eebcaa7b40ec5722967ced01cfc8f2 --client-name "OPTIONALNAMEHERE" -x 50 -j
请注意我们也增加了-j参数,以便客户端具有JSON-RPC服务,来允许与ethminer实例的通信。此外我们还移除了与挖矿相关的参数因为ethminer现在会为我们开始挖矿了。为了使每个GPU都执行一个不同的ethminer实例:
ethminer --no-precompute -G --opencl-device X
这里的X是你希望ethminer来使用的openCL设备索引号{0, 1, 2, …}。你可以执行 ethminer --list-devices
来简单地获得所有支持openCL的设备列表,并且附带一些额外信息。
以下是一个输出示例:
[0] GeForce GTX 770
CL_DEVICE_TYPE: GPU
CL_DEVICE_GLOBAL_MEM_SIZE: 4286345216
CL_DEVICE_MAX_MEM_ALLOC_SIZE: 1071586304
CL_DEVICE_MAX_WORK_GROUP_SIZE: 1024
最后, --no-precompute
参数要求ethminer不要预先创建DAG。尽管这已经不推荐了,因为在每个DAG切换周期时你的挖矿都会被打断。
性能评估¶
挖矿能力基本上会随内存及带宽的增加而提高。AMD的GPU会比NVidia的更好的支持我们用OpenCL写成的算法实现。实验证明,同价位的AMD GPU较NVidia竞品可以提供更好的挖矿表现。
要对一个独立的设备进行性能评估,你可以通过使用ethminer的评估模式参数 -M :
ethminer -G -M
如果你有很多设备,想单独评估某个时,你可以在上述脚本中添加 –opencl-device 选项:
ethminer -G -M --opencl-device X
使用ethminer的 --list-devices
来列出上述命令中可选的设备序号X {0, 1, 2, …}。
要在Windows系统中进行挖矿,首先 下载geth的windows客户端 。
- 解压Geth并启动命令行窗口。使用 cd 命令切换到Geth的数据文件夹。
- 用
geth --rpc
启动Geth。
执行以上命令以后,以太坊区块链就会开始下载数据。有时你的本地防火墙会阻止数据同步(它应该会提示你),这种情况,请点击 “Allow access” (允许访问)。
- 首先 下载并安装ethminer 这个C++挖矿软件(你的防火墙或系统服务会自动反应,允许其访问网络)。
- 打开另一个命令行窗口(保留第一个的运行状态),输入
cd /Program\ Files/Ethereum(++)/release
来切换目录。 - 确保 geth 已经完成区块链同步。然后
ethminer -G
命令开始挖矿。
这时也许会出现一些问题。如果你得到一个错误提示,你可以用 Ctrl+C
组合键中止挖矿。如果错误提示 “Insufficient Memory” 说明你的GPU没有足够的内存来进行挖矿。
矿池挖矿¶
矿池就是指为了稳定预期收益而将挖矿能力池化的矿工合作组织。作为回报,他们通常会将你的挖矿收益的最多5%支付给你。这种矿池由一个中心账户提供有工作量证明的区块,然后将收益按各合作矿工的挖矿能力重新分配。
警告
多数矿池包含第三方、中心化的组件,这意味着他们不可信。换句话说,矿池操作者可以带着你的收益跑掉。要小心。另外也有一部分去信任、去中心化的基于开源项目的矿池。
警告
矿池仅提供工作量证明计算,他们不做区块校验或者运行VM对交易执行结果所导致的状态转移进行检查。在安全方面讲,这样的特性使矿池更像是一个单一的节点,所以矿池的增大和增多会导致中心化 51%攻击 风险的提高。所以请遵从网络计算能力分散化的原则,不要使矿池变得太过巨大。(也就是说,请尽量不要再加入那些计算能力已经很大的矿池了,译者注。)
一些矿池¶
- coinotron
- nanopool
- ethpool - Predictable solo mining, unconventional payout scheme, affiliated with etherchain.org.
- supernova
- coinmine.pl
- eth.pp.ua
- talkether - Unconventional payout scheme, partially decentralized
- weipool
- ethereumpool
- pooleum
- alphapool
- cryptopool
- unitedminers
- dwarfpool - Try to avoid this (currently over 50% of the network)
- laintimes - Discontinued
挖矿相关参考资源¶
- Top miners of last 24h on etherchain
- pool hashrate distribution for august 2015
- Unmaintained list of pools on Forum
- Mining profitability calculator on cryptocompare
- Mining profitability calculator on cryptowizzard
- Mining profitability calculator on etherscan
- Mining profitability calculator on In The Ether
- Mining difficulty chart on etherscan
合约和交易¶
账户类型、气和交易¶
外部账户(EOA)和合约账户¶
- 以太坊中有两种类型的账户
- 外部账户(Externally Owned Accounts)
- 合约账户(Contracts Accounts)
合约账户¶
一个合约
- 有一个以太币余额
- 有关联代码
- 由交易或从其他合约收到的消息所触发执行
- 代码执行 - 可以处理任意复杂度的操作(图灵完备) - 可以操作它自己的持久化存储,比如可以有它自己的永久状态 - 可以调用其他合约
以太坊区块链上的所有动作,都被设定为由外部账户所发出的交易所触发。每当合约账户接收到交易,它的代码会根据作为交易的一部分传入的参数来具体执行。将在网络中每个节点上的以太坊虚拟机中被执行,并被作为它们对新区块的验证结果的一部分。
这种执行需要是完全可预测的,它仅有的上下文就是区块在区块链中的位置及所有可用数据。区块链上的区块相当于时间的单元,区块链自己即以时间维度记录着链上所有区块的状态变动历史。
所有以太币余额都被以wei为单位所记录:1以太币即是1e18wei(10的18次方Wei)。
注解
以太坊里的“合约”不该被认为是应该“实现”或“编译”,他们更像是以太坊运行环境中的“自治化的代理”,当被消息或交易所“插入”时会执行特定的代码,并且由它们自己的以太币余额所控制、由它们自己的键/值存储永久的状态。
什么是交易?¶
在以太坊中,所谓“交易”,是指存储了消息的签名数据包,在区块链上从一个外部账户发送到另外一个外部账户。
- 交易包含:
- 消息的接收方
- 一个用以标示发送方的签名,来证明他们通过区块链发送消息给接收方的意图
VALUE
字段 - 由发送方向接收方转移的wei的数量- 一个可选数据字段,可以包含发送到某个合约的消息
STARTGAS
值,代表交易执行所允许花费的最大可计算步骤(气)的数量GASPRICE
值,代表发送方愿意为了气(gas)的消耗所支付的费用。一单位的气与执行一个原子操作对等,比如一个可计算步骤。
什么是消息?¶
合约可以发送“消息”给其他合约。消息是一些虚拟对象,他们不会被序列化,且仅存在于以太坊的执行环境中,他们可以被理解为函数调用。
- 一个消息包括:
- 消息的发送方(内置的)
- 消息的接收方
VALUE
字段 - 伴随消息一起转移到合约地址的wei的数量- 一个可选数据字段,这是实际输入给合约的数据
STARTGAS
字段,由消息所触发的代码执行所能引起的气的最大消耗数量
大体上讲,消息就像交易,除了它是由合约产生的,而不是外部用户。当合约代码执行 CALL
或 DELEGATECALL
操作码时会产生并执行一个消息。像交易一样,消息会导致接收者账号执行它的代码。这样,合约就可以与其他合约建立联系,就像外部用户之间用交易建立联系那样。
什么是气?¶
以太坊在区块链上实现了一个被称为以太坊虚拟机(EVM)的执行环境。网络中的每个节点都会将EVM作为区块校验协议的一部分来运行。它们会逐个检查正在验证的区块中的所有交易,并在EVM中执行这些交易所触发的代码。网络中的每个全节点都会进行相同的计算并保存相同的结果。显然,以太坊并不是在做计算效率的优化,它这种并行计算是无必要的;这是为了提供一种无需第三方、权威机构或垄断组织的方式来达到系统状态的共识。这当然不是为了优化计算,事实上,合约是在各个节点之上无必要的重复执行的,这使合约变得很昂贵。所以总体上说,并不鼓励在链上运行那些可以脱离区块链完成的计算。
当你在运行一个去中心化应用(dapp)的时候,它会使用区块链来读取和修改它的状态。但这些应用仅在区块链上存放那些对达成共识最为重要的业务逻辑和状态。
当一个合约被一个消息或交易触发而执行的时候,每个预设指令都会被在网络中的所有节点上执行。这会导致一个结果:每个被执行的操作都会有一个用气的数量来衡量的特定花销。
气是交易的发送方需要为在以太坊区块链上执行每个操作而支付的执行费用的名称。这个费用可以想象为一种驱动智能合约执行的加密燃油,气这个名称的灵感就来源于此。气是从那些执行代码的矿工那里用以太币的形式购置的。气和以太币被故意作为不同的概念,是因为气相当于计算单位的自然消耗,而以太币的价格一般会因市场原因而波动。一个自由市场会调和两者的关系:气的价格实际上是由矿工们决定的,它们可以拒绝那些气的价格低于它们的最低限的交易。要获得气,你只需要为你的账户添加以太币即可。以太坊客户端会根据你为交易所指定的最大开支自动用你的以太币购置气。
为了阻止故意的攻击或对以太坊网络的滥用,以太坊协议规定执行合约或交易中的每个计算步骤都需要支付费用。每个交易都需要包含气的上限和希望为每个气所支付的费用。矿工们可以决定是否包含某个交易并获得相应的费用。如果交易所产生的所有计算步骤(包含原始消息和可能被触发的所有其他消息)所需要的气的总量小于等于交易中指定的气的上限,交易会被处理。如果实际消耗的气的总量超过交易中气的上限,所有的变动都会被回复原样,除了交易仍然有效,且费用仍可以被矿工收取。所有在交易执行过程中没有被消耗的多余的气,会被作为以太币返还给发送方。你不需要担心超支,因为你最多只会被收取你在交易中所充入的所有气(即你为交易指定的气的上限,译者注)。这意味着为你的交易指定一个超出预估的气的上限是有用并且安全的。
估算交易的费用¶
一个交易的总费用取决于两个因素:
gasUsed
交易中所消耗的气的总量
gasPrice
交易中所指定的气的价格(用以太币为单位)
总费用 = gasUsed * gasPrice
gasUsed¶
EVM中的每个操作都会对应一个其消耗的气的数值。 gasUsed
即是所有操作所消耗的气的总和。 这份表格 提供了相关的一些分析。
这里有份 estimateGas API 可以帮助你预估 gasUsed
,但其中也有些需要小心的地方。
gasPrice¶
一个用户构造并签名了一个交易之后,每个用户都可以指定一个他们希望的 gasPrice
,这甚至可以设为0。然而,在Frontier版本的以太坊客户端中gasPrise会有一个默认值0.05e12 wei。由于矿工们会优化他们的收入,所以如果大多数交易的gasPrise都是0.05e12 wei的话,你就很难让矿工去接受一个低于这个数值甚至为0的gasPrise了。
交易费用示例¶
让我们使用一个仅仅对两个数字做加法的合约。EVM操作码 ADD
会消耗3个气。
使用默认气价(2016年1月时)的大概的费用为:
3 * 0.05e12 = 1.5e11 wei
由于1以太币等于1e18 wei,所以总费用等于0.00000015以太币。
这是一个简化,因为它忽略了一些费用,比如在两个数字被相加之前,它们需要先被发送给合约。
Operation Name | Gas Cost | Remark |
---|---|---|
step | 1 | 每个执行循环的默认数额 |
stop | 0 | 免费 |
suicide | 0 | 免费 |
sha3 | 20 | 哈希运算,译者注 |
sload | 20 | 从永久存储获取数据 |
sstore | 100 | 向永久存储保存数据 |
balance | 20 | 获取余额,译者注 |
create | 100 | 创建合约 |
call | 20 | 开始只读调用 |
memory | 1 | 扩大内存时每个额外的字 |
txdata | 5 | 交易中的每字节数据或代码 |
transaction | 500 | 基础交易费 |
contract creation | 53000 | 在homestead版本中变更,从21000区块开始的创建合约费用 |
账户交互示例 - 对赌合约¶
如前文所述,有两种类型的合约:
- 外部账户(EOAs) :由私钥控制的账户,如果你拥有EOA的私钥,你就可以用它来发送以太币或者消息。
- 合约账户 :拥有自己的代码,并由代码控制的账户。
默认情况下,以太坊的执行环境是没有任何活动的,所有账户的状态都是一样的。然而,任何用户都可以从一个外部账户发送一个交易从而使以太坊开始运转。如果交易的发送目标是另一个外部账户,那么交易会转移一些以太币但没有任何其他事发生。而如果交易的发送目标是一个合约账户,那么合约就会被激活,其中的代码就会被运行。
这些代码可以从它所控制的内部存储(一个由32字节的键和32字节的值所构成的数据库)读写数据,可以读取接收到的消息,可以将消息发送给其他合约而触发它们的顺序执行。一旦合约执行结束,即所有由合约发送的消息所触发的执行(这是一个可预计的、同步的顺序,就是说父调用会等待子调用完全结束才会继续执行)都停止之时,执行环境会被再次挂起,直到下一个交易发生。
合约账户总体上说是为了4个目的而服务的:
- 维持一些对其他合约或者外部世界有用处的数据的存储。比如,用一个合约来模拟一种货币,或者用一个合约来记录参与特定组织的成员。
- 用来作为一种有更复杂的访问策略的外部账户,这可以叫做“forwarding contract”,它们可以在满足特定条件的情况下,将传入的消息转发给特定的接收方。比如,一个合约可以在得到3个特定私钥其中的两个对某个特定消息的确认之后,将消息进行转发(例如多重签名)。更复杂的“forwarding contract”可以根据消息的不同设置不同的条件。最简单的使用场景就是通过更为复杂的访问步骤来改变取回数据的限定条件。钱包合约就是一个很好的例子。
- 管理多个用户间的持续的合约或者特定的联系。这种例子包括财务合约、一些特定的第三方监管服务或某些保险。另有一种开放性的合约,由一方打开,其他参与方可以随时参加。这种合约的例子就是那种自动支付赏金给那些解决了某些特定的数学问题、或者证明自己提供了一些计算资源的人。
- 为其他合约提供函数,大体上可以认为是作为软件库来使用。
合约与其他合约交互的动作,是通过“调用(calling)”和“发送消息(sending messages)”完成的。一个“消息“,是包含了一定量的以太币、任意大小的字节数据和发送方、接收方地址的一个对象。当一个合约接收到一个消息时,它可以返回一些数据给消息发送方使用,这样,发送一个消息也就像调用一个函数一样。
因为合约可以扮演这些不同的角色,我们可以要求它们之间进行更多的交互。作为一个示例,我们可以想象一个情况:Alice和Bob正在打一个100 GavCoin的赌,赌旧金山下一年内的温度任何时候都不会超过35ºC。然而Alice是个很有安全意识的人,她的主账户使用了一个forwarding contract,只有当三分之二的私钥通过之后才能向外发送消息。Bob则是个对统计密码学持怀疑态度的人,所以他使用了一个只能发送由Lamport签名(一种一次性的单向签名算法,译者注)和传统ECDSA签名(即椭圆曲线签名算法,译者注)共同处理过的消息的forwarding contract(但因为他的守旧,他使用了一个以太坊不直接支持的基于SHA256的Lamport签名算法)。
这个对赌合约自己需要从其他合约取得旧金山的天气数据,它还需要和GavCoin合约交互,当它要实际给Alice或Bob(更准确地说,是给他们的forwarding contrack)发送GavCoin的时候。我可以用下图来表示账户间的关系:

当Bob希望结束对赌的时候,下述步骤将会发生:
1、一个交易被发出,触发一个由Bob的外部账户发送到他的forwarding contract的消息。
2、Bob的forwarding contract发送消息的哈希值和Lamport签名给一个用来做Lamport签名校验库的合约。
3、Lamport签名校验库发现Bob需要基于SHA256的Lamport签名,于是它需要调用SHA256库若干次来校验签名。
4、一旦Lamport签名校验库返回1,也就是说签名已经校验成功,它会给对赌合约发送一个消息。
5、对赌合约会检查提供温度数据的合约取得旧金山的温度数据。
6、如果对赌合约发现温度数据中有超过35ºC的数据,它就会给GavCoin合约发送一个消息,来将合约账户中的GavCoin转移到Bob的forwarding contract。
注意,GavCoin全部都在GavCoin合约的数据库中存储,上边步骤6中所说的“合约账户”是指GavCoin合约的内部会有一个以这个对赌合约地址为键,以其余额为值的数据项。当收到这个消息之后,GavCoin合约会从这个地址减掉一定的数额,给Bob的forwarding contract地址增加相应的数额。我们可以在下图中看到这些步骤:

离线签名交易¶
[ Maybe add this to the FAQ and point to the ethkey section of turboethereum guide? ]
合约¶
什么是合约?¶
一个合约是一个在以太坊区块链上的某个特定地址存在的代码(它的功能)和数据(它的状态)的集合。合约账户可以进行图灵完备的运算,并且可以在账户间发送消息。合约以一个叫做以太坊虚拟机字节码的以太坊所特定的二进制格式保存在区块链上。
合约一般是由某种高级语言,比如 Solidity 写成,然后被编译为字节码上传到区块链上的。
参见
其他语言也是存在的,尤其是Serpent和LLL,关于它们的介绍可以在 以太坊高级语言 找到。
Dapp开发资源 列出了集成开发环境和开发工具可以帮助你使用这些语言进行开发和测试的支持,并提供了一些其他特性。
以太坊高级语言¶
以以太坊特定的二进制格式(EVM字节码)在区块链上存在的合约是由以太坊虚拟机(EVM)执行的。然而合约一般是由高级语言写成,再编译成为字节码发布到区块链上的。
下边是一些开发者可以用来书写以太坊智能合约的几种高级语言。
Solidity¶
Solidity是一种类似于Javascript的语言,可以用来开发合约并编译为EVM字节码。它也是以太坊开发中最受欢迎的标志性语言。
- Solidity Documentation - Solidity is the flagship Ethereum high level language that is used to write contracts.
- Solidity online realtime compiler
- Standardized Contract APIs
- Useful Ðapp Patterns - Code snippets which are useful for Ðapp development.
Serpent¶
Serpent是一个类似于Python的语言,可以用来开发合约并编译为EVM字节码。它最求最大化的简洁,融合了很多低级语言的优点,采用简单易用的编程风格。同时添加了为合约编程定制的一些特性。Serpent是用 LLL 编译的。
LLL¶
Lisp Like Language (LLL) 是一种类似于汇编语言的低级语言,极其简单和抽象化,本质上就是直接在EVM上书写代码的极小包装。
书写一个合约¶
没有哪个语言能躲开写一个Hello World程序。在以太坊环境中,Solidity没有一个明确的方法可以“输出”字符串。最相近的方式就是使用 log event 来将一个字符串放到区块链上:
contract HelloWorld {
event Print(string out);
function() { Print("Hello, World!"); }
}
这个合约会在区块链上创建一个日志项,在它每次被执行时在其中打印一个“Hello World!”。
参见
Solidity docs 有更多样例和指引来书写Solidity代码。
编译一个合约¶
编译Solidity合约可以通过以下几种途径完成。
- 在命令行使用
solc
编译器。 - 在
geth
oreth
提供的javascript控制台使用web3.eth.compile.solidity
(这也需要安装solc
编译器)。 - 使用 Solidity的在线实时编译器.
- 使用 Meteor dapp Cosmo来创建Solidity合约.
- 使用 Mix IDE.
- 使用 以太坊钱包.
注解
更多关于使用solc编译Solidity合约的信息可以在 这里 找到。
在Geth中设置Solidity编译器¶
如果你已经启动 geth
你可以检查哪种编译器是可用的。
> web3.eth.getCompilers();
["lll", "solidity", "serpent"]
这个命令会返回一个数组指出当前可用的编译器。
注解
solc
编译器是随着 cpp-ethereum
一起安装的,或者你可以 自己构建它
如果你的 solc
程序在一个不标准的位置,你可以使用 --solc
参数来指定其执行目录。
$ geth --solc /usr/local/bin/solc
或者,你可以在控制台运行时设置这个选项:
> admin.setSolc("/usr/local/bin/solc")
solc, the solidity compiler commandline interface
Version: 0.2.2-02bb315d/.-Darwin/appleclang/JIT linked to libethereum-1.2.0-8007cef0/.-Darwin/appleclang/JIT
path: /usr/local/bin/solc
编译一个简单的合约¶
让我们编译一个简单的合约代码:
> source = "contract test { function multiply(uint a) returns(uint d) { return a * 7; } }"
这个合约提供了一个方法 multiply ,可以用一个正整数 a
做参数,返回 a * 7
。
你可以使用 eth.compile.solidity() 在 geth
的JS控制台编译Solidity代码:
> contract = eth.compile.solidity(source).test
{
code: '605280600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b60376004356041565b8060005260206000f35b6000600782029050604d565b91905056',
info: {
language: 'Solidity',
languageVersion: '0',
compilerVersion: '0.9.13',
abiDefinition: [{
constant: false,
inputs: [{
name: 'a',
type: 'uint256'
} ],
name: 'multiply',
outputs: [{
name: 'd',
type: 'uint256'
} ],
type: 'function'
} ],
userDoc: {
methods: {
}
},
developerDoc: {
methods: {
}
},
source: 'contract test { function multiply(uint a) returns(uint d) { return a * 7; } }'
}
}
下面的样例会演示通过JSON-RPC来访问 geth
以使用编译器。
$ geth --datadir ~/eth/ --loglevel 6 --logtostderr=true --rpc --rpcport 8100 --rpccorsdomain '*' --mine console 2>> ~/eth/eth.log
$ curl -X POST --data '{"jsonrpc":"2.0","method":"eth_compileSolidity","params":["contract test { function multiply(uint a) returns(uint d) { return a * 7; } }"],"id":1}' http://127.0.0.1:8100
编译器输出的代码中的每个合约对象代表了一个单独的合约。 eth.compile.solidity
实际的返回值是一个合约名字和合约对象的映射对。由于我们的合约名字是 test
, eth.compile.solidity(source).test
会返回给你test合约的合约对象,包含以下字段:
code
- 编译好的EVM字节码
info
- 编译器输出的额外的元数据
source
- 源代码
language
- 合约的语言(Solidity、Serpent或LLL)
languageVersion
- 合约语言的版本
compilerVersion
- 编译这个合约的编译器的版本
abiDefinition
- Application Binary Interface Definition(应用程序二进制接口定义)
userDoc
- 用户的 NatSpec Doc 。
developerDoc
- 开发者的 NatSpec Doc 。
编译器输出内容的结构化(分为 code
和 info
)反映了两种截然不同的 发布路径 。一套EVM代码由一个创建合约的交易发送到区块链上,而其余(信息)则会适当的保存在去中心化的云端,作为在区块链上的可校验元数据使代码得以完整。
如果你的源码包含多个合约,输出则会包含每个合约的单独数据项,可以用合约名字作为属性名获得对应的合约信息对象。你可以通过检查当前的GlobalRegistrar代码来尝试。
contracts = eth.compile.solidity(globalRegistrarSrc)
创建并发布一个合约¶
在你开始这节之前,请确保你有一个已解锁的账户并有一些资金。
你可以用前一章节中的EVM代码作为数据,通过 发送一个交易 到一个空的地址来在区块链上创建一个合约。
注解
使用 Solidity的在线实时编译器 或者 Mix IDE 可以很容易地实现。
var primaryAddress = eth.accounts[0]
var abi = [{ constant: false, inputs: { name: 'a', type: 'uint256' } }]
var MyContract = eth.contract(abi)
var contract = MyContract.new(arg1, arg2, ..., {from: primaryAddress, data: evmByteCodeFromPreviousSection})
所有二进制数据都会被序列化为十六进制格式。十六进制字符串通常会以固定前缀 0x
开头。
注解
注意, arg1, arg2, ...
是合约构造器的参数,可以接受任意数据。如果你的合约不需要构造参数,就可以省略它们。
值得指出的是,这个步骤需要你为执行付费。一旦你的交易进入某个区块,你的账户余额(就是你作为发送方在 from
指定的账户)会根据EVM中气的用量的规则相应减少。一段时间之后,你的交易可能会出现在某个区块中,即它所带来的状态的共识得到确认。你的合约就在区块链上生效了。
用异步方式做同样的事,应该是像这样:
MyContract.new([arg1, arg2, ...,]{from: primaryAccount, data: evmCode}, function(err, contract) {
if (!err && contract.address)
console.log(contract.address);
});
与一个合约进行交互¶
与合约的交互一般可以通过一个类似 eth.contract() 的抽象层函数来实现,它会返回一个javascript对象,带有目标合约的所有可调用函数。
描述一个合约的有效函数的标准方式是 ABI definition 。这个对象是一个数组,描述了每个有效的合约函数的调用方法和返回值。
var Multiply7 = eth.contract(contract.info.abiDefinition);
var myMultiply7 = Multiply7.at(address);
现在所有在ABI中说明的函数调用都在合约实例上可用了,你可以选择两种调用方式之一在合约实例上实际调用。
> myMultiply7.multiply.sendTransaction(3, {from: address})
"0x12345"
> myMultiply7.multiply.call(3)
21
当使用 sendTransaction
这个函数来通过发送交易来调用合约函数时,它会消耗以太币来执行发送,并被永久的记录到区块链上。这种方式调用的返回值是交易的哈希值。
当使用 call
这个函数来调用合约函数时,执行实在本地EVM中进行的,返回值将是合约函数的实际返回值。这种方式的调用不会被记录到区块链上,但也不能更改合约的内部状态。这种方式也就是一种 不变的 函数调用,当然也不会花费以太币。
你应该在只关心返回值的时候使用 call
,而在只关心合约状态的 边界效应(side effects,即副作用、额外的影响,译者注) 时使用 sendTransaction
。
在以上的例子中并没有边界效应,所以 sendTransaction
仅仅消耗了气,增加了宇宙里的总熵。
合约元数据¶
在上面的章节里我们解释了你如何创建在区块链上创建一个合约。现在我们来看一下编译器余下的输出, 合约元数据 或者叫合约信息。
当与一个不是你自己创建的合约进行交互的时候,你也许会希望看到它的文档或者源码。合约作者被鼓励来在区块链上注册这样的信息或者通过一个类似于 EtherChain 的第三方服务来进行发布。 admin
API提供了方便的方法来获取选择了注册的任何合约的具体信息。
// get the contract info for contract address to do manual verification
var info = admin.getContractInfo(address) // lookup, fetch, decode
var source = info.source;
var abiDef = info.abiDefinition
确保这种方法可以运作的底层机制是:
- 合约信息被上传到某处,由一个 URI 标示为可以公开访问
- 任何仅知道合约地址的人都可以知道这个 URI
这些需求是通过两步区块链注册实现的。第一步注册是通过一个叫做 HashReg
的合约对要做注册的合约代码进行内容哈希。第二步则是用第一步中生成的内容哈希,通过 UrlHint
这个合约来注册一个URL。这种 合约注册机制 是Frontier版本的一部分,被拿到了Homestead版本中。
基于这种方案,我们就可以通过已知的合约地址来查询url,从而获得实际的合约元数据信息包。
至此我们可以小结下合约创建的步骤:
- 1、把合约本身发布到区块链上
- 2、取得合约信息json文件
- 3、把合约信息json文件发布到你选择的url上
- 4、注册 代码哈希 -> 内容哈希 -> url
JS API提供了助手使这个过程非常简单。调用 admin.register
可以从合约取得其合约信息,把这些json内容写入到一个文件,计算这个文件的内容哈希,最后用合约的代码哈希来注册内容哈希。当你把这个内容文件发布到某个url之后,你可以使用 admin.registerUrl
来用你的内容哈希把url注册到区块链上。(注意,如果以固定内容地址模式来存储文档,那就不需要再使用url-hint这个合约了。)
source = "contract test { function multiply(uint a) returns(uint d) { return a * 7; } }"
// compile with solc
contract = eth.compile.solidity(source).test
// create contract object
var MyContract = eth.contract(contract.info.abiDefinition)
// extracts info from contract, save the json serialisation in the given file,
contenthash = admin.saveInfo(contract.info, "~/dapps/shared/contracts/test/info.json")
// send off the contract to the blockchain
MyContract.new({from: primaryAccount, data: contract.code}, function(error, contract){
if(!error && contract.address) {
// calculates the content hash and registers it with the code hash in `HashReg`
// it uses address to send the transaction.
// returns the content hash that we use to register a url
admin.register(primaryAccount, contract.address, contenthash)
// here you deploy ~/dapps/shared/contracts/test/info.json to a url
admin.registerUrl(primaryAccount, hash, url)
}
});
测试合约和交易¶
你一般需要用一些底层的策略来测试、调试合约和交易。这节会介绍一些调试工具。为了不涉及真实共识逻辑来测试合约和交易,最好的方式时使用私有区块链。这可以通过设置一个特殊的网络id(比如选一个特殊的整数)并禁止掉其他节点来做到。推荐的方式是使用独立的数据目录和网络端口,以免因为误操作影响到你正在使用的区块链网络(如果你使用默认设置的话)。推荐你使用带分析的最高日志等级的VM debug模式启动 geth
。
geth --datadir ~/dapps/testing/00/ --port 30310 --rpcport 8110 --networkid 4567890 --nodiscover --maxpeers 0 --vmdebug --verbosity 6 --pprof --pprofport 6110 console 2>> ~/dapp/testint/00/00.log
在提交交易之前,你需要先设置好你的私有测试链。请参考 测试网络 。
// create account. will prompt for password
personal.newAccount();
// name your primary account, will often use it
primary = eth.accounts[0];
// check your balance (denominated in ether)
balance = web3.fromWei(eth.getBalance(primary), "ether");
// assume an existing unlocked primary account
primary = eth.accounts[0];
// mine 10 blocks to generate ether
// starting miner
miner.start(4);
// sleep for 10 blocks (this can take quite some time).
admin.sleepBlocks(10);
// then stop mining (just not to burn heat in vain)
miner.stop();
balance = web3.fromWei(eth.getBalance(primary), "ether");
创建交易之后,你可以用以下命令强制处理它们:
miner.start(1);
admin.sleepBlocks(1);
miner.stop();
你可以检查待处理的交易:
// shows transaction pool
txpool.status
// number of pending txs
eth.getBlockTransactionCount("pending");
// print all pending txs
eth.getBlock("pending", true).transactions
如果你提交了创建合约的交易,你可以检查合约代码是否已经被加入当前的区块链:
txhash = eth.sendTansaction({from:primary, data: code})
//... mining
contractaddress = eth.getTransactionReceipt(txhash);
eth.getCode(contractaddress)
访问合约和交易¶
RPC¶
前边几节我们已经看到合约是如何写成、发布和交互的,现在该深入一些关于以太坊网络和智能合约间通信的细节了。
一个以太坊节点提供一个 RPC 接口。这个接口允许Ðapp访问以太坊网络和节点提供的功能,比如编译智能合约代码。它使用 JSON-RPC 2.0 规范的一个子集(不支持通知或命名参数)作为序列化协议,通过HTTP和IPC协议(在Linux/OSX上是unix domain socket,在Windows上是named pipes)实现。
如果你对细节不感兴趣,但在寻找一种简单的使用javascript的库,那你可以跳过下边的内容,直接参考 使用Web3 。
公约¶
PRC接口使用了一些不在JSON-RPC 2.0规范中的公约:
发布合约¶
我们来看一下仅使用RPC接口来发布下述合约的步骤。
contract Multiply7 {
event Print(uint);
function multiply(uint input) returns (uint) {
Print(input * 7);
return input * 7;
}
}
首先需要确认HTTP RPC接口是有效的。就是说我们用 --rpc
参数启动geth,或者用 -j
参数启动eth。在这个例子里,我们在一个私有开发链上使用geth节点,用这种方式,我们不需要真实的以太币。
> geth --rpc --dev --mine --minerthreads 1 --unlock 0 console 2>>geth.log
这会在 http://localhost:8545
启动一个HTTP RPC接口。
注解
geth是支持 CORS 的。请参考 --rpccorsdomain
参数。
我们可以通过使用 curl 获取coinbase地址来验证接口是否在运行。请注意这里使用的数据会与你本地节点有所不同,如果你想尝试这些命令,请相应修改请求参数。
> curl --data '{"jsonrpc":"2.0","method":"eth_coinbase", "id":1}' localhost:8545
{"id":1,"jsonrpc":"2.0","result":["0xeb85a5557e5bdc18ee1934a89d8bb402398ee26a"]}
> curl --data '{"jsonrpc":"2.0","method":"eth_getBalance", "params": ["0xeb85a5557e5bdc18ee1934a89d8bb402398ee26a"], "id":2}' localhost:8545
{"id":2,"jsonrpc":"2.0","result":"0x1639e49bba16280000"}
记得我们已经说过数字需要被变换为16进制吧?在这里返回的余额是由16进制表示的wei的数量。如果我们希望获得以太币单位的余额,我们可以在geth控制台使用web3。
> web3.fromWei("0x1639e49bba16280000", "ether")
"410"
现在我们在私有开发链上有了一些以太币,我们可以发布合约了。第一步是验证Solidity编译器可用。我们可以使用 eth_getCompilers
这个RPC方法查询可用的编译器。
> curl --data '{"jsonrpc":"2.0","method": "eth_getCompilers", "id": 3}' localhost:8545
{"id":3,"jsonrpc":"2.0","result":["Solidity"]}
我们看到Solidity编译器是可用的。如果它不可用,请参考 安装Solidity 。
下一步就是把Multiply7合约编译为可以发动到EVM的字节码。
> curl --data '{"jsonrpc":"2.0","method": "eth_compileSolidity", "params": ["contract Multiply7 { event Print(uint); function multiply(uint input) returns (uint) { Print(input * 7); return input * 7; } }"], "id": 4}' localhost:8545
{"id":4,"jsonrpc":"2.0","result":{"Multiply7":{"code":"0x6060604052605f8060106000396000f3606060405260e060020a6000350463c6888fa18114601a575b005b60586004356007810260609081526000907f24abdb5865df5079dcc5ac590ff6f01d5c16edbc5fab4e195d9febd1114503da90602090a15060070290565b5060206060f3","info":{"source":"contract Multiply7 { event Print(uint); function multiply(uint input) returns (uint) { Print(input * 7); return input * 7; } }","language":"Solidity","languageVersion":"0.2.2","compilerVersion":"0.2.2","compilerOptions":"--bin --abi --userdoc --devdoc --add-std --optimize -o /tmp/solc205309041","abiDefinition":[{"constant":false,"inputs":[{"name":"input","type":"uint256"}],"name":"multiply","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"","type":"uint256"}],"name":"Print","type":"event"}],"userDoc":{"methods":{}},"developerDoc":{"methods":{}}}}}}
现在我们有了编译好的代码,我们需要确定发布它要消耗多少气。RPC接口 eth_estimateGas
可以给我们一个估算。
> curl --data '{"jsonrpc":"2.0","method": "eth_estimateGas", "params": [{"from": "0xeb85a5557e5bdc18ee1934a89d8bb402398ee26a", "data": "0x6060604052605f8060106000396000f3606060405260e060020a6000350463c6888fa18114601a575b005b60586004356007810260609081526000907f24abdb5865df5079dcc5ac590ff6f01d5c16edbc5fab4e195d9febd1114503da90602090a15060070290565b5060206060f3"}], "id": 5}' localhost:8545
{"id":5,"jsonrpc":"2.0","result":"0xb8a9"}
最后发布合约。
> curl --data '{"jsonrpc":"2.0","method": "eth_sendTransaction", "params": [{"from": "0xeb85a5557e5bdc18ee1934a89d8bb402398ee26a", "gas": "0xb8a9", "data": "0x6060604052605f8060106000396000f3606060405260e060020a6000350463c6888fa18114601a575b005b60586004356007810260609081526000907f24abdb5865df5079dcc5ac590ff6f01d5c16edbc5fab4e195d9febd1114503da90602090a15060070290565b5060206060f3"}], "id": 6}' localhost:8545
{"id":6,"jsonrpc":"2.0","result":"0x3a90b5face52c4c5f30d507ccf51b0209ca628c6824d0532bcd6283df7c08a7c"}
交易被节点接受,交易的哈希被返回。我们可以用这个哈希来追踪交易。
接下来是确定我们的合约的发布地址。每个交易被执行后都会有个收据。这个收据包含了一些交易信息,比如交易被包含在哪个区块、EVM消耗了多少气。如果一个交易创建了一个合约,它还会包含合约的地址。我们可以使用 eth_getTransactionReceipt
这个RPC方法取得收据信息。
> curl --data '{"jsonrpc":"2.0","method": "eth_getTransactionReceipt", "params": ["0x3a90b5face52c4c5f30d507ccf51b0209ca628c6824d0532bcd6283df7c08a7c"], "id": 7}' localhost:8545
{"id":7,"jsonrpc":"2.0","result":{"transactionHash":"0x3a90b5face52c4c5f30d507ccf51b0209ca628c6824d0532bcd6283df7c08a7c","transactionIndex":"0x0","blockNumber":"0x4c","blockHash":"0xe286656e478a1b99030e318d0f5c3a61a644f25e63deaa8be52e80da1e7b0c47","cumulativeGasUsed":"0xb8a9","gasUsed":"0xb8a9","contractAddress":"0x6ff93b4b46b41c0c3c9baee01c255d3b4675963d","logs":[]}}
我们可以看到合约被创建在 0x6ff93b4b46b41c0c3c9baee01c255d3b4675963d
上。如果你获得了null,说明交易还没有被包含到区块上。稍等一下,检查你的矿工是否在运行,然后重试这个命令。
与智能合约交互¶
现在我们的合约已经发布完成,我们可以与它开始交互了。这里有两种方法,发送一个交易,或者 像先前提到的那样call 。在此我们会向合约的multiply方法发送一个交易。
如果我们查看 eth_sendTransaction 这个文档,我们需要提供多个参数。我们需要指定 from
、 to
和 data
参数。from
是我们的账号的公共地址, to
是合约地址。 data
参数有点儿麻烦。它包含了哪些方法需要用哪些参数进行调用这样的有效信息。这里就需要ABI(Application Binary Interface)出场了。ABI是如何为EVM编码的定义。请参考 ABI的所有细节 。
这里的有效信息字节就是函数选择器,它将指定哪些方法会被调用。这是通过把对函数名称和他的参数类型的Keccak哈希值的首4字节转换为16进制达成的。 multiply 函数接受一个 等价于 uint256 的 uint 参数。我们可以获得:
> web3.sha3("multiply(uint256)").substring(0, 8)
"c6888fa1"
更多细节请参考 函数选择器 。
下一个步骤就是对参数进行编码,我们只有一个uint256,让我们假定以6作为参数值。这个ABI文档 章节 具体说明了如何编码成uint256类型。
int<M>: enc(X) is the big-endian two’s complement encoding of X, padded on the higher-oder (left) side with 0xff for negative X and with zero bytes for positive X such that the length is a multiple of 32 bytes.
这样,6就应该编码为 0000000000000000000000000000000000000000000000000000000000000006
。
结合函数选择器和参数编码,我们的 data
应该就是 0xc6888fa10000000000000000000000000000000000000000000000000000000000000006
。
我们试一下:
> curl --data '{"jsonrpc":"2.0","method": "eth_sendTransaction", "params": [{"from": "0xeb85a5557e5bdc18ee1934a89d8bb402398ee26a", "to": "0x6ff93b4b46b41c0c3c9baee01c255d3b4675963d", "data": "0xc6888fa10000000000000000000000000000000000000000000000000000000000000006"}], "id": 8}' localhost:8545
{"id":8,"jsonrpc":"2.0","result":"0x759cf065cbc22e9d779748dc53763854e5376eea07409e590c990eafc0869d74"}
由于我们发送了一个交易,我们获得了交易的哈希。如果我们来获取收据,会看到一些新东西:
{
blockHash: "0xbf0a347307b8c63dd8c1d3d7cbdc0b463e6e7c9bf0a35be40393588242f01d55",
blockNumber: 268,
contractAddress: null,
cumulativeGasUsed: 22631,
gasUsed: 22631,
logs: [{
address: "0x6ff93b4b46b41c0c3c9baee01c255d3b4675963d",
blockHash: "0xbf0a347307b8c63dd8c1d3d7cbdc0b463e6e7c9bf0a35be40393588242f01d55",
blockNumber: 268,
data: "0x000000000000000000000000000000000000000000000000000000000000002a",
logIndex: 0,
topics: ["0x24abdb5865df5079dcc5ac590ff6f01d5c16edbc5fab4e195d9febd1114503da"],
transactionHash: "0x759cf065cbc22e9d779748dc53763854e5376eea07409e590c990eafc0869d74",
transactionIndex: 0
}],
transactionHash: "0x759cf065cbc22e9d779748dc53763854e5376eea07409e590c990eafc0869d74",
transactionIndex: 0
}
收据包含了日志。这个日志是在交易执行的时候由EVM生成并包含到收据里的。我们可以看到在multiply函数中的Print事件被触发,打印了输入数值的7倍。由于Print事件的参数是uint256类型,我们可以基于ABI规则对其解码得到我们预期的十进制数值42。虽然脱离了data,topics字段就没有意义了,但它可以用来判断是哪个事件创建了这个日志:
> web3.sha3("Print(uint256)")
"24abdb5865df5079dcc5ac590ff6f01d5c16edbc5fab4e195d9febd1114503da"
你可以从 Solidity tutorial 中得到更多关于events、topics和indexing相关的信息。
这里仅是个对最普通任务的简短介绍。请参阅 RPC wiki page 获知全部的可用RPC方法。
Web3.js¶
就像我们在先前的示例中看到的那样,使用JSON-RPC接口是单调的、容易犯错的,特别是当我们要处理ABI的时候。Web.js则是一个基于以太坊RPC接口之上的javascript库,它的目标是提供一个更友好的接口、减少出错的机会。
用web3发布Multiply7合约大致像这样:
var source = 'contract Multiply7 { event Print(uint); function multiply(uint input) returns (uint) { Print(input * 7); return input * 7; } }';
var compiled = web3.eth.compile.solidity(source);
var code = compiled.Multiply7.code;
var abi = compiled.Multiply7.info.abiDefinition;
web3.eth.contract(abi).new({from: "0xeb85a5557e5bdc18ee1934a89d8bb402398ee26a", data: code}, function (err, contract) {
if (!err && contract.address)
console.log("deployed on:", contract.address);
}
);
deployed on: 0x0ab60714033847ad7f0677cc7514db48313976e2
加载发布的合约并发送一个交易:
var source = 'contract Multiply7 { event Print(uint); function multiply(uint input) returns (uint) { Print(input * 7); return input * 7; } }';
var compiled = web3.eth.compile.solidity(source);
var Multiply7 = web3.eth.contract(compiled.Multiply7.info.abiDefinition);
var multi = Multiply7.at("0x0ab60714033847ad7f0677cc7514db48313976e2")
multi.multiply.sendTransaction(6, {from: "0xeb85a5557e5bdc18ee1934a89d8bb402398ee26a"})
注册一个当 Print
事件创建日志之后会被调用的回调(callback)。
multi.Print(function(err, data) { console.log(JSON.stringify(data)) })
{"address":"0x0ab60714033847ad7f0677cc7514db48313976e2","args": {"":"21"},"blockHash":"0x259c7dc07c99eed9dd884dcaf3e00a81b2a1c83df2d9855ce14c464b59f0c8b3","blockNumber":539,"event":"Print","logIndex":0, "transactionHash":"0x5c115aaa5418118457e96d3c44a3b66fe9f2bead630d79455d0ecd832dc88d48","transactionIndex":0}
更多信息请参考 web3.js wiki页。
控制台¶
geth 控制台 提供了一个javascript环境的命令行接口。它可以连接到一个本地或远程的geth或eth节点。它会加载web3.js库,使用户可以在控制台上使用web3.js与智能合约进行交互。 Web3.js 这节中的样例是可以直接在命令行执行的。
查看合约和交易¶
有很多在线的区块链浏览器可以使你查看以太坊区块链。请参考 区块链浏览器 。
托管的区块链浏览器¶
- EtherChain
- EtherCamp
- EtherScan (and for Testnet)
其他资源¶
- EtherNodes - Geographic distribution of nodes and split by client
- EtherListen - Realtime Ethereum transaction visualizer and audializer
Mix¶
The IDE Mix is intended to help you as a developer to create, debug and deploy contracts and dapps (both contracts backend and frontend).
WARNING - There are numerous reports of crash-at-boot issues for Mix on OS X. The issue is a Heisenbug which we have been chasing for a month or two. The best workaround we have for right now is to use the Debug configuration, like so:
cmake -DCMAKE_BUILD_TYPE=Debug ..
WARNING - A replacement for Mix called Remix is being worked on, so if you are experiencing issues with Mix, you might be better to look for alternatives until Remix is more mature.
Start by creating a new project that consists of
- contracts
- html files
- JavaScript files
- style files
- image files
Project Editor¶
You can use projects to manage the creation and testing of a dapp. The project will contain data related to both backend and frontend as well as the data related to your scenarios (blockchain interaction) for debugging and testing. The related files will be created and saved automatically in the project directory.
Creating a new project¶
The development of a dapp start with the creation of a new project. Create a new project in the “edit” menu. Enter the project name, e.g. “Ratings” and select a path for the project file.
Editing backend contract file¶
By default, a new project contains a contract “Contract” for backend development on the blockchain using the Solidity language and the “index.html” for the frontend. Check the Solidity tutorial for references.
Edit the empty default contract “Contract”, e.g.
contract Rating {
function setRating(bytes32 _key, uint256 _value) {
ratings[_key] = _value;
}
mapping (bytes32 => uint256) public ratings;
}
Check the Solidity tutorial for help getting started with the solidity programming language.
Save changes
Editing frontend html files¶
Select default index.html file and enter the following code
.... <script>
function getRating() {
var param = document.getElementById(“query”).value;
var res = contracts[“Rating”].contract.ratings(param);
document.getElementById(“queryres”).innerText = res;
}
function setRating() {
var key = document.getElementById("key").value;
var value = parseInt(document.getElementById("value").value);
var res = contracts["Rating"].contract.setRating(key, value);
}
</script>
</head>
<body bgcolor="#E6E6FA">
<h1>Ratings</h1>
<div>
Store:
<input type="string" id="key">
<input type="number" id="value">
<button onclick="setRating()">Save</button>
</div>
<div>
Query:
<input type="string" id="query" onkeyup='getRating()'>
<div id="queryres"></div>
</div>
</body>
</html>
Then it is possible to add many contract files as well as many HTML, JavaScript, css files
Scenarios Editor¶
Scenarios can be used to test and debug contracts.
A scenario is effectively a local blockchain where blocks can be mined without PoW – otherwise testing would be quite slow ;).
A scenario consists of a sequence of transactions. Usually, a scenario would start with the contract creation scenarios of the dapp. In addition, further transactions can be added to test and debug the dapp. Scenarios can be modified, i.e. transactions can be removed. Note that a scenario needs to be rebuilt for modifications to become effective. Further testing can be done using local JS calls via the JS API.
In case it’s not open, access the scenario and debugger pane by pressing F7 or Windows > Show right or the debug button in the upper right corner of the main window.
Creating and setting up a new scenario¶
When you launch Mix for the first time, an empty scenario, i.e. not containing any transactions, will be created. Add an account named “MyAccount” and set it’s initial balance to 1 ether. Click OK. Rename the scenario to “Deploy”.
Modifying initial ether balance of an account¶
Actually, we want to do a lot of tests Edit the Genesis block parameters and set your initial account balance to 1000 ether. Rebuild the scenario for the change to become effective.
Rebuilding a scenario¶
Each time a transaction is modified or an account added, the scenario has to be rebuilt for modifications to become effective. Note that if a scenario is rebuilt the web frontend (local storage) may also need to be reset (this is not done automatically be Mix).
Creating a transaction¶
Let’s get some ether sent to Bob. Create another account named “Bob” with zero ether balance. Create a new transaction in the scenario pane. Click “Add Tx…” and send 300 ether to Bob. Add a block.
Altering and reusing scenarios¶
Create a new scenario or start from a scenario with several transactions that you duplicate first
Rename the scenario
Modify scenario by specifying transactions that shall be removed
Rebuild the scenario
Display calls¶
A contract call is a function invokation. This is not a transaction as a contract call cannot change the state. A contract call is not part of the blockchain but for practical and ux design reason, it is convenient to display calls at the same functional level as a transaction. The JS icon warn you that this is not a transaction but a call. To show/hide call, click on the menu Scenario -> Display calls.
State Viewer¶
This panel is located below the block chain panel, in the scenario view. Once the blockchain has been run, this panel shows the state of the blockchain.
By state we mean all accounts balance (including contract and normal account), and the storage (global variable of all deployed contract). The content of this panel is not static, it depends on the selected transaction on the blockchain panel. The state shown here is the state resulting of the execution of the selected transaction.
In that case, 2 contracts are deployed, the selected transaction (deployment of testCtr) is the last one. so the state view shows the storage of both TestCtr and BasicContract.
Transaction Explorer¶
Using the transaction pane
The transaction pane enables you to explore transactions receipts, including
- Input parameters
- Return parameters
- Event logs
To display the transaction explorer, click on the down triangle icon which is on the right of each transaction, this will expand transaction details:
Then you can either copy the content of this transaction in the clipboard, Edit the current transaction (you will have to rerun the blockchain then), or debug the transaction.
JavaScript console¶
Mix exposes the following objects into the global window context
web3 - Ethereum JavaScript API
contracts: A collection of contract objects. keys represents contracts name. values are is an objects containing the following properties:
- contract: contract object instance (created as in web3.eth.contract)
- address: contract address from the last deployed state (see below)
- interface: contract ABI
Check the JavaScript API Reference for further information.
Using the JS console to add transactions and local calls¶
In case the name of the contract is “Sample” with a function named “set”, it is possible to make a transaction to call “set” by writing:
contracts["Sample"].contract.set(14)
If a call can be made this will be done by writing:
contracts["Sample"].contract.get.call()
Transaction debugger¶
Mix supports both Solidity and assembly level contract code debugging. You can toggle between the two modes to retrieve the relevant information you need.
At any execution point the following information is available:
VM stack – See Yellow Paper for VM instruction description
Call stack – Grows when contract is calling into another contract. Double click a stack frame to view the machine state in that frame
Storage – Storage data associated with the contract
Memory – Machine memory allocated up to this execution point
Call data – Transaction or call parameters
Accessing the debug mode¶
When transaction details are expanded, you can switch to the debugger view by clicking on the “Debug Transaction” button
Toggling between debug modes and stepping through transactions¶
This opens the Solidity debugging mode. Switch between Solidity and EVM debugging mode using the Menu button (Debug -> Show VM code)
- Step through a transaction in solidity debugging mode
- Step through a transaction in EVM debugging mode
Dapps deployment¶
The deployment process includes three steps:
- Deploy contract:This step will deploy contracts in the main blockchain.
- Package dapp:This step is used to package and upload frontend resources.
- Register:To render the Dapp, the Ethereum browser (Mist or AlethZero) needs to access this package. This step will register the URL where the resources are stored.
To Deploy your Dapp, Please follow these instructions:
Deploy
, Deploy to Network
.- Deploy contract
- Select Scenario
“Ethereum node URL” is the location where a node is running, there must be a node running in order to initiate deployment.
“Pick Scenario to deploy” is a mandatory step. Mix will execute transactions that are in the selected scenario (all transactions except transactions that are not related to contract creation or contract call). Mix will display all the transactions in the panel below with all associated input parameters.
“Gas Used”: depending on the selected scenario, Mix will display the total gas used.
- Deploy Scenario
“Deployment account” allow selecting the account that Mix will use to execute transactions.
“Gas Price” shows the default gas price of the network. You can also specify a different value.
“Deployment cost”: depending on the value of the gas price that you want to use and the selected scenario. this will display the amount ether that the deployment need.
“Deployed Contract”: before any deployment this part is empty. This will be filled once the deployment is finished by all contract addresses that have been created.
“Verifications”. This will shows the number of verifications (number of blocks generated on top of the last block which contains the last deployed transactions). Mix keep track of all the transactions. If one is missing (unvalidated) it will be displayed in this panel.
- Package dapp
The action “Generate Package” will create a new folder named ‘www’, this folder will contain all the resources and scripts will be mapped to the current deployed contract. In order to publish your dapp, you need to host the www folder in a webserver (to be replace soon by IPFS and SWARM). by default the library web3.js is not included. If you want to be able to use the dapp in a standard web browser, you wiil need to include this library.
Code Editor¶
This editor provides basic functionalities of a code editor.
- In Solidity or JavaScript mode, an autocompletion plugin is available (Ctrl + Space).
- Increasing/decreasing the font size (Ctrl +, Ctrl -)
- In Solidity mode, you can display the gas estimation (Tools -> Display Gas Estimation). This will highlight all statements which requires a minimum amount of gas. Color turns to red if the gas required becomes important. It will also display the max execution cost of a transaction (for each function).
Dapps¶
一个Dapp是一个使最终用户和服务提供者可以直接交互的服务(比如某些市场中的买家和卖家,文件存储服务中的所有者和保存者)。以太坊Dapp一般会允许用户通过一个使用javascript API的HTML/Javascript web应用程序来与区块链进行交流。Dapp一般会在区块链上保有它们自己的一些合约,作为它们的业务逻辑和业务状态的持久化存储的载体。由于以太坊网络中的冗余计算要求,实际运行所消耗的气总是会高于在私有链上执行时的消耗。这就使Dapp的开发者需要限制他们需要保存到区块链上的的代码量和数据存储量。
Dapp名录¶
使用以太坊的Dapp被编制到下边的名单中。其中列出了它们的开发状态(概念、原型、活跃/已发布)。如果你正在开发Dapp,请考虑将其加入这些名单中:
这里列出的去中性化服务涵盖了非常广泛的领域,包括:金融、保险、预测市场(prediction markets)、社交网络、分布式计算和存储、赌博、集市、物联网、政府、协作、开发以及游戏。
- 我们最终会希望得到什么样的应用? https://www.reddit.com/r/ethereum/comments/2mnl7f/the_top_10_ether_dapps_of_2015/cm63nsf
未来,Dapp将会由集成到Dapp浏览器的Dapp市场来进行罗列和分发。
Dapp浏览器¶
- Mist - official GUI dapp browser developed by the foundation, alpha stage. Mist as Wallet dapp is in beta.
- Status - Mobile Ethereum browser (alpha)
- MetaMask - Aaron Kumavis Davis’s in-browser GUI. Epicenter Bitcoin interview on github - supported by DEVgrants
- AlethZero - C++ eth client GUI, (discontinued).
- Supernova - (discontinued).
开发工具¶
Dapp开发需要对Web3 Javascript API、JSON RPC API以及Solidity开发语言的相关理解。
注解
这里有一些可以帮助你自动化地利用相关资源来开发、测试和发布Dapp的工具。
- Web3 JavaScript API - 这是你想要和以太坊节点进行交互时会用到的主要的javascript SDK。
- JSON RPC API - 这是 Web3 JavaScript API 用到的底层JSON RPC 2.0接口。
- Solidity Docs - Solidity是开发以太坊智能合约所需的语言,可以被编译为EVM操作码。
- Solium - 一个遵从官方的 Solidity风格指引 的Solidity语法检查工具。
- 测试网络 - 测试网络帮助开发者开发和测试以太坊代码和网络交互,而不需要它们在主网络上花费自己的以太币。后边会列出一些测试网络选项。
- Dapp开发资源 这可以协助你开发、调试和发布以太坊应用程序。
Dapp开发资源¶
IDEs/Frameworks¶
以下使一些开发框架和IDE,可以用来书写以太坊Dapp。
- Truffle - Truffle是一个以太坊的开发环境、测试框架和资产渠道。
- Dapple - Dapple是一个Solidity开发者工具,有助于在类似于以太坊的区块链上构建和管理复杂的合约系统。
- Populus - Populus是一个用Python写的智能合约开发框架。
- Eris-PM - Eris包管理器可以在私有链和公有链上发布和测试智能合约系统。
- Embark - Embark是一个用javascript写的Dapp开发框架。
- EtherScripter (obsolete, discontinued)
- Resilience Raw Transaction Broadcaster
Ethereum控制台¶
以太坊节点的命令行控制台。
Ethconsole 可以通过IPC连接到以太坊节点并后台运行,它可以提供一个包含了web3对象和admin功能的javascript控制台。
这里你可以找到一个有效命令的列表 以太坊节点控制命令 。
要是用控制台,你需要启动一个本地以太坊节点,并允许IPC socket通信(在数据目录中的 geth.ipc
文件)。你启动一个节点之后,可以在本地的主目录 .ethereum 下找到IPC socket文件。你可以设置 --test
选项来使用特定的节点测试命令。
> eth --test
> ethconsole ipc://path/to/geth.ipc
在控制台输入:
> web3.eth.<command name> (arguments, function(){})
这里是 --test
模式的节点命令:
> web3.test.addBlock("[RLP]", function(){}) - Add a block from a string containing its hex RLP
> web3.test.rewindToBlock:("[int]", function(){}) - Reset the blockchain to specified block number
> web3.test.mineBlocks:("[int]", function(){}) - Mine a certain amount of NoProof blocks into chain
> web3.test.modifyTimestamp:("[int]", function(){}) - Set current block timestamp
> web3.test.setChainParams:("[json]", function(){}) - Reset the blockchain with given node configuration file
更多信息请参考 节点配置 。
基础层服务¶
Whisper¶
- What is Whisper and what is it used for - stackexchange Q&A
- Gavin Wood: Shh! Whisper - DEVCON-1 talk youtube video
- Whisper overview and dream API usage -
- ELI5
Swarm¶
Swarm是一个分布式存储平台和内容分发服务,是以太坊Web3技术栈的原生基础层服务。Swarm的主要目标是为以太坊的公共履历提供一个充分的去中心化的冗余存储,特别是可以像处理区块链数据那样保存和分发Dapp代码和数据。从经济学角度来看,它允许参与者把他们的存储和带宽资源充分的池化,来给所有参与者提供上述服务。
从最终用户的角度,Swarm和WWW没有多大不同,除了数据并不是上传到一个特定的服务器以外。其目标就是达成一个点到点(peer-to-peer)存储来提供DDOS抗性、零宕机时间、容错和抗审查的特性,就像因为内置的使用点到点账户并允许由支付来交易资源的激励机制所产生了自我维持特性那样。Swarm被设计为与以太坊的devp2p多重网络协议和以太坊区块链进行深度集成,为域名解析、服务支付和内容有效性保障所服务。
ÐΞVcon上关于Swarm的谈话¶
- Viktor Trón, Daniel A. Nagy: Swarm - Ethereum ÐΞVcon-1 talk on youtube
- Daniel A. Nagy: Keeping the Public Record Safe and Accessible - Ethereum ÐΞVcon-0 talk on youtube
代码和状态¶
- [source](https://github.com/ethereum/go-ethereum/tree/swarm)
- [issues on github](https://github.com/ethereum/go-ethereum/labels/swarm)
- [development roadmap]()
- ethersphere on twitter
- swarm gitter room
- swarm subreddit
线上、线下的存储
以太坊闹钟¶
- Author: Piper Merriam
- Website: alarm_main_website.
- Documentation: alarm_documentation.
一个可以调度交易在一段时间之后发生的集市。与unix中的 crontab 或javascript中的 setTimeout 扮演相似的角色。
- Decentralized cron service in Ethereum proposal - by Peter Szilagyi
以太坊计算市场¶
- Author: Piper Merriam
- Website: computation_market_main_website.
- Documentation: computation_market_documentation.
一个可以使链下的可验证计算得以进行的集市。允许在EVM中进行非常昂贵的计算而不用支付在链上运行它们所需要的高额的气。
BTCRelay¶
- BTCrelay
- More information (about ETH/BTC 2-way peg without modifying bitcoin code).
- BTCrelay audit
EVM¶
以太坊虚拟机(EVM)是以太坊上的智能合约运行环境。它不但是个沙箱,而且是完全独立的,就是说在EVM中运行的代码是不能访问任何网络、文件系统或其他进程的。智能合约甚至对其他智能合约也是有限访问的。
区块链上的合约是以以太坊特定的二进制格式(EMV字节码)保存的。然而,合约一般是由一种以太坊高级语言写成的,由EVM编译器编译为字节码,最终使用以太坊客户端上传到区块链上的。
Ethereum Tests¶
Using Testeth¶
Ethereum cpp-client testeth tool for creation and execution of ethereum tests.
To run tests you should open folder (see also Installing and building)
/build/libethereum/test
and execute a command ./testeth
This will run all test cases automatically.
To run a specific test case you could use parameter -t
in the command line option:
./testeth -t <TEST_SUITE>/<TEST_CASE>
Or just the test suite:
./testeth -t <TEST_SUITE>
You could also use --filltests
option to rerun test creation from .json files which are located at ../cpp-ethereum/test/<TEST_FILLER>.json
./testeth -t <TEST_SUITE>/<TEST_CASE> --filltests
By default using --filltests
option testeth
recreate tests to the ETHEREUM_TEST_PATH
folder. You might want to set this variable globally on your system like:
nano /etc/environment
ETHEREUM_TEST_PATH="/home/user/ethereum/tests"
Filler files are test templates which are used to fill initial parameters defined at test specification Ethereum Tests and then create a complete test .json
file. You might find filler files very useful when creating your own tests.
The --checkstate
option adds a BOOST error if the post state of filled test differs from its expected
section.
To specify a concrete test in a TEST_CASE file for filling/running procedure use --singletest
option:
./testeth -t <TEST_SUITE>/<TEST_CASE> --singletest <TEST_NAME>
If you want to debug (note: testeth should be build with VMTRACE=1) a single test within a result test .json
file, you might use the following command:
./testeth --log_level=test_suite --run_test=<TEST_SUITE>/<TEST_CASE> --singletest <TEST_FILE>.json
<TEST_NAME> --vmtrace --verbosity 12
./testeth -t <TEST_SUITE>/<TEST_CASE> --singletest <TEST_NAME> --vmtrace --verbosity 12
Some tests may use excessive resources when running, so by default they are disabled. Such tests require specific flag to be set in order to be executed. Like --performance
, --inputLimits
, --memory
, --quadratic
. You may also enable all of the tests by setting --all
flag. Be careful. Enabled memory tests may stress your system to use 4GB of RAM and more.
That’s it for test execution. To read more about command line options you may run testeth
with --help
option.
Now let’s see what test cases are available.
Test Cases¶
Almost each test case has its filler file available at /webthree-umbrella/libethereum/test
TEST_SUITE = BlockTests TEST_CASES = blValidBlockTest blInvalidTransactionRLP blTransactionTest blInvalidHeaderTest userDefinedFile
TEST_SUITE = TransactionTests TEST_CASES = ttTransactionTest ttWrongRLPTransaction tt10mbDataField userDefinedFile
TEST_SUITE = StateTests TEST_CASES = stExample stSystemOperationsTest stPreCompiledContracts stLogTests stRecursiveCreate stTransactionTest stInitCodeTest stSpecialTest stRefundTest stBlockHashTest stQuadraticComplexityTest stSolidityTest stMemoryTest stCreateTest userDefinedFileState
TEST_SUITE = VMTests TEST_CASES = vm_tests vmArithmeticTest vmBitwiseLogicOperationTest vmSha3Test vmEnvironmentalInfoTest vmBlockInfoTest vmIOandFlowOperationsTest vmPushDupSwapTest vmLogTest vmSystemOperationsTest vmPerformanceTest vmInputLimitsTest1 vmInputLimitsTest2 vmRandom userDefinedFile
Blockchain Tests¶
Found in /BlockTests
, the blockchain tests aim is to test the basic verification of a blockchain.
/BlockTests
- general blockchain tests. All blocks are built on network: Frontier
/BlockTests/Homestead
- homestead blockchain tests. All blocks are built on network: Homestead
/BlockTests/TestNetwork
- transition blockchain tests. All blocks before 5th are built on network: Frontier, then each block should correspond to Homestead rules.
It is based around the notion of executing a list of single blocks, described by the blocks
portion of the test. The first block is the modified genesis block as described by the genesisBlockHeader
portion of the test. A set of pre-existing accounts are detailed in the pre
portion and form the world state of the genesis block.
It is generally expected that the test implementer will read genesisBlockHeader
and pre
and build the corresponding blockchain in the client. Then the new blocks, described by its RLP found in the rlp
object of the blocks
(RLP of a complete block, not the block header only), is read. If the client concludes that the block is valid, it should execute the block and verify the parameters given in blockHeader
(block header of the new block), transactions
(transaction list) and uncleHeaders
(list of uncle headers). If the client concludes that the block is invalid, it should verify that no blockHeader
, transactions
or uncleHeaders
object is present in the test. The client is expected to iterate through the list of blocks and ignore invalid blocks.
Basic structure¶
{
"ValidBlocks": {
"genesisBlockHeader": { ... },
"pre": { ... },
"blocks" : [
{
"chainname" : "A",
"blocknumber" : "1",
"rlp": { ... },
"blockHeader": { ... },
"transactions": { ... },
"uncleHeaders": { ... }
},
{
"chainname" : "A",
"blocknumber" : "2",
"rlp": { ... },
"blockHeader": { ... },
"transactions": { ... },
"uncleHeaders": { ... }
}
]
},
"SomeInvalidBlocks": {
"genesisBlockHeader": { ... },
"pre": { ... },
"blocks" : [
{
"chainname" : "B",
"blocknumber" : "3",
"chainnetwork" : "Frontier",
"rlp": { ... },
},
{
"blocknumber" : "1",
"rlp": { ... },
"blockHeader": { ... },
"transactions": { ... },
"uncleHeaders": { ... }
},
{
"blocknumber" : "1",
"chainnetwork" : "Homestead",
"rlp": { ... },
},
{
"blocknumber" : "2",
"rlp": { ... },
"blockHeader": { ... },
"transactions": { ... },
"uncleHeaders": { ... }
}
]
},
...
}
Sections¶
- The
genesisBlockHeader
section
coinbase
:- The 160-bit address to which all fees collected from the successful mining of this block be transferred, as returned by the COINBASE instruction.
difficulty
:- A scalar value corresponding to the difficulty level of this block. This can be alculated from the previous block’s difficulty level and the timestamp, as returned by the DIFFICULTY instruction.
gasLimit
:- A scalar value equal to the current limit of gas expenditure per block, as returned by the GASLIMIT instruction.
number
:- A scalar value equal to the number of ancestor blocks. The genesis block has a number of zero.
timestamp
:- A scalar value equal to the reasonable output of Unix’s time() at this block’s inception, as returned by the TIMESTAMP instruction.
parentHash
:- The Keccak 256-bit hash of the parent block’s header, in its entirety
bloom
:- The Bloom filter composed from indexable information (logger address and log topics) contained in each log entry from the receipt of each transaction in the transactions list.
extraData
:- An arbitrary byte array containing data relevant to this block. This must be 1024 bytes or fewer.
gasUsed
:- A scalar value equal to the total gas used in transactions in this block.
nonce
:- A 256-bit hash which proves that a sufficient amount of computation has been carried out on this block.
receiptTrie
:- The Keccak 256-bit hash of the root node of the trie structure populated with the receipts of each transaction in the transactions list portion of the block.
stateRoot
:- The Keccak 256-bit hash of the root node of the state trie, after all transactions are executed and finalisations applied.
transactionsTrie
:- The Keccak 256-bit hash of the root node of the trie structure populated with each transaction in the transactions list portion of the block.
uncleHash
:- The Keccak 256-bit hash of the uncles list portion of this block
pre
section: as described in State Tests.postState
section: as described in State Tests (section - post).blocks
section is a list of block objects, which have the following format:rlp
section contains the complete rlp of the new block as described in the yellow paper in section 4.3.3.blockHeader
section describes the block header of the new block in the same format as described in genesisBlockHeader.transactions
section is a list of transactions which have the same format as in Transaction Tests.uncleHeaders
section is a list of block headers which have the same format as descibed in genesisBlockHeader.
Optional BlockHeader Sections (Information fields)¶
"blocknumber" = "int"
is section which defines what is the order of this block.
It is used to define a situation when you have 3 blocks already imported but then it comes new version of the block 2 and 3 and thus you might have new best blockchain with blocks 1 2’ 3’ instead previous. If blocknumber is undefined then it is assumed that blocks are imported one by one. When running test, this field could be used for information purpose only.
"chainname" = "string"
This is used for defining forks in the same test. You could mine blocks to chain “A”: 1, 2, 3 then to chain “B”: 1, 2, 3, 4 (chainB becomes primary). Then again to chain “A”: 4, 5, 6 (chainA becomes primary) and so on. chainname could also be defined in uncle header section. If defined in uncle header it tells on which chain’s block uncle header would be populated from. When running test, this field could be used for information purpose only.
"chainnetwork" = "string"
Defines on which network rules this block was mined. (see the difference https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.mediawiki). When running test, this field could be used for information purpose only.
State Tests¶
Found in /StateTest
, the state tests aim is to test the basic workings of the state in isolation.
It is based around the notion of executing a single transaction, described by the transaction
portion of the test. The overarching environment in which it is executed is described by the env
portion of the test and includes attributes of the current and previous blocks. A set of pre-existing accounts are detailed in the pre
portion and form the world state prior to execution. Similarly, a set of accounts are detailed in the post
portion to specify the end world state. Since the data of the blockchain is not given, the opcode BLOCKHASH
could not return the hashes of the corresponding blocks. Therefore we define the hash of block number n
to be SHA256("n")
.
The log entries (logs
) as well as any output returned from the code (output
) is also detailed.
It is generally expected that the test implementer will read env
, transaction
and pre
then check their results against logs
, out
, and post
.
Basic structure¶
{
"test name 1": {
"env": { ... },
"logs": { ... },
"out": { ... },
"post": { ... },
"pre": { ... },
"transaction": { ... },
},
"test name 2": {
"env": { ... },
"logs": { ... },
"out": { ... },
"post": { ... },
"pre": { ... },
"transaction": { ... },
},
...
}
Sections¶
- The
env
section:
currentCoinbase
currentDifficulty
currentGasLimit
currentNumber
currentTimestamp
previousHash
- The
transaction
section:
data
gasLimit
gasPrice
nonce
address
secretKey
to
value
- The
pre
andpost
sections each have the same format of a mapping between addresses and accounts. Each account has the format:
balance
nonce
code
storage
"1200"
or "0x04B0"
For values used $DATA_ARRAY.logs
sections is a mapping between the blooms and their corresponding logentries.address
The address of the logentry.data
The data of the logentry.topics
The topics of the logentry, given as an array of values.Finally, there is one simple key output
output
RETURN
instruction). See $DATA_ARRAY. In order to avoid big data files, there is one exception. If the output data is prefixed with #
, the following number represents the size of the output, and not the output directly.
- $DATA_ARRAY - type that intended to contain raw byte data
and for convenient of the users is populated with three types of numbers, all of them should be converted and concatenated to a byte array for VM execution.
The types are:
- number - (unsigned 64bit)
- “longnumber” - (any long number)
- “0xhex_num” - (hex format number)
e.g:````[1, 2, 10000, "0xabc345dFF", "199999999999999999999999999999999999999"]````
RLP Tests¶
Describes an RLP (https://github.com/ethereum/wiki/wiki/RLP) encoding using the .json file. The client should read the rlp byte stream, decode and check whether the contents match its json representation. Then it should try do it reverse - encode json rlp representation into rlp byte stream and check whether it matches the given rlp byte stream.
If it is an invalid RLP byte stream in the test, then ‘in’ field would contain string ‘INVALID’
Some RLP byte streams are expected to be generated by fuzz test suite. For those examples ‘in’ field would contain string ‘VALID’ as it means that rlp should be easily decoded.
RLP tests are located in in /RLPTests
Note that RLP tests are testing a single RLP object encoding. Not a stream of RLP objects in one array.
Basic structure¶
{
"rlpTest": {
"in": "dog",
"out": "83646f67"
},
"multilist": {
"in": [ "zw", [ 4 ], 1 ],
"out": "c6827a77c10401"
},
"validRLP": {
"in": "VALID",
"out": "c7c0c1c0c3c0c1c0"
},
"invalidRLP": {
"in": "INVALID",
"out": "bf0f000000000000021111"
},
...
}
Sections¶
in
- json object (array, int, string) representation of the rlp byte stream (*except values ‘VALID’ and ‘INVALID’)out
- string of rlp bytes stream
Difficulty Tests¶
Found in \Basic Tests\difficulty*.json
files. This tests are designed to just check the difficulty formula of a block.
difficulty = DIFFICULTY(currentBlockNumber, currentTimestamp, parentTimestamp, parentDifficulty)
described at [EIP2](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.mediawiki) point 4 with homestead changes.
So basically this .json tests are just to check how this function is calculated on different function parameters (parentDifficulty, currentNumber) in its extremum points.
There are several test files:
difficulty.json
- Normal Frontier/Homestead chain difficulty tests defined manually
difficultyFrontier.json
- Same as above, but auto-generated tests
difficultyMorden.json
- Tests for testnetwork difficulty. (it has different homestead transition block)
difficultyOlimpic.json
- Olympic network. (no homestead)
difficultyHomestead.json
- Tests for homestead difficulty (regardless of the block number)
difficultyCustomHomestead.json
- Tests for homestead difficulty (regardless of the block number)
Basic structure¶
{
"difficultyTest" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "43",
"currentBlockNumber" : "42",
"currentDifficulty" : "1000488"
}
}
Sections¶
parentTimestamp
- indicates the timestamp of a previous blockparentDifficulty
- indicates the difficulty of a previous blockcurrentTimestamp
- indicates the timestamp of a current blockcurrentBlockNumber
- indicates the number of a current block (previous block number = currentBlockNumber - 1)currentDifficulty
- indicates the difficulty of a current block
Transaction Tests¶
Describes a complete transaction and its RLP representation using the .json file. The client should read the rlp and check whether the transaction is valid, has the correct sender and corresponds to the transaction parameters. If it is an invalid transaction, the transaction and the sender object will be missing.
Basic structure¶
{
"transactionTest1": {
"rlp" : "bytearray",
"sender" : "address",
"blocknumber" : "1000000"
"transaction" : {
"nonce" : "int",
"gasPrice" : "int",
"gasLimit" : "int",
"to" : "address",
"value" : "int",
"v" : "byte",
"r" : "256 bit unsigned int",
"s" : "256 bit unsigned int",
"data" : "byte array"
}
},
"invalidTransactionTest": {
"rlp" : "bytearray",
},
...
}
Sections¶
rlp
- RLP encoded data of this transactiontransaction
- transaction described by fieldsnonce
- A scalar value equal to the number of transactions sent by the sender.gasPrice
- A scalar value equal to the number of wei to be paid per unit of gas.gasLimit
- A scalar value equal to the maximum amount of gas that should be used in executing this transaction.to
- The 160-bit address of the message call’s recipient or empty for a contract creation transaction.value
- A scalar value equal to the number of wei to be transferred to the message call’s recipient or, in the case of contract creation, as an endowment to the newly created account.v, r, s
- Values corresponding to the signature of the transaction and used to determine the sender of the transaction.sender
- the address of the sender, derived from the v,r,s values.blocknumber
- indicates network rules for the transaction. Since blocknumber = 1000000 Homestead rules are applied to transaction. (see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.mediawiki)
VM Tests¶
Found in /VMTest
, the VM tests aim is to test the basic workings of the VM in isolation. This is specifically not meant to cover transaction, creation or call processing, or management of the state trie. Indeed at least one implementation tests the VM without calling into any Trie code at all.
It is based around the notion of executing a single piece of code as part of a transaction, described by the exec
portion of the test. The overarching environment in which it is executed is described by the env
portion of the test and includes attributes of the current and previous blocks. A set of pre-existing accounts are detailed in the pre
portion and form the world state prior to execution. Similarly, a set of accounts are detailed in the post
portion to specify the end world state.
The gas remaining (gas
), the log entries (logs
) as well as any output returned from the code (output
) is also detailed.
Because the data of the blockchain is not given, the opcode BLOCKHASH could not return the hashes of the corresponding blocks. Therefore we define the hash of block number n to be SHA3-256(“n”).
Since these tests are meant only as a basic test of VM operation, the CALL
and CREATE
instructions are not actually executed. To provide the possibility of testing to guarantee they were actually run at all, a separate portion callcreates
details each CALL
or CREATE
operation in the order they would have been executed. Furthermore, gas required is simply that of the VM execution: the gas cost for transaction processing is excluded.
It is generally expected that the test implementer will read env
, exec
and pre
then check their results against gas
, logs
, out
, post
and callcreates
. If an exception is expected, then latter sections are absent in the test. Since the reverting of the state is not part of the VM tests.
Basic structure¶
{
"test name 1": {
"env": { ... },
"pre": { ... },
"exec": { ... },
"gas": { ... },
"logs": { ... },
"out": { ... },
"post": { ... },
"callcreates": { ... }
},
"test name 2": {
"env": { ... },
"pre": { ... },
"exec": { ... },
"gas": { ... },
"logs": { ... },
"out": { ... },
"post": { ... },
"callcreates": { ... }
},
...
}
Sections¶
The env
section:
currentCoinbase
: The current block’s coinbase address, to be returned by theCOINBASE
instruction.currentDifficulty
: The current block’s difficulty, to be returned by theDIFFICULTY
instruction.currentGasLimit
: The current block’s gas limit.currentNumber
: The current block’s number.currentTimestamp
: The current block’s timestamp.previousHash
: The previous block’s hash.
The exec
section:
address
: The address of the account under which the code is executing, to be returned by theADDRESS
instruction.origin
: The address of the execution’s origin, to be returned by theORIGIN
instruction.caller
: The address of the execution’s caller, to be returned by theCALLER
instruction.value
: The value of the call (or the endowment of the create), to be returned by theCALLVALUE
instruction.data
: The input data passed to the execution, as used by theCALLDATA
… instructions. Given as an array of byte values. See $DATA_ARRAY.code
: The actual code that should be executed on the VM (not the one stored in the state(address)) . See $DATA_ARRAY.gasPrice
: The price of gas for the transaction, as used by theGASPRICE
instruction.gas
: The total amount of gas available for the execution, as would be returned by theGAS
instruction were it be executed first.
The pre
and post
sections each have the same format of a mapping between addresses and accounts. Each account has the format:
balance
: The balance of the account.nonce
: The nonce of the account.code
: The body code of the account, given as an array of byte values. See $DATA_ARRAY.storage
: The account’s storage, given as a mapping of keys to values. For key used notion of string as digital or hex number e.g:"1200"
or"0x04B0"
For values used $DATA_ARRAY.
The callcreates
section details each CALL
or CREATE
instruction that has been executed. It is an array of maps with keys:
data
: An array of bytes specifying the data with which theCALL
orCREATE
operation was made. In the case ofCREATE
, this would be the (initialisation) code. See $DATA_ARRAY.destination
: The receipt address to which theCALL
was made, or the null address ("0000..."
) if the corresponding operation wasCREATE
.gasLimit
: The amount of gas with which the operation was made.value
: The value or endowment with which the operation was made.
The logs
sections is a mapping between the blooms and their corresponding logentries. Each logentry has the format:
address
: The address of the logentry.data
: The data of the logentry.topics
: The topics of the logentry, given as an array of values.
Finally, there are two simple keys, gas
and output
:
gas
: The amount of gas remaining after execution.output
: The data, given as an array of bytes, returned from the execution (using theRETURN
instruction). See $DATA_ARRAY.
- $DATA_ARRAY - type that intended to contain raw byte data
- and for convenient of the users is populated with three types of numbers, all of them should be converted and concatenated to a byte array for VM execution.
The types are: 1. number - (unsigned 64bit) 2. “longnumber” - (any long number) 3. “0xhex_num” - (hex format number)
e.g:
````[1, 2, 10000, "0xabc345dFF", "199999999999999999999999999999999999999"]````
Web3基础层服务¶
作为以太坊区块链的补充,使web应用程序的很多其他重要部分去中心化的更多组件也被开发了出来。

Swarm - 去中心化数据存储和分发¶
Swarm是一个点到点数据共享网络,文件会由它们的内容哈希作为地址。像Bittorrent一样,可以从很多节点同时获取数据,每个节点只提供一部分数据,从任何地点都可以访问。这种方法使不使用任何服务器就可以分发数据,数据访问也不依赖位置。
网络中的其他节点能够被激励来复制和存储数据,从而免除当原始节点没有接入网络时对托管服务的需要。
名称注册¶
由于Dapp可以被保存到任何地方,包含Swarm网络,名称注册可以将名称和它们的内容或地址进行映射。这其实就是一种去中心化的域名系统(DNS)。
常见问题¶
- 问题
- 什么是以太坊?
- 我听说过以太坊,但什么是Geth、Mist、Ethminer和Mix呢?
- 我如何在区块链上存储大型文件?
- 以太坊是基于比特币的么?
- 以太坊的未来是什么?
- 账户和“钱包合约”的区别是什么?
- 秘钥文件是否仅能在我下载客户端的电脑上访问?
- 下载区块链大概要花多长时间?
- 我如何获得进出一个地址的所有交易列表?
- 一个合约可以自己支付它的执行消耗么?
- 一个合约可以调用其他合约么?
- 一个交易可以进行离线签名,然后提交到在线装置上么?
- 如何获得测试网络的以太币?
- 一个交易是否可以由第三方发送?比如,将交易广播外包
- 以太坊合约可以通过第三方API来拉取数据么?
- 以太坊网络上发送的数据和合约内容是加密的么?
- 我可以在以太坊网络上存储隐私数据或者密码么?
- 以太坊如何对付那些中心化的矿池?
- 以太坊如何处理一直在增长的区块链规模?
- 以太坊如何确保提供每秒10000+的交易能力?
- 智能合约保存在哪儿?
- 你的问题依然没有得到解答?
问题¶
我听说过以太坊,但什么是Geth、Mist、Ethminer和Mix呢?¶
- Geth :这是个以太坊节点的Go语言实现,是与以太坊区块链交互的基础。在本地运行这个程序可以使你很容易地和以太坊区块链进行交互。请参考 go-ethereum installation instructions 。
- Mist :这相当于以太坊平台中的Web浏览器,它作为一个GUI来显示与你交互的账户及合约。它也允许你在图形界面中创建并与合约进行交互而不使用命令行。如果你不是一个开发者,仅仅想存储以太币并与以太坊合约进行交互,Mist就是该使用的程序。你可以在 Mist发布页面 下载它。
- Ethminer :一个独立的矿工。它可以用来挖矿或为挖矿做评估。它与eth、geth和pyetherem兼容。请查看 挖矿 获得更多信息。
- Mix :这是为DApp作者们提供的集成开发环境,使用它可以在以太坊平台上快速构建原型和调试去中心化应用程序。更多信息请参考 Mix GitHub Page 。
我如何在区块链上存储大型文件?¶
通常来讲,因为在以太坊区块链上的存储成本很高,所以一般不会在其上存储大型文件或者数据块。你可以使用一个第三方的解决方案,比如Swarm或者IPFS。Swarm是一个为以太坊设计的分布式文件存储方案。IPFS是一个非以太坊工程,但与以太坊有紧密的关联;它可以独立使用并且可能会在未来被添加到Swarm之下作为独立的层级。参考 this Ethereum StackExchange post on the topic 获得更多信息。
以太坊是基于比特币的么?¶
仅仅在使用了比特币开创的区块链技术这方面,是的。以太坊是一个独立的区块链,并且使用了很多不同于比特币区块链的重要技术。更详尽的解释请参考 this Ethereum StackExchange answer 。
以太坊的未来是什么?¶
以太坊开发者正在计划一个在未来由工作量证明共识到权益证明共识的切换。他们也在研究如何在区块链上保存隐私数据的扩展方案。
账户和“钱包合约”的区别是什么?¶
一个账户是你的公/私钥对来在区块链上作为你的标示,请参考术语表中的“账户”。而“钱包合约”是一种以太坊智能合约,它可以保护你的以太币和身份,并提供一些诸如多重签名认证、程序化的储蓄/取出限制等特性。一个钱包合约可以简单的由以太坊钱包的Mist图形客户端创建。
秘钥文件是否仅能在我下载客户端的电脑上访问?¶
不是。你可以随意导出或移动你的秘钥文件,但记得做好备份,记住你在哪些电脑上存储了它们。
下载区块链大概要花多长时间?¶
以太坊区块链在不断的增长,到2016年3月已经达到大约10GB。下载全部数据的时间,取决于你能链接到多少节点、你的互联网链接速度及一些其他条件。请参考 更快的下载区块链 来获知更快地同步区块链的方法。
我如何获得进出一个地址的所有交易列表?¶
你需要手工把交易信息从区块链中导出。或者你可以使用第三方的浏览器API,比如 Etherchain 。然而对于合约执行的交易,你可以通过过滤合约日志来实现。
一个合约可以自己支付它的执行消耗么?¶
不,这不可能。执行操作所需的气,必须有提交执行请求的地址所提供。
一个合约可以调用其他合约么?¶
是的,可以。请参考 合约间的交互 。
一个交易可以进行离线签名,然后提交到在线装置上么?¶
可以,你可以从 Icebox 参考具体方案。
如何获得测试网络的以太币?¶
请参考 测试网络 。
一个交易是否可以由第三方发送?比如,将交易广播外包¶
技术上说,可以。但比特币签名时的一个重要限制妨碍了这么做:在以太坊中,每个交易都有一个nonce(更确切地说,每个账户都会有个计数器,记录它已经发送了多少交易。如果当前账户发送过3个交易,这个账户的nonce将是3)。
以太坊合约可以通过第三方API来拉取数据么?¶
不行,以太坊合约不能从外部数据源拉取数据。然而,通过交易从外部站点推送数据(例如天气网站或股票价格)到以太坊合约是可能的。有一些“权威”的有偿服务可以提供到以太坊拉取/推送数据的兼容性。
以太坊网络上发送的数据和合约内容是加密的么?¶
以太坊网络中的数据和合约是经过编码的,但不是加密的。所有人都可以审计合约的行为和发送给他们的数据。然而,你可以随时在本地加密数据之后再把它们广播到网络上。
我可以在以太坊网络上存储隐私数据或者密码么?¶
以太坊上的所有数据都是公开的。在以太坊合约中存储隐私数据或密码是无法保证它们不被其他人看到的。通过代码模糊(code obfuscation)和其他技术手段使这成为可能的研究工作正在进行。Vitalik Buterin写的 Privacy on the Blockchain 是一个很好的参考。
以太坊如何对付那些中心化的矿池?¶
基于以太坊工作量证明的共识算法有两种主要方法对付中心化的挖矿( 原文 )。
- 首先是降低因孤儿区块(orphaned blocks,即因主分叉增长而缺失父区块导致被废弃的区块,译者注)导致的损失,以使独立的矿工有更多的参与度。
- 以太坊挖矿算法的这部分,即GHOST,使包含最近的孤儿区块的区块产出节点和包含了这些孤儿区块的节点都能获得一些降低的报酬(与主分叉中的区块产出节点获得的报酬相比,译者注)。这些被包含的从“祖父”看是孤儿或更早的区块通常是指那些“叔舅”区块(即因为分布式计算/共识校验的原因,导致这些区块的父区块的父区块相同,但父区块不同,译者注),因为关于中立性别的术语“ommer”并不广为人知。
- 第二个用以对抗中心化挖矿方法是以太坊的工作量证明共识算法是有ASIC抗性的。
- 通过阻止那些用专门设计生产的计算硬件来争取统治地位的挖矿,独立的矿工可以保持竞争力甚至有了某种在它们那个硬件投资等级上的利润优势,因为它们可以使用那些商品化的硬件(比如普通消费者所使用的显卡)。
以太坊如何处理一直在增长的区块链规模?¶
围绕区块链的扩展有很多讨论。这个问题在 Ethereum StackExchange post 和 Vitalik Buterin的这篇博客 上可以得到部分的解答。
以太坊如何确保提供每秒10000+的交易能力?¶
以太坊计划在开发路线图的Serenity阶段(下一个生产版本,译者注)实现一个权益证明共识协议。关于以太坊的权益证明的更多信息以及它如何提高秒级交易量可以 在这里找到 。
智能合约保存在哪儿?¶
待续。
你的问题依然没有得到解答?¶
请在 Ethereum StackExchange 向社区提问。
术语表¶
- Đ
- Đ, 加了横线的D 是在古英语、中世纪英语以及冰岛语、法罗斯群岛语中的一个大写字母”Eth”。它被用在像ĐEV或Đapp(去中心化应用)这样的词中,在这里,Đ是一个斯堪的纳维亚语的字母”eth”。大写的eth(Đ)也被用来做加密货币Dogecoin(Doge币)的象征。
- 去中心化应用 (= dapp)
- 脱离中心化的信任机构而运作的服务。一种允许脱离中间人而使最终用户/资源可以直接进行互动、达成协议或交换信息的应用程序。参考 Dapps 。
- DAO
- 去中心化自治组织。DAO是区块链上的一种类型的合约(或者一套合约),它可以制定规则、强制执行或自动化包括组织管理、资金筹措、实操、开销和扩张在内的一些组织级的工作。
- 身份(identity)
- 由同一个人创建的一组可以通过某种方式进行验证的交互。
- 数字身份(digital identity)
- 一组使用相同公钥签名的、可以进行验证的交易,定义了数字身份的行为。在很多真实场景(比如投票)会希望数字身份可以和真实身份相符。如何非暴力地确保这一点,是个仍然未被解决的问题。
- 唯一身份(unique identity)
- 由同一个人创建的一组可以通过某种方式进行验证的交互,外加一个限定:一个人不会同时具有多个身份。
- 名声(reputation)
- 一个被其他实体所相信 (1) 有能力完成某项任务, (2) 在某些情况下值得信任(例如即使有短期获益的可能,也不会背叛其他人)的身份所拥有的财产(所有物)。
- 第三方监管(escrow)
- 如果两个互不信任的实体有意进行交易,他们也许会希望通过一个他们分别信任的第三方来处理资金转移;只有当产品交付的证明确认之后,资金才会被划转给收款方。这降低了付款方或者收款方进行欺诈的风险。这个过程和这个第三方就被叫做escrow。
- 保证金(deposit)
- 一些数字资产可以被加入一个合约,并在合约中包含另一方;当一个特定的条件无法达成时,这些数字资产会自动丧失,被奖励给认定这个条件的另一方,或者销毁掉(= 消费掉 = 被分发出去),或者被捐赠给一些信托基金。这些数字资产就是所谓的押金。
- 信任网络(web of trust)
- 这是一种设想:如果A高度认可B,并且B高度认可C,那么A可以信任C。基于这种原理,从理论上讲,判断特定概念中的特定个体间的可靠性的更复杂、更有效的算法,是可以被设计出来的。
- 激励相融(incentive compatibility)
- 这是一种协议,如果任何人想要“不遵守规则”来尝试欺诈,那么除非大多数人都在同时同意这种欺诈(共谋),否则无法达成。
- 共谋(collusion)
- 指在一种激励性的协议下,一部分参与者 一起假扮 (密谋)基于规则为他们自己牟利。
- 代币系统(token system)
- 一种可以被交易的不可替换的虚拟货物。更正规的讲,一个代币系统就是一个将许多资产映射为地址的数据库。其中所允许的主要操作就是N个代币由A转移到B,N不能为负数,N不大于A的余额,并有一份文档记录这个由A签名的转移授权。此外,类似于“保险”和“消费”的操作也是可以存在的,交易费会被收取,多个实体间同时发生的多重交易也是可能的。典型的使用场景包含货币、网络中的加密代币、企业股份和数字礼品卡。
- 区块(block)
- 一个区块就是一个数据包。包含了若干交易、前一区块(父区块)的哈希和其他可选数据。所有区块的总和就叫做区块链,包含了网络中所有交易的历史;除了最开始的“创世区块(genesis block)”以外,每个区块都包含一个它父区块的哈希。一些基于区块链的加密货币使用“账本(ledger)”一词,而不是区块链;但他们大体上是等价的。不过,在那些使用”账本“术语的系统中,每个区块一般会包含一个所有账户当前状态的完整拷贝(比如货币余额、部分满足的合约、登记项目等),来允许用户丢弃过时的历史数据。
- dapp
- 即Đapp,就是“去中心化应用程序”。因为使用了 大写的eth字母Ð ,也可以把它读作Ethapp。
- 地址(address)
- 一个以太坊地址代表了一个账户。对于 EOA ,地址是由控制账户的公钥的最后20字节获得的,例如
cd2a3d9f938e13cd947ec05abc7fe734df8dd826
。这是个 16进制 格式,一般更明确地以0x
作为前缀。在Web3.js和控制台函数中使用地址时可以不加前缀,但我们推荐使用它们。由于每字节地址由两个16进制字符标示,所以加上前缀的地址长度就是42字节。很多应用和API都实现了从Mist以太坊钱包0.5.0版本开始引入的新的 可校验地址规则(checksum-enabled address scheme) 。
- 16进制(hexadecimal)
- 表示字节序列的一般格式。它的优点是可以使用两个字符(字符
[0-9][a-f]
)来简洁地表示一字节数据的值。- 以太币(ether)
- 以太币是以太坊中所使用的货币的名称。它用来支付EVM中的计算费用。此外略有歧义的,它也是系统中一个计量单位的名称。
- 外部账户(EOA)
- 即Externally Owned Account,一个由唯一私钥控制的账户。如果你拥有一个EOA的私钥,你就可以使用它来发送以太币和消息。合约账户也有一个地址,参考 账户 。从Serenity版本开始,EOA和合约账户可以组合到同一个账户中。
- 气(gas)
- 即所谓 加密燃油(cryptofuel) 的名称,由EVM在执行代码时所消耗。气被用来支付以太坊区块链上的每个执行所需的费用。
- 气的上限(gas limit)
- 气的上限可以被应用到单独的交易中,参考 气价 ,也可以被用在区块中 block-gas-limit 。对于单独的交易,气的上限表示了你希望为执行合约的交易所支付的最大的气的数量。它是为了保护用户,使他们的以太币不会在尝试执行一个大任务或者恶意合约时被花光。区块的气上限,代表了区块中所有交易的气的累积。随着Homestead的发布,区块的气上限从3,141,592提高到4,712,388(大约增加了50%)。
- 气价(gas price)
- 即在交易中指定的每单位气所对应的以太币价格。随着Homestead的发布,默认的气价从50 shannon降低到20 shannon(大约降低了60%)。
- 交易(transaction)
- 一个由外部账户发出的签名数据包,其中保存一个消息。一个交易就是从一个外部账户到另一个外部账户或合约账户的信息转移。
- 消息(message)
- 合约与合约之间进行数据传输的一种机制。消息也可以被描述为一种虚拟对象,它不会被序列化,并且仅存在于以太坊执行环境中。
- Web3
- Web3的确切定义仍在被讨论,但它一般是指由日益增长的各种可连接设备、去中心化服务和应用程序、在线信息的逻辑存储和人工智能应用程序所组成的网络。
- epoch
- Epoch是DAG的生成周期,DAG是PoW算法Ethash所使用的种子。Epoch被指定为30000个区块。(即每隔30000个区块需要重新生成DAG,译者注。)
- 椭圆曲线(elliptic curve,密码学)
- 一个基于椭圆曲线代数结构的公钥密码学算法。参见 椭圆曲线加密 。
- 钱包(wallet)
- 一般意义上说,钱包就是任何可以保存以太币或其他加密货币的载体。在加密货币领域,钱包一般是指从可以保存单一公私钥对到管理多个密钥对的任何载体,比如Mist以太坊钱包。
- 合约(contract)
- 以太坊区块链上的一些持久化的代码,包含可执行函数的数据。当包含特定输入参数的以太坊交易发生时,这些函数可以运行。函数可以基于输入参数与合约内外的数据进行交互。
- 自杀(suicide)
- 参考自毁。依照 EIP 6 - Renaming SUICIDE OPCODE
自杀(suicide)
已不推荐使用。自毁(selfdestruct)
是与其等价的术语。- 自毁(selfdestruct)
- Solidity语言中的一个全局变量,允许你`“销毁当前合约,把它的资金发送到给定的地址上” <https://solidity.readthedocs.org/en/latest/miscellaneous.html#global-variables>`_ ,是已不推荐使用的术语自杀(suicide)的同义词。它会释放在区块链上的空间,并防止合约再被执行。合约的地址仍然回存在,但发送到其上的以太币会永远丢失。合约的创建者可以使用Solidity的
selfdestruct
函数来删掉合约。- 交易费(transaction fee)
- 也就是气费(gas cost),是为了执行你的交易所需要支付给矿工们的以太币的数量。
- 挖矿(mining)
- 在以太坊区块链上校验交易和合约的执行(挖到区块),以此来交换一个以以太币为单位的奖励的过程。
- 矿池(mining pool)
- 一个由矿工所组成的资源池,它们通过一个网络共享处理能力,依照解决一个区块所贡献的工作量分配收到的奖励。
- 挖矿奖励(mining reward)
- 挖到一个新区块的矿工会被给予的加密货币(在这里是以太币)奖励。
- 状态(state)
- 区块链上所有余额和数据在某个时间点的快照,一般指某个特定区块的状况。
- 区块链(blockchain)
- 一个永远增长的数据区块序列。当一个新交易被作为一个新区块的一部分被确认的时候,它会得以增长。每个新区块都会基于一个密码学的工作量证明(PoW)而添加到当前区块链的尾部。
- 端点(peer)
- 网络上其他也在运行以太坊节点(Geth)的计算机,和你一样,它们也都有一个准确的区块链拷贝。
- 签名(signing)
- 用你的私钥生成一些表示签名的数据,来证明数据的原始拥有者是你。
- 发现(端点)
- 与网络中的其他‘攀谈’的过程,以此来获取其他节点的状态。
- 权威气价(gas price oracle)
- 一个Geth客户端的辅助函数,在发送交易时可以找到一个合适的默认气价。
- 轻客户端(light client)
- 允许用户在一个低容量环境中执行和检查交易执行,而不用去运行一个以太坊全节点(Geth)的客户端程序。
- etherbase
- 你的节点上的账户的默认名称,它会作为你的主账户。如果你进行挖矿,挖矿奖励会被存入这个账户。
- coinbase
- 一个与etherbase类似的概念,但也是个所有加密货币平台所通用的术语。
- 余额(balance)
- 属于一个账户的加密货币(在现在这个事例里)的数量。
- solidity
- Solidity是一个高级开发语言,语法规则接近Javascript。它被设计用来编译以太坊虚拟机的代码。
- serpent
- Serpent是一种高级开发语言,语法规则接近Python。它被设计用来编译以太坊虚拟机的代码。
- EVM
- 即以太坊虚拟机(Ethereum Virtual Machine),它是构成以太坊平台的去中心化核心计算平台。
- 虚拟机(virtual machine)
- 在计算机领域,它指一种对特定的计算机系统的模拟。
- 端到端网络(peer to peer network,即P2P网络)
- 一个由计算机组成的网络,可以完成那些仅可能由中心化的、基于服务器的服务所完成的功能。
- 去中心化(decentralization)
- 一种将控制和计算处理的执行从中心化的实体中移出的概念。
- 分布式哈希表(Distributed Hash Table,DHT)
- 分布式哈希表是一种去中心化的分布式系统,可以提供类似于哈希表功能的查找服务。DHT中保存的是键、值对,网络中的任何节点都可以通过特定键高效地取得相应的值。
- 网络地址翻译(Network Address Translation,NAT)
- 一种将一个IP地址重映射到其他地址的方法。这是通过在网络路由设备中传输数据包时修改数据包头数据中的网络协议(IP)信息而做到的。
- nonce
- 即一次性数字。在信息技术里,nonce就是为了某个特定目的而生成的数字,比如会话验证(session authentication)。典型地,nonce应该是一些随时间而变化的数值,因而有时会使用一个很大的随机数。一般而言,nonce意味着“邻近的时刻”或者“临时”。在区块链的工作量证明场景中,适合当前网络难度来证明区块有效性的那些由矿工找到的哈希值,被称为Nonce。
- 工作量证明(proof-of-work)
- 指一个数学上的值,可以证明已经解决了一个消耗资源和时间的计算问题。一般以缩写形式“PoW”出现。
- 权益证明(proof-of-stake)
- 挖矿操作的一种替代方法,需要矿工通过回答问题的方式证明它们拥有一定量的网络货币。这基于一个原理,就是矿工们不应该会去尝试破坏一个它们拥有权益的网络。权益证明一般以缩写形式“PoS”出现。与PoW相比,PoS可以降低算力的浪费,但它同样也可以给网络提供额外的安全性。
- CASPER
- Casper是一个基于保证金的经济学共识协议。这意味着被称为“bonded validators”的节点,需要为了在通过产生区块而达成共识的时候缴纳一份保证金(我们称之为“bonding”的一种行为)。如果一个验证器(即某个节点)产生了一个被Casper认为“无效”的数据,它就会丧失这个保证金和继续参与共识过程的权力。
- 共识(consensus)
- 指网络中所有节点关于以太坊网络状态的一致认同。
- homestead
- Homestead是以太坊平台的第二个主版本。它包含了很多未来网络升级所需的协议改动和网络改动:EIP-2 Main homestead hardfork changes ; EIP-7 Hardfork EVM update (DELEGATECALL) ; EIP-8 devp2p forward compatibility 。他已经在主网络到达1,150,000区块时被引入了。在测试网路中,它是在494,000区块时被引入的。
- metropolis
- 以太坊的第三个发布版本。这是个用户界面出现的阶段(比如Mist),包括dapp商店。非技术背景的用户也可以在这个时候舒服的加入了。
- serenity
- 以太坊的第四个发布阶段。这将是我们希望将网络中的挖矿过程由工作量证明迁移到权益证明的时候。
- frontier
- 以太坊被计划为执行四个主要的阶段,Frontier是第一阶段的名称。Frontier版本已经在2015年7月30日发布。在这个命令行方式的Frontier阶段,每个区块奖励都被定为5以太币,并允许以太币的兑换。Frontier大大超过了早期的预料,使以太坊的生态系统得到了巨大的成长。
- olympic
- Frontier的先期发布版本,于2015年5月9日上线。它是为了使开发者可以测试以太坊区块链的各种边界限制。
- morden
- Morden是以太坊的第一个替代性测试网络。预计它会从Frontier到Homestead阶段一直持续存在。
- 测试网络(testnet)
- 为测试目的而存在的以太坊生产环境的镜像网络。参见morden。
- 私链(private chain)
- 私链就是一个写入权限中心化地由一个组织所掌握的区块链。
- 联盟链(consortium chain)
- 一个共识处理由预设的若干节点所控制的区块链。
- 微支付(micropayment)
- 微支付就是经常在线上活动发生的,交易额很小(小于1美元)的财务交易。
- 分片(sharding)
- 将可能的账户(合约也属于账户)空间切分为子空间的处理,比如基于它们的数字地址的首数字。这可以使合约在‘片’上执行,而不是在整个网络中,从而使交易更快速完成,并提供了一种更强的可扩展性。
- 哈希(hash)
- 一个密码学功能,它可以接受一个输入(或‘消息’),产生一个定长的字符串,被称为哈希值(有时也称为消息摘要、数字指纹、摘要或者检查计数)。哈希函数(或哈希算法)是一种将文档(比如一部分数据或文件)变换为一个较小数据(通常是32字节)的处理。哈希值看起来是完全随机的,并且与文档毫无关联的数据,但特定的文档经过哈希处理所得到的值总是一样的。此外最重要的是,要找到两个具有同样哈希值的文档是极为困难的计算处理。一般而言,即使两个文档中只有一个字母的不同,它们也会产生完全不同的哈希值。比如,“Saturday”的SHA3哈希值是
c38bbc8e93c09f6ed3fe39b5135da91ad1a99d397ef16948606cdcbd14929f9d
,而“Caturday”的SHA3哈希值则是b4013c0eed56d5a0b448b02ec1d10dd18c1b3832068fbbdc65b98fa9b14b6dbf
。哈希总是被用做生成某个特定文档的不可伪造的全局唯一标示的方法。- 加密燃油(crypto-fuel)
- 就是‘气’,指处理交易所需要的加密货币数量。
- 加密经济学(cryptoeconomics)
- 即加密货币的经济学。
- 协议(protocol)
- 一个用来定义通过计算机网络交换数据的方法的标准。
- 区块认可(block validation)
- 即通过存储在区块链上的历史数据对区块的密码学签名进行合法性校验。
- 区块时间(blocktime)
- 挖矿产生两个区块的平均时间间隔。
- 网络哈希率(network hashrate)
- 网络中节点每秒可以完成的哈希计算次数总和。
- 哈希率(hashrate)
- 每秒可以完成的哈希计算次数。
- 序列化(serialization)
- 把数据结构变换为字节序列的处理。以太坊内部使用一个被成为Recursive-Length Prefix(RLP)编码的格式,在 wiki的RLP这一节 中有具体描述。
- 双花(double spend)
- 一个故意的区块链分叉;一个有大量挖矿算力的用户发送了一个交易来订购一些产出,然后当收到相应的产品之后,创建另一个交易,将与之前交易里的花销等量的代币再发送给自己。攻击者会在与原始交易同级的地方创建一个包含了第二个交易的新区块,然后在这个新的分支上开始挖矿。如果攻击者拥有超过全部挖矿算力50%的算力,就可以确保双花在任何区块深度上都能最终实现。如果攻击者的算力不足50%,那么虽然有可能会实现,但最多只能维持2到5个区块;所以,大多数加密货币交易、对赌网站和财务服务,会等到第六个区块产生才接受一个支付交易。
- SPV客户端(SPV client)
- 一个仅下载区块链的一小部分的客户端,允许用户在低算力或低存储的硬件(比如智能手机和手提电脑)上来获得同样的安全保障,仅在必要的时候下载一部分状态信息。这种客户端不需要花费很高的带宽或存储去校验和维持全部的区块链数据。参考轻客户端。
- uncle
- Uncle就是某个矿工在其他矿工已经找到的区块的相同位置找到的区块,它们被称为“stale blocks”。Uncle的父区块是要插入的区块的一个祖先,可以定位到区块链的尖端。与比特币网络不同,为了避免对于那些网络条件欠佳的矿工的惩罚,“stale blocks”也会得到奖励。因为比特币网络的区块时间(约10分钟)比在以太坊网络中(小于15秒)高出很多,所以这个问题在比特币网络中并不严重。
- GHOST
- 即Greedy Heaviest-Observed Sub-Tree,是一种特殊的链选择(chain-selection)方法,它被设计用来激励stale blocks(uncle),从而降低对矿池挖矿的激励。在GHOST中,即使是由stale block给出的对先前区块的确认也是有效的,产出stale block的矿工也会得到挖矿奖励。
- merkle patricia tree
- Merkle Patricia tree提供了一种密码学的验证数据结构,能够存储所有的(键,值)绑定。它们是完全可预测的,就是说具有相同的(键,值)绑定的Patricia tree会确保其下的所有字节都相同,所以会有相同的根哈希(root hash)。它为插入、查找和删除提供了0(log(n))的复杂度,并且比像红黑树(red-black tree)这种更复杂的基于比较的可选方案更容易理解和用编码实现。
- DAG
- 即Directed Acyclic Graph。它是一个由一组节点和节点间的连接所组成的图,具有非常特殊的属性。以太坊在其工作量证明算法Ethash中使用DAG。Ethash中使用的DAG会会花费较长的时间才能生成,它会在每次切换Epoch时被矿工节点生成并存入一个缓存文件,而后当算法需要时,从文件中取得相应的值。
- uncle rate
- 每个区块所产生的uncle数量。
- issuance
- 对一个发现新区块的矿工进行的、新的加密货币的铸造和授予。
- 预售(presale)
- 在网络实际发布之前的加密货币销售。
- 静态节点(static node)
- 以太坊客户端Geth、Golang支持的一种特性,允许总是连接到特定的节点。静态节点会在断线时重新连接。请参考 静态节点的章节 。
- 引导节点(bootnode)
- 当一个节点运行的时候,可以被用来初始化发现过程的节点。这些节点的接入点是在以太坊代码之中记载的。
- 兑换(exchange)
- 一个在线交易市场,可以基于市场兑换比率进行加密货币和官方货币的兑换。
- 编译器(compiler)
- 一个可以将高级语言书写的代码变换为低级的可执行代码的程序。
- 创世区块(genesis block)
- 区块链中的第一个区块。
- 网络ID(network id)
- 一个用来标示以太坊网络特定版本的数字。
- 区块头(block header)
- 一个区块中一组数据,具有针对区块的内容和区块创建时的状况的唯一性。它包含了前一个区块头的哈希、挖出当前区块的软件版本、时间戳以及区块内容的merkle根哈希。
- 待定的交易(pending transaction)
- 一个尚未被以太坊网络所确认的交易。
- 区块广播(block propagation)
- 将一个已确认的区块传送给网络中的所有节点的过程。
- 侧链(sidechain)
- 从主链上分支出去的、周期性地进行检查的一个区块链。由于侧链是脱离主链独立运行的,所以其上的安全损害不会影响到主链。
- pegging
- 单向地锁定两个链上的货币/代币兑换比率(通常是一个主链和一个侧链)。
- 2-way pegging
- 双向地锁定两个链上的货币/代币兑换比率(通常是一个主链和一个侧链)。
- 去信任(trustless)
- 指一种网络能力,通过可信的方式完成交易,而不需要相关各方信任其他任何人。
- faucet
- 一个随意分发加密货币(一般是测试网络)的网站。
- 检查计数(checksum)
- 一次数据传输中的数据位计数,它会被包含在数据单元中,以便接收方可以验证所有的数据都被传输完成了。
- ICAP
- 即Interexchange Client Address Protocol,是一个用来标示和处理用户账户的、兼容IBAN(国际银行账户编号)的系统。它旨在提高资金转移的效率、保证汇兑安全,最终,使KYC(Know Your Customer,指了解客户)和AML(Anti-money laundering,即反洗钱)顾虑成为过去。
- 私钥(private key)
- 私钥是一个仅拥有者才知道的字符串,和其所对应的公钥一起被文本加密解密算法所使用。
- 公钥(public key)
- 一个由私钥衍生出来的字符串,可以公开。它被用来校验由私钥生成的签名的真实性。
- 编码(encryption)
- 编码就是一个将电子数据变换为其他人不可读的格式的处理,只有拥有正确的解码密钥的人才能获知原始数据。就是将一个称为密钥的较短的字符数据(比如
c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4
)混合进原始数据(纯文本)中产生一个输出(加密文本),这个输出可以被持有密钥的人“解码”为原始的数据,但其他任何没有密钥的人都无法进行解码。- 数字签名(digital signature)
- 一个用来证明一个数字消息或文档真实性的数学方案。
- 端口(port)
- 一个网络端口就是由实现网络数据交互的现成标准(比如TCP、UDP)所使用的通信端点。
- RPC
- 即Remote Procedure Call,是一种无需了解网络细节,就可以从网络中的远程计算机上请求一个服务的程序协议。
- IPC
- 即Interprocess communication,是一组变成接口,允许程序员在一个操作系统中跨多个程序进程完成一些协作任务。
- attach
- 一个可以初始化以太坊Javascript控制台的命令。
- daemon
- 一种后台运行的计算机程序,不直接与用户进行交互。
- 系统服务(system service)
- 参考base layer service
- 基础服务(base layer service)
- 像Swarm和Whisper这样内置在以太坊平台的服务。
- js
- Javascript.
- 同步(syncing)
- 下载全部区块链数据的过程。
- 快速同步(fast sync)
- 快速同步仅下载区块的交易收据并拉取最新的状态数据库,而不是一次性处理全部区块链并回顾所有历史交易。
- ASIC
- 即Application-specific integrated circuit,在这里指专为加密货币挖矿所设计的特制集成电路。
- 强存储(memory-hard)
- 强存储功能就是那些即使有效存储略微降低,也会使速度和可用性大幅降低的处理。
- keyfile
- 每个账户的私钥/地址对都被保存在一个keyfile里边。这是一个包含了账户的加密私钥的JSON文本文件,只有创建账户过程中输入的密码才能对其进行解密。
- ICAP格式(ICAP format)
- 使用 Inter-exchange Client Address Protocol 定义的IBAN(国际银行账户编号)格式。
- 区块链浏览器(block chain explorer)
- 一个允许简单的从区块链搜索和导出数据的网络站点。
- geth
- 基于以太坊黄皮书定义的协议,用Golang程序设计语言实现的以太坊客户端。
- eth
- 基于以太坊黄皮书定义的协议,用C++程序设计语言实现的以太坊客户端。
- ethereumjs
- 基于以太坊黄皮书定义的协议,用Javascript程序设计语言实现的以太坊客户端。
- pyethereum
- 基于以太坊黄皮书定义的协议,用Python程序设计语言实现的以太坊客户端。
- ethereumj
- 基于以太坊黄皮书定义的协议,用Java程序设计语言实现的以太坊客户端。
- ethereumh
- 基于以太坊黄皮书定义的协议,用Maskell程序设计语言实现的以太坊客户端。
- parity
- 基于以太坊黄皮书定义的协议,用Rush程序设计语言实现的以太坊客户端。
- 难度(difficulty)
- 最简单的讲,就是挖到一个新区块所需的工作量。随着Homestead的发布,难度调整算法也改变了 。
- 账户(account)
- 账户是以太坊网络的中心部分,也是任何交易或合约的必要组成部分。在以太坊中由两种类型的账户:外部账户(EOA)和合约账户。
- HLL (obsolete,淘汰的)
- 即Higher Level Language,就是Serpent和Solidity这样的语言。HLL也是早期的Ðapp开发者对不涉及低级元素的以太坊程序设计语言的称呼,这个习语已经被逐步废除了。
- CLL (obsolete,淘汰的)
- 即C Like Language,就是Mutan这样的语言。这个缩写也已经被废除了。
- ES1, ES2, and ES3 (obsolete,淘汰的)
- “Ethereum Script”的版本1,2和3。这些是以太坊虚拟机(EVM)的早期版本。
- 日志事件(log event)
- 合约是被作为区块验证的一部分的交易执行所触发的。如果把它们想象成为函数调用,那么合约执行就是异步的,所以它们没有返回值。取而代之地,它们是用日志事件与外部世界进行通信的。日志事件是交易收据的一部分,是在交易执行时产生的。收据是被保存在收据二叉树上的,收据二叉树是作为区块头的一部分,和状态二叉树的根状态一起保存的,这保证了它的完整性。更广义地从外部来看,除了这些收据不是能从内部读取的合约以外,它们是以太坊系统状态的一个组成部分。
Homestead文档计划¶
目的和受众¶
这份手册是为所有以太坊用户和开发者提供的入门级的资料。
这份手册的目标是为使用以太坊与去中心化应用(dapp)进行交互或开发一个去中心化应用提供初级和中级功能的简短流程向导和样例。
任何对于上述目标而言过于具体、技术或不必要的内容都被保留在以太坊的Github Wiki上。如有必要,会在这份手册中保留链接。
虽然很多内容在Frontier和Homestead手册里是很接近的,但还是需要很多精力去确认这里记述的内容是精确的。这份文档不是针对特定客户端的,样例和流程向导可能会涉及各个客户端,作者会根据样例/流程向导指明其所使用的客户端。
尽管过于具体和技术性的文档不会被包含在这份手册的首次迭代中,但这份手册的受欢迎程度和其社区内的使用,会在未来决定是否将Github Wiki中的文档迁移过来。
过于具体和技术型的文档包括:
- ETHash、CASPER、ABI、RLP或其他技术说明。
- 针对协议的完整的API说明。警告:如果一个样例、信息或流程指引需要参考某个客户端的API调用或者界面来完成,那么这种参考是可以接受的。但请确保你保留了链接,以便让用户可以找到可能在Github Wiki上的具体文档。
范例文档资源¶
这里是一些先前的以太坊文档和一些范例文档。
- Solidity Docs - https://ethereum.github.io/solidity/docs/home/
- Frontier Guide - https://ethereum.gitbooks.io/frontier-guide/content/
- Gav’s TurboEthereum Guide - https://gavofyork.gitbooks.io/turboethereum/content/
- Ancient EthereumBuilder’s Guide - https://ethereumbuilders.gitbooks.io/guide/content/en/index.html
- Other Ethereum Links: https://souptacular.gitbooks.io/ethereum-tutorials-and-tips-by-hudson/content/giant_ethereum_resource_list.html
- Django Docs - https://docs.djangoproject.com/en/1.9/
文本整理标记工具 - Sphinx¶
- Best Cheat Sheet - https://github.com/ralsina/rst-cheatsheet/blob/master/rst-cheatsheet.rst
- Quick Reference - http://docutils.sourceforge.net/docs/user/rst/quickref.html
- Official Cheat Sheet - http://docutils.sourceforge.net/docs/user/rst/cheatsheet.txt -> http://docutils.sourceforge.net/docs/user/rst/cheatsheet.html
- RST Primer http://sphinx-doc.org/rest.html
- http://sphinx-doc.org/markup/inline.html
编译和发布¶
我们使用 make 命令的 Makefile 来自动生成文档结构。
git clone https://github.com/ethereum/homestead-guide
cd homestead-guide
make html
处理技巧¶
固定的章节换行(每行总是使用80字符长度,除了那些超过80字符的标题以外)
for f in `ls source/*/*.rst`; do cat $f|perl -pe 's/\=+$/================================================================================/' > $f.o; mv $f.o $f; done; done
for f in `ls source/*/*.rst`; do cat $f|perl -pe 's/\*+$/********************************************************************************/' > $f.o; mv $f.o $f; done
for f in `ls source/*/*.rst`; do cat $f|perl -pe 's/\-+$/--------------------------------------------------------------------------------/' > $f.o; mv $f.o $f; done
for f in `ls source/*/*.rst`; do cat $f|perl -pe 's/\++$/++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/' > $f.o; mv $f.o $f; done
for f in `ls source/*/*.rst`; do cat $f|perl -pe 's/\#+$/################################################################################/' > $f.o; mv $f.o $f; done
Referencing Old Documentation¶
old-docs-for-reference folder has all of the Frontier Gitbook and Ethereum Wiki doc. Feel free to copy/paste information from those documents that is still relevant.
Migrate and Convert Old Wiki Content Using Pandoc¶
If you still want to clone the absolute latest Ethereum Wiki and Frontier Guide docs:
git clone git@github.com:ethereum/go-ethereum.wiki.git
git clone git@github.com:ethereum/wiki.wiki.git
mkdir main-wiki.rst
mkdir go-ethereum-wiki.rst
for f in `ls wiki.wiki/*.md`; do pandoc $f -o main-wiki.rst/`basename $f .md`.rst; done
for f in `ls go-ethereum.wiki/*.md`; do pandoc $f -o go-ethereum-wiki.rst/`basename $f .md`.rst; done
改进这份文档¶
请参考 Homestead文档计划 来帮助我们继续改进这份文档。