OpenZeppelin集成Truffle编写健壮安全的合约

原文:http://truffleframework.com/tutorials/robust-smart-contracts-with-openzeppelin

因为智能合约往往涉及金钱,保证Soldity代码没有错误,以及足够的安全是非常根本的。Zeppelin Solutions,一个智能合约审查服务商,已经意识到相关的需求。建立在他们的合约审查经验之上,他们把一些最佳实践整理到了OpenZeppelin

我们可以使用和扩展这些合约,以在更少的时间内创建更安全的DAPP。OpenZeppelin为各种各样重要的功能提供了广泛的智能合约(在这里查看全部支持合约)。而今天,我们来看看其中的代币合约。具体来说,我们打算扩展其中提供了StandardToken.sol来创建一个我们自己的支持ERC-20标准的代币。

环境

这个教程需要你对Truffle、Ethereum和Solidity已经有一些了解。你可以先从宠物商店这个教程开始。

查看更多相关的信息

概述

在这个教程里你将学到下述的知识:

  • 拆箱即用的前端
  • 使用OpenZeppelin的StandardToken来创建自己的TutorialToken
  • 编译和部署智能合约到testrpc
  • 与自己新创建的前端交互

拆箱即用的前端

开发的主要精力应该放在智能合约上。为达到这个目的,Truffle以truffle box的方式提供了拆箱即用的前端。打开命令行,进入到某个工作空间。在这里我们选择工作空间oz-workspace

$ cd oz-workspace
$ truffle unbox tutorialtoken

备注: Truffle要升级到最新版,可以用命令sudo npm i -g truffle升级。

当前文章的Truffle版本:

$ truffle version
Truffle v3.4.7 (core: 3.4.7)
Solidity v0.4.13 (solc-js)

成功安装后的目录如下:

下一步,我们要集成OpenZeppelin。最新版本的OpenZeppelin可以通过npm来安装使用。

npm install zeppelin-solidity

集成成功后,在node_moduleszeppelin-solidity的依赖,如下图所示:

2. 创建TutorialToken智能合约

使用已经搭建好的前端环境,现在让我们来创建TutorialToken合约。在contracts目录下,创建名为TutorialToken.sol的智能合约,内容如下:

pragma solidity ^0.4.4;
import 'zeppelin-solidity/contracts/token/StandardToken.sol';

contract TutorialToken is StandardToken {

}

在上面的代码中,importStandardToken.sol,并声明TutorialToken继承自StandardToken。这样就继承了StandardToken合约中所有变量和函数。继承的合约可以被覆盖,只要在子类重定义对应的变量与函数就行了。

接下来,设置代币的参数,需要定义自己的namesymboldecimalsINITIAL_SUPPLY

string public name = 'TutorialToken';
string public symbol = 'TT';
uint public decimals = 2;
uint public INITIAL_SUPPLY = 12000;

namesymbol变量,定义了代币的一个独一无二的标识。decimals变量定义了代币可被细分的程度。在上面的例子里decimals我们的取值为2,效果类似于美元和美分。最后,INITIAL_SUPPLY变量定义了在合约部署时,代币将创建的数量。在这个例子中,我们选择的是12000。

最后在构造函数中我们简单设置totalSupply来等于INITIAL_SUPPLY,同时把所有的币赋值给部署者的帐户。

function TutorialToken() {
  totalSupply = INITIAL_SUPPLY;
  balances[msg.sender] = INITIAL_SUPPLY;
}

这样,使用小于15行手写的Solidity代码,我们创建了一个自己的ERC-20的代币。下一步,我们将部署代币,并与代币进行交互。

3. 编译与部署

/migrations目录下,用下述内容创建文件2_deploy_contracts.js

var TutorialToken = artifacts.require("./TutorialToken.sol");

module.exports = function(deployer) {
  deployer.deploy(TutorialToken);
};

TutorialToken合约内的import语句会由编译器进行自动处理,它会自动导入StandardToken内的相关引用包。

现在,我们可以编译与部署了:

## 启动testrpc
$ testrpc
## 编译合约
$ truffle compile
## 部署合约
$ truffle migrate

migrate时默认选择的网络是development
你当前的Truffle默认配置truffle.js应该如下(即默认部署到testrpc):

module.exports = {
  networks: {
    development: {
      host: "localhost",
      port: 8545,
      network_id: "*" // Match any network id
    }
  }
};

4. 与TutorialToken交互

对于这部分的教程,我们推荐使用MetaMask的Chrome插件。它能轻松的在不同的帐户间快速切换,对于测试我们新创建代币的转发非常方便。这里有设置metamask与testrpc的教程

另外,我们已经为你安装了lite-server,所以可以在oz-workspace目录,跑下面的命令,跑起来一个简单的页面:

npm run dev

运行后会弹出一个界面如下:

这个简单的dapp显示了当前的余额。

可以尝试转移一些代币到其它的帐户,下面这里,转移了2000TT到第二个帐户。

Truffle + OpenZeeelin 超级开发体验

Truflle很激动的看到,类似Zeppelin Solutions这样解决方案对于合约标准化,以及提升安全性上的贡献。结合OpenZeppelin的合约和Truffle的工具集,可以非常容易的创建工业级的分布式应用。

enjoy。

update20170902:好多人说,看不到余额?显示是TT。

确保你已经安装了MetaMask,这个浏览器插件,帮你注入web3.js到前端中。

官网:https://metamask.io ,google插件应该在这里:https://chrome.google.com/webstore/detail/nkbihfbeogaeaoehlefnkodbefgpgknn

详细集成TestRpc与MetaMask教程:http://truffleframework.com/tutorials/pet-shop#using-our-dapp-in-chrome

一个小插曲,使用MetaMask,一直连不上我的TestRpc。于是我使用 http://localhost:8545 放到浏览器中,一直显示400 bad request。这个尝试误导了我,其实MetaMask是通过配置的IP与端口,以RPC方式访问,直接http访问是不行。但我的MetaMask就是不能切换到TestRPC,结果花了两个小时,发现是我的电脑开了全局代理。浏览器,走了代理,所以不行,/笑哭。

1. 首先部署

部署成功后,你能看到successful字样

2. 导入帐户

由于Truffle默认是使用TestRpc的第一个帐户来进行发布的,所以代币也是初始分配给了第一个帐号。所以我们要回到TestRpc,找到第一个帐户并导入到MetaMask。

这是我本地的TestRpc的启动输出结果。由于是可以通过私匙推出公匙,所以MetaMask导入时,使用私匙导入就可以,选择下面的Import Account

输入第一个私匙,其实就是创建合约的那个帐户。切换到这个帐户后,你就能看到你自己代币的余额了。

成功后,可以看到下面的界面了。

处于某些特定的环境下,可以看到评论框,欢迎留言交流^_^。