发行代币——部署代币智能合约

现在越来越多的公司发行了自己的以太坊代币,不管他们的目的是推进公司建设也好,还是割韭菜也好,其实跟我们开发者的关系并不大,我们应该关注的是其背后的区块链技术。上一次我们讲了如何编写代币的智能合约,这次我们来看下怎么发布智能合约。

部署合约

当我们把智能合约编译完成后,我们就可以将其发布到区块链上了,这里我们介绍如何将智能合约发布到本地环境和 Rinkeby 测试环境。

首先我们需要在migrations文件夹中新增一个2_deploy_contracts.js文件,文件内容如下,这样部署程序才会部署我们的合约:

1
2
3
4
5
const Mytoken = artifacts.require('./Mytoken.sol');

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

部署本地环境

我们可以使用之前介绍的Ganache来创建本地环境,打开Ganache客户端我们可以看到本地环境已经启动,同时默认创建了 10 个测试账号。

然后打开编辑器开始修改工程目录下的truffle.js文件,新增开发环境网络。

1
2
3
4
5
6
7
8
9
10
module.exports = {
  networks: {
    // 本地环境配置
    development: {
      host: '127.0.0.1',
      port: 7545,
      network_id: '*',
    },
  },
}

最后执行发布命令,从输出信息中我们可以看到,我们创建了 2 个智能合约,第一个是项目默认的Migrations,第二个就是我们的代币合约。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ truffle migrate
Using network 'development'.

Running migration: 1_initial_migration.js
  Deploying Migrations...
  ... 0x77229d85d7a60ba492254db506561ab1ce56a50198c616ddc9b96555e10b796c
  Migrations: 0xf6a0e4e40f0ae34dba890ebacb775371fb965658  // 这是项目默认的智能合约
Saving successful migration to network...
  ... 0xe0fbc8fa8f42e7a920184c597e5ecf14a1dca8ab7b246a68153f3117cc24aced
Saving artifacts...
Running migration: 2_deploy_contracts.js
  Deploying ZzmCoin...
  ... 0x2aab385e1ea9ab9dd65be93b3df99118a521822b18c48d76e3f6ae7933de9e4d
  Mytoken: 0x593e548762ae1ca31bcdfa1be54f7e93d8265b9c // 这是我们的代币合约
Saving successful migration to network...
  ... 0xc1a702e5d6582aaa6cb57903849a007024c887a89d67a982afa13f09ede7e736
Saving artifacts...

因为部署本地环境是用第一个账号来发布合约,并且创建合约是需要花费账号金额的, 所以发布完成后,我们再次查看Ganache客户端,可以看到我们的第一个账号的账户金额发生了变化,并且产生了 4 个交易,这样就表示我们的代币已经发布成功了。

部署 Rinkeby 环境

下面我们将代币发布到与生产环境比较相似的测试环境 Rinkeby,这里有两种方式可以来发布代币。

第一种方式:使用 Geth

我们先用Geth在本地启动一个 Rinkeby 节点,启动时我们指定节点的datadir目录,同时指定我们需要的几个rpcapi,并将日志写入到rinkeby.log文件。

1
geth --datadir "rinkeby" --rinkeby --rpcapi eth,web3,personal,db,net --rpc --rpcaddr=0.0.0.0 --rpccorsdomain "*" console 2>>rinkeby.log

这种方式需要将 Rinkeby 的全部数据先同步下来,可以在Geth 的 console 页面输入eth.syncing,如果返回值是false则表示已经同步完成了,如果是返回一个 json 对象,则表示还在同步。

PS:同步 Rinkeby 全节点数据大概是 16G 左右(截止 2018 年 7 月)

1
2
3
4
5
6
7
8
9
10
> eth.syncing
{
  currentBlock: 2678044,
  highestBlock: 2701227,
  knownStates: 10200179,
  pulledStates: 10200179,
  startingBlock: 2677747
}
> eth.syncing
false

接着我们编辑truffle.js文件中的网络配置信息:

1
2
3
4
5
6
7
8
9
10
module.exports = {
  networks: {
    rinkeby: {
      host: '127.0.0.1',
      port: 8545,
      from: '0xd2e7c99558878629bb841678a022508b8ff585ff', // 这里指定由哪个账号来创建智能合约
      network_id: 4,
    },
  },
}

注意from属性是指通过哪个账号来创建合约,但这个账号必须在 Rinkeby 网络中有一定数量的 ETH,否则创建合约将失败,Rinkeby 网络获取 ETH 方法可以参照如何在 Rinkeby 网络赚取以太币及代币

在发布合约之前,我们还需要将刚才提到的账号解锁,在Geth 的 console 页面输入解锁命令和账号密码,看到返回结果为true则表示解锁成功。

1
2
3
4
> personal.unlockAccount('0xd2e7c99558878629bb841678a022508b8ff585ff')
Unlock account 0xd2e7c99558878629bb841678a022508b8ff585ff
Passphrase:
true

最后同样是执行发布命令,但需要在后面加上参数:truffle migrate --network rinkeby,执行成功的输出信息和本地环境是一样的。

第二种方式:使用 HDwallet

使用Geth方式比较麻烦的一点就是需要同步全节点的数据,下面介绍通过infura网络直接部署到 Rinkeby 测试环境的方法。

首先我们需要先安装truffle-hdwallet-provider

1
yarn add truffle-hdwallet-provider

然后再修改truffle.js的配置信息,将 Rinkeby 网络配置改成如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const HDWalletProvider = require('truffle-hdwallet-provider');
const mnemonic =
  'trumpet human tree genius reject purity secret off regret join orbit tent';

module.exports = {
  networks: {
    rinkeby: {
      provider: function() {
        return new HDWalletProvider(mnemonic, 'https://rinkeby.infura.io/');
      },
      network_id: 4,
    },
  },
};

注意,这里通过助记词创建的账号是用来发布智能合约的,所以账号里面也需要有一定数量的 ETH。

最后执行发布命令truffle migrate --network rinkeby就可以了。

合约源码开源

代币发布完成之后,我们可以在以太坊浏览器中查看代币的详细信息,如果我们是发布到 Rinkeby 网络就可以查看rinkeby.etherscan.io这个网址,然后在上面输入合约地址就可以进行代币信息的查询了。

在以太坊上很多运作良好的代币都会将代币合约源码进行开源,以证明代币的公正公开公平,但我们刚发布的代币并没有源码信息,所以我们需要手动上传代币的源码。

以 Rinkeby 网络为例,进入rinkeby.etherscan.io后在右上角菜单可以看到一个Verify Contract选项。

点击选项后进入智能合约源码上传页面,在这里要填写合约地址、合约名称,编译器版本等信息,还有上传合约的源码。

注意事项:

  • Optimization选项要选择No,选择Yes会报错,具体原因未知
  • 编译器版本可以查看编译后的 json 文件,里面有compiler属性
  • 因为我们的合约是继承自OpenzeppelinStandardToken类,所以要将继承的基类源码一起上传才能验证通过,比如我们的代码继承了StandardToken这个基类,就需要将它的代码一起上传,然后StandardToken又继承了ERC20BaseToken这 2 个类,则需要再将这 2 个类的源码一起上传,这些基类的源码可以在Openzeppelin的 github 仓库中找到。

最后点击Verify And Publish按钮就可以上传智能合约的源码了,上传成功后我们可以在Code栏查看上传后的源码。

总结

我们主要介绍了代币的智能合约编写、发布以及源码上传等过程,这里要感谢开源社区的框架和工具,让我们编写智能合约变得越来越简单,希望区块链以后可以吸引到更多开发者来参与基础设施的建设。

赞赏

如果文章对您有所帮助,可以捐赠我喝杯咖啡😌,捐赠方式:

BTC 地址: 3LYgSyf7ddMALwGWPQr3PY4wzjsTDdg1oV
ETH 地址: 0x0C9b27c89A61aadb0aEC24CA8949910Cbf77Aa73
qrcode

Comments