2018年9月にsolidityのライブラリであるOpenZeppelinのv2.0.0がリリースされました。それに伴い、OpenZeppelinを使ったERC20トークンの発行方法も変わっているので、ご紹介したいと思います。
ERC20トークンとは
ERC20トークンとは、Ethereum上で発行されるトークンの規格の一種で、最も有名なものです。この規格はオープンに議論されており、下記リンクから参照可能です。
https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
この規格に対応したトークンを発行することで、対応している多くのウォレットで扱うことができるようになります。
OpenZeppelinとは
OpenZeppelinnとはスマートコントラクト用のライブラリで、コントラクト実装には欠かせない存在です。
OpenZeppelin is a battle-tested framework of reusable smart contracts for Ethereum and other EVM and eWASM blockchains.
battle-tested
と書かれている通り、しっかりとテストされたコントラクトなので、安心して利用できます。(コントラクトは基本的に一度デプロイすると変更できないので、しっかりテストされたライブラリを活用して実装することがおすすめです)
オフィシャルサイト
https://openzeppelin.org/
コード
https://github.com/OpenZeppelin/openzeppelin-solidity
ERC20トークンのコード
それでは、ERC20トークンを発行していきます。
solidityというEthereumのスマートコントラクト言語を用いて記述していきます。
以下が最終のERC20のコードです。
pragma solidity >=0.5.0 <0.7.0;
import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol";
contract MyToken is ERC20, ERC20Detailed {
string private _name = "TAKASE";
string private _symbol = "TKS";
uint8 private _decimals = 18;
address account = msg.sender;
uint value = 100000000000000000000;
constructor() ERC20Detailed( _name, _symbol, _decimals) public {
_mint(account, value);
}
}
ここから各行について解説していきます。
pragma solidity >=0.5.0 <0.7.0;
ここで、solidityのコンパイラのバージョンを指定します。
import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol";
次に、OpenZeppelinからERC20.sol
とERC20Detailed.sol
をインポートしてきます。ERC20.sol
では基本的なERC20の機能が実装されております。また、ERC20Detailed.sol
には「名前」「シンボル」「小数点の桁数」の設定が可能になっています。
contract MyToken is ERC20, ERC20Detailed {
...
}
MyToken
という名前のコントラクトを定義し、ERC20
, ERC20Detailed
のコントラクトを継承します。
string private _name = "TAKASE";
string private _symbol = "TKS";
uint8 private _decimals = 18;
発行するトークンの「名前」、「シンボル」、「小数点の桁数」の値を代入します。
address account = msg.sender;
uint value = 100000000000000000000;
発行時のトークンをどのウォレットに付与するかを決定する必要があり、ここではmsg.sender
(このコントラクトをデプロイした時のウォレット)のアドレスを代入しています。
また、value
でトークンの初期発行数を設定しています。
constructor() ERC20Detailed( _name, _symbol, _decimals) public {
_mint(account, value);
}
constructor()とは、コントラクトをデプロイする時に1度だけ呼ばれるももので、初期値の設定などに活用されます。
今回のMyTokenコントラクトでは、ERC20Detailed
のコントラクトを継承しているで、ERC20Detailed
のコンストラクタもよんでおきます。引数には先ほど設定した、「名前」「シンボル」「小数点の桁数」を渡してあります。
また、 _mint()
はERC20.sol
で定義されているinternal
な関数で、継承しているMyToken
から呼び出しています。引数には先ほど定義したウォレットのアドレスと初期発行数を渡しています。
発行方法(コントラクトのデプロイ)
solidityのIDE(統合開発環境)を使って、実装したコントラクトをデプロイしていきます。
Remix
https://remix.ethereum.org/
具体的な方法については過去noteを参照いただけると幸いです。(記事中盤のRemix活用の部分)
https://note.mu/toshitoissho/n/n93eadf07fd47
機能の拡張
上記は、非常にシンプルなERC20を実装しました。
ですが、OpenZeppelinでは他にも機能拡張させたコントラクトを用意してくれています。
そこで、以下のように2種の概念を追加したERC20のコントラクトを実装してみます。
pragma solidity >=0.5.0 <0.7.0;
import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/ERC20Mintable.sol";
import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/ERC20Burnable.sol";
import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol";
contract MyToken is ERC20Mintable, ERC20Burnable, ERC20Detailed {
string private _name = "TAKASE";
string private _symbol = "TKS";
uint8 private _decimals = 18;
uint value = 100000000000000000000;
constructor()
ERC20Detailed(_name, _symbol, _decimals)
ERC20Burnable()
ERC20Mintable()
public
{
_mint(msg.sender, value);
}
}
追加したのは、
- ERC20Mintable.sol
- ERC20Burnable.sol
の2種です。
constructor()
ERC20Detailed(_name, _symbol, _decimals)
ERC20Burnable()
ERC20Mintable()
public
{
_mint(msg.sender, value);
}
実装は極めてシンプルで、importして継承したコントラクトをconstructorで呼び出すだけです。
では、具体的に何ができるようになったのか、以下で見ていきます。
ERC20Mintable.sol
初期のシンプルなERC20では、初期に発行したトークンの数量を増やすことはできませんでした。
一方ERC20Mintable
では、mint
関数を使って、随時トークンの発行を可能にします。そのため、権限者の意図によって総発行数量を増やすことができます。
また、addMinter
関数でトークンを発行する権利をもつウォレットを追加可能にしています。
ERC20Burnable.sol
初期コントラクトでは、発行したトークンを増やすことができないのと同様に、減らすこともできませんでした。
一方、ERC20Burnable.sol
は、発行したトークンをバーン(消去)することができます。そのため、総発行数量を減らすことができます。
まとめ
OpenZeppelinの2.0.0では、目的別の実装がシンプルでわかりやすく実装できるようになった印象があります。ですが、結局のところERC20トークンはドシドシ発行したところで無価値すぎるので、どんな用途に使うのか考え抜いて発行しないといけないなと思います。
とりあえず、OpenZepplinを使ってみたい方や、v2.0.0になって戸惑っている方にお役立ちできる内容になっていれば幸いです。
以上