erc20 ethereum

実用開発環境で作るイーサリアムトークン発行

現場で製品用のスマートコントラクトを開発するのに使える実践的な開発環境でイーサリアムトークンを発行するチュートリアルです.
Feb. 2, 2020, 1:51 p.m.

目次

開発環境の構成

今回作成する開発環境は以下の構成です.

  • ホストマシン(Mac or Windows)- コーディングや動作確認

    • テキストエディタ – SolidityやJavascriptなどのコーディング.

    • ブラウザ – EtherscanやMetaMaskへのアクセス、Dappsの動作確認など.

    • MetaMask – INFURAへアカウントを提供.コントラクト公開や呼び出しの費用支払。

  • ゲストマシン(Linux) – Ethereum開発ツールの実行

    • Truffle – 開発ツールセット.

    • Zeppelin Solidity – Solidityライブラリ.

  • クラウド

    • INFURA – イーサリアムネットワークへの入り口.

ホストマシンのテキストエディタでコーディング可能なように、ゲストマシンの間でファイル共有をします.

また、ゲストマシン上で使用するポートはホストマシンの同ポートにフォワード(マッピング)します.

例えばTruffle開発サーバーの9545などです.

MetaMaskのセットアップ

MetaMaskとは何か

MetaMask公式ページ

イーサリアムでイーサやトークンの送金などを行うためのウォレットです.

Ethereum上のアプリ(=Dapps)は通常Google Chromeなどのブラウザからアクセスします.

そのDappsではEthereumのアカウントと送金処理が必要になります.

それを裏で行ってくれるのがMetaMaskです.

RemixでもMetaMaskを使用します.

MetaMaskのインストール方法

公式ページにアクセスして下さい.

MetaMask公式ページ

Chrome、FirefoxまたはOpera用があります.

ここではChromeを例に説明します.

「GET CHROME EXTENSION」をクリック.

Chrome用のMetaMask拡張を入手

「ADD TO CHROME」をクリック.

「Add extension」をクリック.

Chromeの右上にキツネマークが追加されます.

キツネマークをクリック.

MetaMaskがまだ開発途中のベータ版であることが表示されます.

「Accept」をクリック.

MetaMaskの利用規約が表示されます.

一番下までスクロールダウンして下さい.

「Accept」が有効になります.

「Accept」をクリック.

パスワードを2箇所に入力して「CREATE」をクリック.

12単語からなる英文が表示されます.

ニーモニックといい、ウォレットの鍵を開けるのに必要な大切なものです.

MetaMaskを再インストールする時にも入力するとウォレットを復元できます.

「SAVE SEED FILE AS FILE」をクリックしてダウンロード.

誰にも見せないように大切に保管して下さい.

誰かに知られることはEtherをあげてしまうことと同じです.

後ほど使用するので文字列を保存しておいて下さい.

「I’VE COPIED IT SOMEWHERE ELSE」をクリック.

インストール作業は以上で完了です.

ネットワークの切り替え

イーサリアムには通貨やトークンが売買されているMainnet以外にも多くのネットワークが存在します.

ここではRopstenという開発テスト用ネットワークに切り替えてみます.

現在のネットワーク名の右側にある「▼」をクリック.

ネットワーク一覧が表示されます.

「Ropsten Test Network」をクリック.

これで切り替えは完了です.

開発用通貨の入手

MainnetのEtherは取引所などで本当のお金と引き換えに買う必要があります.

一方で開発テスト用Etherは無料で配られています.

ここではRopsten用のEtherをもらってみます.

「BUY」をクリック.

「ROPSTEN TEST FAUCET」をクリック.

FAUCETとは水道の蛇口のことですね.

「request 1 ether from faucet」をクリック.

画面下にトランザクションが追加されたらOKです.

開発テスト用Etherの受取りはこれで以上です.

ゲストマシンの用意

Linux環境を用意します.

Ethereum開発ツール(に限らず開発ツール全般ですが)はLinux向け第一に作られています.

VagrantやVirtual Boxの詳細は以下のページを参考にしてください.

Ethereum開発を快適にする仮想マシンの作成

Virtual Boxのインストール

ダウンロードページ

自身のOS(MacかWindows)に合ったものをダウンロード・インストールしてください.

Vagrantのインストール

ダウンロードページ

自身のOS(MacかWindows)に合ったものをダウンロード・インストールしてください.

仮想マシンとの接続用ディレクトリを作成

Macの場合はターミナルを、Windowsの場合はコマンドプロンプトを起動して下さい.

1
mkdir ethereum_dev

仮想マシンの初期化

接続用ディレクトリに移動して、初期化します.

1
2
cd ethereum_dev
vagrant init

Vagrantfileという設定ファイルが生成されます.

仮想マシンの設定

お好きなエディタでVagrantfileを開いて、内容を全て消してから以下の内容を書き込み保存して下さい.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
  config.vm.box = "bento/ubuntu-17.10"
  config.vm.box_version = "201802.02.0"

  config.vm.network "forwarded_port", guest: 9545, host: 9545 # truffle develop

  config.vm.provider "virtualbox" do |vb|
    vb.gui = false
    vb.customize ["modifyvm", :id, "--memory", "2048", "--cpus", "2", "--ioapic", "on"]
  end
end

それぞれの簡単な説明をします.自分にとってカスタマイズが必要な場合はカスタマイズして下さい。

1
2
  config.vm.box = "bento/ubuntu-17.10"
  config.vm.box_version = "201802.02.0"

仮想マシンのバージョンを設定します.

クラウドからダウンロードするので、いつでも同じバージョンをインストールするためです.

1
    config.vm.network "forwarded_port", guest: 9545, host: 9545

後ほど使用するTruffle開発サーバー用に9545ポートをフォワードする設定です.

※今後追加でポートが必要になった場合、下の行に追記するとポートを追加出来ます.

1
2
3
4
  config.vm.provider "virtualbox" do |vb|
    vb.gui = false
    vb.customize ["modifyvm", :id, "--memory", "2048", "--cpus", "2", "--ioapic", "on"]
  end

パフォーマンスを向上させる設定です.

自身の環境に合わせて削除しても大丈夫です.

CUIで操作する場合GUIは不要なので、vb.gui = falseで無効化しています(GUIが必要な場合はtrueにします).

vb.customizeは使用メモリ・CPUを変更する設定です.

仮想マシンの起動

初回起動時は仮想マシンのダウンロードを挟むので、数分かかることがあります.

1
vagrant up

仮想マシンへのログイン

仮想マシンへログインするとフォルダやコマンドなどすべて仮想マシンのものに置き換わります.ターミナルやコマンドプロンプトの見た目はMacやWindowsですが、中身は完全にUbuntuとなっています。

1
vagrant ssh

INFURAへの登録方法

INFURA登録ページ

上記へアクセスして

  • First(名前)
  • Last(名字)
  • What is your email address?(メールアドレス)
  • Terms of Service(利用規約)

を記入し、「I’m not a robot」にチェック.

重要なメールが届くので、必ず受信できるメールアドレスを入力しましょう.

Mailing Listはチェックしてもしなくても構いません.

「Submit」をクリック.

INFURAへの接続情報の確認

infura@infura.ioから先ほど登録したメールアドレスへ以下のようなメールが届きます.

Main Ethereum Network

本物のイーサリアムネットワークのノードへ接続するためのURLです.

Test Ethereum Network (Ropsten)

世界中で広く使われている開発テスト用ネットワークのURLです.

これらのURLがINFURAに接続するために必要になります.

保存しておいて下さい.

Truffleのセットアップ

Truffleとは

Truffle(トリュフ)

Githubレポジトリ

公式ドキュメント

TruffleはEthereum開発を便利にしてくれるツールセットです.

以下のツールなどがセットになっています.

  • Ethereumで使用するSolidity言語のコンパイラ
  • デプロイツール
  • テストツール
  • デバッガ
  • ローカルテスト用ネットワーク

Node.jsとnpmのインストール

Truffleを動かすにはNode.jsというツールを使用します.

Node.jsとは

Javascriptの実行環境です.

参考: https://nodejs.org/ja/

インストールにはnpmというパッケージマネージャを使用します.

npmとは

Javascriptのパッケージマネージャです.

Ethereum開発ツールの多くがnpmで配布されています.

参考: https://www.npmjs.com/

Ubuntuにログインして下さい.

Vagrant経由でログインする場合は以下を実行.

1
vagrant ssh

まずはUbuntu内のインストール可能なツールを最新化.

1
sudo apt-get update

Node.jsとnpmをインストール.

バージョン8系をインストールします.

1
2
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs

インストールを確認しましょう.

1
2
node -v
npm -v

それぞれのバージョンが表示されたらOKです.

Truffleのインストール

npmではプロジェクト単位でパッケージを管理します.

ここではhello_ethereumというプロジェクトを作成しましょう.

重要: /vagrantというフォルダがホスト(Mac, Windows)側とリアルタイム同期されているので、ホスト側から編集できます.

1
2
3
4
cd /vagrant
mkdir hello_ethereum
cd hello_ethereum
npm init

以下のような質問が続きます.

すべてEnterでデフォルト設定で問題ありません.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
package name: (hello_ethereum)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to /home/vagrant/hello_ethereum/package.json:

Truffleをインストールします.

1
npm install truffle@4.1.7

Tip

npmでインストールする時には必ず@でバージョンを指定しましょう.

デフォルトで最新のバージョンがインストールされてしまうので、意図せずバージョンが上がる危険があるためです.

Ethereum周辺ツールは変化が速いので破壊的な変更が入る可能性があります.

インストールが終わったらtruffleの作業用ディレクトリを作り初期化しましょう.

npmはデフォルトではパッケージをプロジェクト内にインストールします.

実行ファイルはnode_modules/.binディレクトリ内にあります.

sudo npm install -g truffle でインストールすることでグローバル空間にインストールすることも可能です.

1
2
3
mkdir truffle
cd truffle
../node_modules/.bin/truffle init

truffle.js、contracts、migrations、testの基本的な構造が作られます.

  • truffle.js – truffleの設定ファイルです.ネットワーク設定など。
  • contracts – コントラクトを格納するディレクトリです.
  • migrations – truffle migrate で実行されるデプロイスクリプトを格納します.
  • test – truffle testで実行されるテストを格納します.

Truffleのコンソールを立ち上げてみましょう.

1
../node_modules/.bin/truffle develop

以下のようなコメントが表示されたら成功です.

1
2
3
4
5
Truffle Develop started at http://127.0.0.1:9545/
...

...
truffle(develop)>

Truffleのインストールはこれで以上です.

TruffleとINFURAの接続設定

truffle-hdwallet-providerをインストール

Truffleはインストール済みでtruffle developが実行できると想定しています.

TruffleでINFURAに接続するためにtruffle-hdwallet-providerというライブラリを使用します.

truffleの作業用ディレクトリの中でインストールしましょう.

C++のコンパイルのためにg++も必要です.

1
2
3
sudo apt-get install -y g++

npm install truffle-hdwallet-provider@0.0.5

※痛い目に合わないように、バージョンは明示的に指定しましょう.

Truffleの設定

truffle.jsにINFURAへの接続するように設定します.

truffleディレクトリの中にtruffle.jsという設定があるので開いて下さい.

もともと書かれている内容を削除して、以下の内容を保存して下さい.

重要: フォルダが同期されているのでホストマシンのエディタで編集可能です.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
var HDWalletProvider = require("truffle-hdwallet-provider");
var infura_key = "XXXXXXXXXXXXXXXXXX";
var mnemonic = "YYYYYYYYYYYYYYYYYYYYYY";
module.exports = {
  networks: {
    ropsten: {
      provider: new HDWalletProvider(mnemonic, "https://ropsten.infura.io/" + infura_key),
      network_id: "*",
      gas: 4000000
    },
    mainnet: {
      provider: new HDWalletProvider(mnemonic, "https://mainnet.infura.io/" + infura_key),
      network_id: "*",
      gas: 4000000
    }
  }
};

重要: 以下2つの変数は各自のもので設定して下さい.

  • infura_key – INFURAからメールで届いたキー(URL末尾)
  • mnemonic – MetaMaskでウォレット作成時に保存した12語の英文

Ropstenネットワークに接続テスト

Ropstenネットワークに接続してみましょう.

以下のコマンドを実行して下さい.

1
../node_modules/.bin/truffle console --network ropsten

以下のような表示になります.

1
truffle(ropsten)>

Ctrl+Cを2回打ちtruffle(ropsten)を終了してください.

TruffleとINFURAを使ったEthereum開発環境構築は以上です.

Zeppelin Solidityのインストール

Zeppelin Solidityは、Solidityでコントラクトを書くためのライブラリです.

多くのICOやDappsでも使用されています.

ライブラリとして使う用にも、勉強用のコードリーディングでも必ずお世話になるはずです.

hello_ethereumディレクトリ以下で、次のコマンドを実行.

1
npm install openzeppelin-solidity

これでインストールはすべて完了です.

トークンの実装

先ほどRemixで実装した内容と同じトークンを実装します.

内容を少し詳しく説明します.

このトークンはERC20という規格に基づいたトークンで、

  • アカウントごとの残高を記録
  • アカウント間での送金

が可能となっているトークンです.

今回は10000.000000000000000000枚発行することとします.

※この小数点以下の桁数はETHに合わせてあります.最もポピュラー。

発行と同時にオーナー(スマートコントラクトの公開者)に全額振込みます.

実装していきます.

truffle/contractsディレクトリに移動して下さい.

ShunCoin.solというファイルを作成し、以下の内容を書き込んで下さい.

先ほどとの違いはimportしているライブラリがgithubからローカルになっている点のみです.

先ほどと同様にファイル名、コントラクト名、トークン名、通貨単位は自分のものに変更して下さい.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
pragma solidity ^0.4.24;

import "../../node_modules/openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";


contract ShunCoin is ERC20 {
    // トークン名
    string public name = "ShunCoin";

    // 通貨単位
    string public symbol = "SHN";

    // 小数点移動の数
    uint8 public decimals = 18;

    // 初期発行量
    uint256 public initialSupply = 10000 * (10 ** uint256(decimals));

    constructor() public {
        // 最初は発行者にすべてを振り込む
        _mint(msg.sender, initialSupply);
    }
}

ソースコード解説

Solidityのソースコードを詳しく説明していきます.

1
pragma solidity ^0.4.24;

Solidity言語のコンパイラのバージョン指定です.このバージョン以下のコンパイラではコンパイルされません。また^をつけることで、それ以上のマイナーバージョン(0.5.0以上)でもコンパイルされません。

1
2
3
4
5
import "../../node_modules/openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";


contract ShunCoin is ERC20 {
}

OpenZeppelin SolidityのERC20/ERC20.solのERC20コントラクトにトークンの基本実装がしてあります.トークンを発行する時にはこれを継承したコントラクトを作成すると、ほとんどコードを書く必要がありません。ShunCoinはERC20を継承していることを表しています。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
    // トークン名
    string public name = "ShunCoin";
    // 通貨単位
    string public symbol = "SHN";
    // 小数点移動の数
    uint8 public decimals = 18;
    // 初期発行量
    uint256 public initialSupply = 10000 * (10 ** uint256(decimals));
 ```

トークンをカスタマイズしているコードです.上からトークン名、通貨単位、小数点以下何桁まで表示するか、初期発行量の設定です。

**他のトークンと被っていても問題ありません.コントラクトを公開した時に割り振られるアドレスで一意に特定されます。**

初期発行量は、10000トークン発行し、小数点以下18桁なので4+18で0は22個となります.

```js
  constructor () public {
    }

コンストラクタです.スマートコントラクトがインスタンス化されるのはデプロイ時の1回のみです。つまりコンストラクタは1回しか呼ばれません。

publicは、メソッドの修飾子で、このコントラクト自身の他のメソッドからも全世界のユーザー誰からも呼び出せます.コンストラクタは一度しか呼べないので重要ではありませんが、普通のメソッドではセキュリティ上とても重要です。

  • private: このコントラクト自身の他メソッドからは呼び出し可能だが、外部ユーザーは呼び出し不可.
  • extenral: このコントラクト自身の他メソッドからは呼び出し不可.外部ユーザーは呼び出し可。
  • view: ブロックチェーンの内容を読むが、書きかえない.
  • pure: ブロックチェーンの内容を読み書きしない.

viewpureをつけておくと、関数実行時にトランザクションを発行する必要がなくなり、手数料が無料になります.

1
2
        // 最初は発行者にすべてを振り込む
        _mint(msg.sender, initialSupply);

_mintはERC20コントラクト側で定義されている、トークンを追加発行する関数です.最初は0トークンの状態なので、初期発行量分だけmsg.senderに対して発行します。

msg.senderというのはaddress型という型で、コントラクト公開のトランザクションを発生させたユーザーのアドレスが格納されます.つまりここではオーナーですね。

Solidityの型には他に

  • 真偽値(bool)
  • 文字列(string)
  • 符号あり整数(int)
  • 符号なし整数(uint256)
  • バイト(byte)
  • 配列([n])
  • 動的配列([])
  • 連想配列(mapping)

などがあります.

デプロイの設定

公開していきます.

truffleディレクトリに移動しましょう.

migrationsというディレクトリがあるので、その中に2_deploy.jsというファイルを作成し、以下の内容を書き込んで下さい.

ShunCoinは自身のトークン名に変更して下さい.

1
2
3
4
5
var ShunCoin = artifacts.require("ShunCoin");

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

ローカルにデプロイして動作確認

以下のコマンドを実行してローカルテスト用ノードを立ち上げて下さい.

1
    ../node_modules/.bin/truffle develop

以下のコマンドでデプロイしましょう.

1
    truffle(develop)> migrate --reset

migrateはmigrations以下のデプロイスクリプトを順に実行するコマンドです.

–resetを指定すると必ず1からすべて実行されます.

開発時は–resetを指定するとよいでしょう.

以下のコマンドでAccount0の残高が確認できます.

1
2
    truffle(develop)> ShunCoin.deployed().then(function(instance){shun=instance;})
    truffle(develop)> shun.balanceOf(web3.eth.accounts[0])

Ropstenネットワークに公開

以下のコマンドでRopstenに接続したコンソールを立ち上げて下さい.

1
    ../node_modules/.bin/truffle console --network ropsten

以下のコマンドでデプロイ完了です.(全世界からアクセス可能な状態です)

1
    truffle(ropsten)> migrate --reset

公開されたアドレスを確認しましょう.

1
2
    truffle(ropsten)> ShunCoin.address
    '0xb4daaebd10f75f6b87a122734114a057777df697'

次のMetaMaskでの確認に使用するためコピーしておいて下さい.

MetaMaskで確認

MetaMaskでトークンを追加してみましょう.

トークンの追加

MetaMaskではEtherだけでなく、トークンも管理できます.

ここ作ったShunCoinを追加してみましょう.

「TOKENS」をクリック.

「ADD TOKEN」をクリック.

「Token Contract Address」に先ほどコピーした自分のトークンのアドレスを入力.

例: 0x6670fc52dd04dd9d1780f10b464d1fa56d4a39f2

「Token Symbol」の入力欄をクリック.

SymbolとDecimalsが自動で入力されるはずです.

「Add」をクリック.

以上でトークンが追加されます.

10000SHN振り込まれていたら成功です.

トークン発行は以上です.

お疲れ様でした!