以太坊智能合约编程之菜鸟教程
⼿把⼿带你⾛上智能合约编程之路
译注:⾸发于ConsenSys开发者博客,原作者为Eva以及ConsenSys的开发团队。如果您想要获取更多及时信息,可以访问⾸页点击左下⾓Newsletter订阅邮件。本⽂的翻译获得了ConsenSys创始⼈Lubin先⽣的授权。
有些⼈说以太坊太难对付,于是我们(译注:指, 下同)写了这篇⽂章来帮助⼤家学习如何利⽤以太坊编写智能合约和应⽤。这⾥所⽤到的⼯具,钱包,应⽤程序以及整个⽣态系统仍处于开发状态,它们将来会更好⽤!
概述,讨论了关键概念,⼏⼤以太坊客户端以及写智能合约⽤到的编程语⾔。
讨论了总体的⼯作流程,以及⽬前流⾏的⼀些DApp框架和⼯具。
主要关于编程,我们将学习如何使⽤Truffle来为智能合约编写测试和构建DApp。
mysqlzip安装教程第⼀部分. 概述
如果你对诸如⽐特币以及其⼯作原理等密码学货币的概念完全陌⽣,我们建议你先看看Andreas Antonopoulos所著的的头⼏章,然后读⼀下。(译注:以太坊⽩⽪书中⽂版请看)
如果你觉得⽩⽪书中的章节太晦涩,也可以直接动⼿来熟悉以太坊。在以太坊上做开发并不要求你理解所有那些“密码经济计算机科
学”(crypto economic computer science),⽽⽩⽪书的⼤部分是关于以太坊想对于⽐特币架构上的改进。
新⼿教程
提供了官⽅的新⼿⼊门教程,以及⼀个合约和众筹合约的教程。合约语⾔Solidity也有。学习智能合约的另⼀份不错的资料(也是我的⼊门资料)是,不过现在可能有些过时了。
这篇⽂章的⽬的是成为上述资料的补充,同时介绍⼀些基本的开发者⼯具,使⼊门以太坊,智能合约以及构建DApps(decentralized apps,分布式应⽤)更加容易。我会试图按照我⾃⼰(依然是新⼿)的理解来解释⼯作流程中的每⼀步是在做什么,我也得到了ConsenSys酷酷的开发者们的许多帮助。
基本概念
了解这些名词是⼀个不错的开始:
公钥加密系统。 Alice有⼀把公钥和⼀把私钥。她可以⽤她的私钥创建数字签名,⽽Bob可以⽤她的公钥来验证这个签名确实是⽤Alice的私钥创建的,也就是说,确实是Alice的签名。当你创建⼀个以太坊或者⽐特币钱包的时候,那长长的5f地址实质上是个公钥,对应的私钥保存某处。类似于Coinbase的在线钱包可以帮你保管私钥,你也可以⾃⼰保管。如果你弄丢了存有资⾦的钱包的私钥,你就等于永远失去了那笔资⾦,因此你最好对私钥做好备份。过来⼈表⽰:通过踩坑学习到这⼀点是⾮常痛苦的...
点对点⽹络。 就像BitTorrent, 以太坊分布式⽹络中的所有节点都地位平等,没有中⼼服务器。(未来会有半中⼼化的混合型服务出现为⽤户和开发者提供⽅便,这我们后⾯会讲到。)
区块链。 区块链就像是⼀个全球唯⼀的帐簿,或者说是数据库,记录了⽹络中所有交易历史。
以太坊虚拟机(EVM)。 它让你能在以太坊上写出更强⼤的程序(⽐特币上也可以写脚本程序)。它有时也⽤来指以太坊区块链,负责执⾏智能合约以及⼀切。
节点。 你可以运⾏节点,通过它读写以太坊区块链,也即使⽤以太坊虚拟机。完全节点需要下载整个区块链。轻节点仍在开发中。
矿⼯。 挖矿,也就是处理区块链上的区块的节点。这个⽹页可以看到当前活跃的⼀部分以太坊矿⼯:。
⼯作量证明。 矿⼯们总是在竞争解决⼀些数学问题。第⼀个解出答案的(算出下⼀个区块)将获得以太币作为奖励。然后所有节点都更新⾃⼰的区块链。所有想要算出下⼀个区块的矿⼯都有与其他节点保持同步,并且维护同⼀个区块链的动⼒,因此整个⽹络总是能达成共识。(注意:以太坊正计划转向没有矿⼯的权益证明系统(POS),不过那不在本⽂讨论范围之内。)
以太币。 缩写ETH。⼀种你可以购买和使⽤的真正的。这⾥是可以交易以太币的其中⼀家交易所的。在写这篇⽂章的时候,1个以太币价值65美分。
Gas. (汽油) 在以太坊上执⾏程序以及保存数据都要消耗⼀定量的以太币,Gas是以太币转换⽽成。这个机制⽤来保证效率。
DApp. 以太坊社区把基于智能合约的应⽤称为去中⼼化的应⽤程序(Decentralized App)。DApp的⽬标是(或者应该是)让你的智能合约有⼀个友好的界⾯,外加⼀些额外的东西,例如IPFS(可以存储和读取数据的去中⼼化⽹络,不是出⾃以太坊团队但有类似的精神)。DApp 可以跑在⼀台能与以太坊节点交互的中⼼化服务器上,也可以跑在任意⼀个以太坊平等节点上。(花⼀分钟思考⼀下:与⼀般的⽹站不
同,DApp不能跑在普通的服务器上。他们需要提交交易到区块链并且从区块链⽽不是中⼼化数据库读取重要数据。相对于典型的⽤户登录系统,⽤户有可能被表⽰成⼀个钱包地址⽽其它⽤户数据保存在
本地。许多事情都会与⽬前的web应⽤有不同架构。)
如果想看看从另⼀个新⼿视⾓怎么理解这些概念,请读。
以太坊客户端,智能合约语⾔
编写和部署智能合约并不要求你运⾏⼀个以太坊节点。下⾯有列出。但如果是为了学习的话,还是应该运⾏⼀个以太坊节点,以便理解其中的基本组件,何况运⾏节点也不难。
运⾏以太坊节点可⽤的客户端
以太坊有许多不同语⾔的客户端实现(即多种与以太坊⽹络交互的⽅法),包括C++, Go, Python, Java, Haskell等等。为什么需要这么多实现?不同的实现能满⾜不同的需求(例如Haskell实现的⽬标是可以被数学验证),能使以太坊更加安全,能丰富整个⽣态系统。
在写作本⽂时,我使⽤的是Go语⾔实现的客户端geth (),其他时候还会使⽤⼀个叫testrpc的⼯具, 它使⽤了Python客户端。后⾯的例⼦会⽤到这些⼯具。
注: 我曾经使⽤过C++的客户端,现在仍然在⽤其中的ethminer组件和geth配合挖矿,因此这些不同的组件是可以⼀起⼯作的。
关于挖矿:挖矿很有趣,有点像精⼼照料你的室内盆栽,同时⼜是⼀种了解整个系统的⽅法。虽然以太币现在的价格可能连电费都补不齐,但以后谁知道呢。⼈们正在创造许多酷酷的DApp, 可能会让以太坊越来越流⾏。
交互式控制台。 客户端运⾏起来后,你就可以同步区块链,建⽴钱包,收发以太币了。使⽤geth的⼀种⽅式是通过(JavaScript console,类似你在chrome浏览器⾥⾯按F12出来的那个,只不过是跑在终端⾥)。此外还可以使⽤类似cURL的命令通过来与客户端交互。本⽂的⽬标是带⼤家过⼀边DApp开发的流程,因此这块就不多说了。但是我们应该记住这些命令⾏⼯具是调试,配置节点,以及使⽤钱包的利器。
在测试⽹络运⾏节点。 如果你在正式⽹络运⾏geth客户端,下载整个区块链与⽹络同步会需要相当时间。(你可以通过⽐较节点⽇志中打印的最后⼀个块号和上列出的最新块来确定是否已经同步。) 另⼀个问题是在正式⽹络上跑智能合约需要实实在在的以太币。在测试⽹络上运⾏节点的话就没有这个问题。此时也不需要同步整个区块链,创建⼀个⾃⼰的私有链就勾了,对于开发来说更省时间。
testrpc. ⽤geth可以创建⼀个测试⽹络,另⼀种更快的创建测试⽹络的⽅法是使⽤testrpc. Testrpc可以在启动时帮你创建⼀堆存有资⾦的测试账户。它的运⾏速度也更快因此更适合开发和测试。你可以从testrpc起步,然后随着合约慢慢成型,转移到geth创建的测试⽹络上 -启动⽅法很简单,只需要指定⼀个networkid:geth --networkid "12345"。这⾥是,下⽂我们还会再讲到它。
接下来我们来谈谈可⽤的编程语⾔,之后就可以开始真正的编程了。
写智能合约⽤的编程语⾔
⽤Solidity就好。 要写智能合约有好⼏种语⾔可选:有点类似Javascript的Solidity, ⽂件扩展名是.sol. 和Python接近的Serpent, ⽂件名以.se结尾。还有类似Lisp的LLL。Serpent曾经流⾏过⼀段时间,但现在最流⾏⽽且最稳定的要算是Solidity了,因此⽤Solidity就好。听说你喜欢Python? ⽤Solidity。
solc编译器。 ⽤Solidity写好智能合约之后,需要⽤solc来编译。它是⼀个来⾃C++客户端实现的组件(⼜⼀次,不同的实现产⽣互补),是安装⽅法。如果你不想安装solc也可以直接使⽤基于浏览器的编译器,例如或者。后⽂有关编程的部分会假设你安装了solc。
注意:以太坊正处于积极的开发中,有时候新的版本之间会有不同步。确认你使⽤的是最新的dev版本,或者稳定版本。如果遇到问题可以去以太坊项⽬对应的Gitter聊天室或者上问问其他⼈在⽤什么版本。
web3.js API. 当Solidity合约编译好并且发送到⽹络上之后,你可以使⽤以太坊的来调⽤它,构建能与之交互的web应⽤。
以上就是在以太坊上编写智能合约和构建与之交互的DApp所需的基本⼯具。
第⼆部分. DApp框架,⼯具以及⼯作流程
DApp开发框架
虽然有上⽂提到的⼯具就可以进⾏开发了,但是使⽤社区⼤神们创造的框架会让开发更容易。
Truffle and Embark. 是把我领进了门。在Truffle出现之前的那个夏天,我⽬睹了⼀帮有天分的学⽣是如何不眠不休的参加⼀个hackathon(编程马拉松)活动的,虽然,但我还是吓到了。然后Truffle出现了,帮你处理掉⼤量⽆关紧要的⼩事情,让你可以迅速进⼊写代码-编译-部署-测试-打包DApp这个流程。另外⼀个相似的DApp构建与测试框架是。我只⽤过Truffle, 但是两个阵营都拥有不少DApp ⼤神。
Meteor. 许多DApp开发者使⽤的另⼀套开发栈由web3.js和组成,Meteor是⼀套通⽤webapp开发框架(项⽬提供了⼀个很棒的⼊门实例,⽽正在构建⼤量Meteor与web3.js和DApp集成的模板)。我下载并运⾏过⼀些不错的DApp是以这种⽅式构造的。在11⽉9⽇⾄13⽇的上将有⼀些有趣的讨论,是关于使⽤这些⼯具构建DApp以及相关最佳实践的(会议将会在上直播)。
APIs. 打算提供⼀套RESTful API给DApp使⽤以免去开发者运⾏本地节点的⿇烦,这个中⼼化服务是基于以太坊Haskell实现的。这与DApp的去中⼼化模型背道⽽驰,但是在本地⽆法运⾏以太坊节点的场合⾮常有⽤,⽐如在你希望只有浏览器或者使⽤移动设备的⽤户也能使⽤你的DApp的时候。BlockApps提供了⼀个命令⾏⼯具,注册⼀个开发者帐号之后就可以使⽤。
许多⼈担⼼需要运⾏以太坊节点才能使⽤DApp的话会把⽤户吓跑,其实包括BlockApps在内的许多⼯具都能解决这个问题。允许你在浏览器⾥⾯使⽤以太坊的功能⽽⽆需节点,以太坊官⽅提供的AlethZero或者AlethOne是正在开发中有易⽤界⾯的客户端,ConsenSys正在打造⼀个轻钱包,这些⼯具都会让DApp的使⽤变得更容易。和⽔平分⽚(sharding)也在计划和开发之中。这是⼀个能进化出混合架构的P2P ⽣态系统。
智能合约集成开发环境 (IDE)
IDE. 以太坊官⽅出品了⽤来编写智能合约的,我还没⽤过但会尽快⼀试。
基于浏览器的IDE. 和都可以让你快速开始在浏览器中编写智能合约。你甚⾄可以让这些⼯具使⽤你的本地节点,只要让本地节点开⼀个端⼝(注意安全!这些⼯具站点必须可信,⽽且千万不要把你的全部⾝家放在这样⼀个本地节点⾥⾯!上有如何使⽤geth做到这⼀点的指引)。在你的智能合约调试通过之后,可以⽤开发框架来给它添加⽤户界⾯和打包成DApp,这正是Truffle的⼯作,后⾯的编程章节会有详细讲解。
正在开发另⼀个强⼤的企业级浏览器IDE。他们的IDE将⽀持沙盒测试⽹络,⾃动⽣成⽤于测试的⽤户界⾯(取代后⽂将展⽰的⼿动编写测试),以及⼀个测试交易浏览器。当你的合约准备正式上线之前,使⽤他们的测试⽹络会是确保你的智能合约在⼀个接近真实的环境⼯作正常的好⽅法。他们也为
正式⽹络提供了⼀个交易浏览器,上⾯可以看到每⼀笔交易的细节。在本⽂写作时Ether.Camp的IDE还只能通过邀请注册,预计很快会正式发布。
合约和Dapp⽰例。 在Github上搜索DApp仓库和.sol⽂件可以看到进⾏中的有趣东西。这⾥有⼀个DApp⼤列表:,不过其中⼀些项⽬已经过时。上有⼀些Solidity和Serpent写的合约⽰例,但是不清楚这些例⼦有没有经过测试或者正确性验证。11⽉12⽇的将会有⼀整天的DApp主题演讲。
部署智能合约的流程
流程如下:
1. 启动⼀个以太坊节点 (例如geth或者testrpc)。
python入门教程 下载2. 使⽤solc*编译*智能合约。 => 获得⼆进制代码。
3. 将编译好的合约部署到⽹络。(这⼀步会消耗以太币,还需要使⽤你的节点的默认地址或者指定地址来给合约签名。) => 获得合约
的区块链地址和ABI(合约接⼝的JSON表⽰,包括变量,事件和可以调⽤的⽅法)。(译注:作者在这⾥把ABI与合约接⼝弄混了。
区划代码是什么ABI是合约接⼝的⼆进制表⽰。)
4. ⽤web3.js提供的JavaScript API来调⽤合约。(根据调⽤的类型有可能会消耗以太币。)
下图详细描绘了这个流程:
你的DApp可以给⽤户提供⼀个界⾯先部署所需合约再使⽤之(如图1到4步),也可以假设合约已经部署了(常见⽅法),直接从使⽤合约(如图第6步)的界⾯开始。
validform第三部分. 编程
在Truffle中进⾏测试
⽤来做智能合约的测试驱动开发(TDD)⾮常棒,我强烈推荐你在学习中使⽤它。它也是学习使⽤JavaScript Promise的⼀个好途径,例如deferred和异步调⽤。Promise机制有点像是说“做这件事,如果结果是这样,做甲,如果结果是那样,做⼄... 与此同时不要在那⼉⼲等着结果返回,⾏不?”。Truffle使⽤了包装web3.js的⼀个JS Promise框架(因此它为为你安装web3.js)。(译注:Promise是流⾏于JavaScript社区中的⼀种异步调⽤模式。它很好的封装了异步调⽤,使其能够灵活组合,⽽不会陷⼊callback hell.)
Transaction times. Promise对于DApp⾮常有⽤,因为交易写⼊以太坊区块链需要⼤约12-15秒的时间。即使在测试⽹络上看起来没有那么慢,在正式⽹络上却可能会要更长的时间(例如你的交易可能⽤光了Gas,或者被写⼊了⼀个孤⼉块)。
下⾯让我们给⼀个简单的智能合约写测试⽤例吧。
使⽤Truffle
⾸先确保你 1.安装好了以及 2.。(testrpc需要和。如果你是Python新⼿,你可能需要⽤来安装,这可以将Python程序库安装在⼀个独⽴的环境中。)
接下来安装 3.(你可以使⽤来安装:npm install -g truffle,-g开关可能会需要sudo)。安装好之后,在命令⾏中输⼊truffle list来验证安装成功。然后创建⼀个新的项⽬⽬录(我把它命名为'conference'),进⼊这个⽬录,运⾏truffle init。该命令会建⽴如下的⽬录结构:
现在让我们在另⼀个终端⾥通过执⾏testrpc来启动⼀个节点(你也可以⽤geth):
回到之前的终端中,输⼊truffle deploy。这条命令会部署之前truffle init产⽣的模板合约到⽹络上。任何你可能遇到的错误信息都会在testrpc 的终端或者执⾏truffle的终端中输出。
在开发过程中你随时可以使⽤truffle compile命令来确认你的合约可以正常编译(或者使⽤solc YourContract.sol),truffle deploy来编译和部署合约,最后是truffle test来运⾏智能合约的测试⽤例。
第⼀个合约
下⾯是⼀个针对会议的智能合约,通过它参会者可以买票,组织者可以设置参会⼈数上限,以及退款策略。本⽂涉及的所有代码都可以在这个到。
contract Conference {
address public organizer;
mapping (address => uint) public registrantsPaid;
uint public numRegistrants;
uint public quota;
event Deposit(address _from, uint _amount); // so you can log these events
event Refund(address _to, uint _amount);
function Conference() { // Constructor
organizer = msg.sender;
quota = 500;
numRegistrants = 0;
}
function buyTicket() public returns (bool success) {
if (numRegistrants >= quota) { return false; }
registrantsPaid[msg.sender] = msg.value;
numRegistrants++;
Deposit(msg.sender, msg.value);
return true;
}
function changeQuota(uint newquota) public {
if (msg.sender != organizer) { return; }
quota = newquota;
}
function refundTicket(address recipient, uint amount) public {
if (msg.sender != organizer) { return; }
if (registrantsPaid[recipient] == amount) {
address myAddress = this;
if (myAddress.balance >= amount) {
recipient.send(amount);
registrantsPaid[recipient] = 0;
numRegistrants--;
Refund(recipient, amount);
}
}
}
php正则验证function destroy() { // so funds not locked in contract forever
if (msg.sender == organizer) {
suicide(organizer); // send funds to organizer
}
js正则表达式去掉br}
}
接下来让我们部署这个合约。(注意:本⽂写作时我使⽤的是Mac OS X 10.10.5, solc 0.1.3+ (通过brew安装),Truffle v0.2.3, testrpc v0.1.18 (使⽤venv))
部署合约
(译注:图中步骤翻译如下:)
使⽤truffle部署智能合约的步骤:
1. truffle init (在新⽬录中) => 创建truffle项⽬⽬录结构
2. 编写合约代码,保存到contracts/YourContractName.sol⽂件。
3. 把合约名字加到config/app.json的'contracts'部分。
4. 启动以太坊节点(例如在另⼀个终端⾥⾯运⾏testrpc)。
5. truffle deploy(在truffle项⽬⽬录中)
添加⼀个智能合约。 在truffle init执⾏后或是⼀个现有的项⽬⽬录中,复制粘帖上⾯的会议合约到contracts/Conference.sol⽂件中。然后打开config/app.json⽂件,把'Conference'加⼊'deploy'数组中。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论