シンプルなクラウドセールの実装手順【OpenZeppelin2.0】

シンプルなクラウドセールの実装手順【OpenZeppelin2.0】

どうもこじりょー(@kojiryoinvestor)です。

この記事は「OpenZeppelin」を利用してクラウドセール(ICO)が行えるコントラクトを開発していくチュートリアルです。

クラウドセールの実装の際にはERC20トークンも実装していきます。

ERC20トークンの実装方法がよくわからない場合は、先に下記のチュートリアルを済ませておくことをオススメします!

【Truffle5.0対応】シンプルなERC20トークンを作成しよう!

またこの記事のチュートリアルは以下の開発環境で実装していきます:

  • Truffle@v5.0.0
  • openzeppelin-solidity@2.1.1
  • ganache(GUI)@v1.2.2
  • solc 0.5.0

クラウドセール(ICO)とは?

企業またはプロジェクトがブロックチェーン上でトークンを発行・販売することで資金調達を実現する方法です。

投資家はウォレットと暗号通貨(BTCやETHなど)さえあれば、誰でもトークンを購入することができます。

資金を集めたプロジェクトが、発行したトークンが利用されるエコシステムを構築すればトークンの価値は上昇します。

その結果、割安でトークンを入手できた投資家や開発者は資産を増やすことができます。

もちろんその反対の結果となったプロジェクトもたくさんあります。

まだまだ課題の多い資金調達方法ですが、従来大きな投資が得られてこなかった社会起業家等が問題解決へのインパクトと共感で資金を集めることができる方法として注目されています。

クラウドセールの実装

クラウドセールの仕様

「OpenZepplin」を利用すればクラウドセールの用途に合わせて開発・拡張することができます。

例えば、開始時間と終了時間をつけたり、集めるETHの上限を設定したり。

事前にトークンの発行に制限を設けず、期間内に購入された分だけトークンを発行するなど。

用途に合わせて様々な拡張が可能です。

ここでは特別なことはせず、ETHを送ればトークンを返すだけのシンプルなクラウドセールコントラクトを実装してきます。

仕様は以下の通りです:

  • クラウドセールコントラクトはセール開始時に10ST(10^18)トークン保持
  • トークンの交換レートは 「1」(「1ETH」送れば「1ST」受け取る)
シンプルなクラウドセールコントラクトの仕様
素材提供:「いらすとや

ERC20トークンの作成

クラウドセールを行うためにはERC20トークンがなくてはいけません。

まずはERC20トークンを作成しましょう。

ここではmint()やburn()のないシンプルなERC20トークンを定義します。

SimpleToken.sol:

このコントラクトは下記の記事で作成したものをそのまま利用しています。

詳細は下記の記事をご参考ください!

【Truffle5.0対応】シンプルなERC20トークンを作成しよう!

クラウドセールコントラクトの実装

それではクラウドセールのコントラクトを作っていきます。

「OpenZepplin」を利用するので、ものすごくシンプルです。

ここでは「MyCrowdsale.sol」として名前をつけて作成します。

MyCrowdsale.sol:

コントラクトの中身は以下のようになっています:

  • Crowdsale.solを継承
  • 作成者が設定したrate、wallet、tokenの各パラメーターをコンストラクタで受け取る
  • 受け取ったパラメーターをCrowdsale.solのコンストラクタに渡す

とっても簡素なコントラクトですが、これだけでクラウドセールができます。

Crowdsale.soldのコントラクトにトークン交換等のロジックが組まれているため、それを継承するだけクラウドセールを実装できます。

マイグレーションの作成

次に作成したコントラクトをデプロイするためのマイグレーションを作成します。

ここでは「2_deploy_simple.js」と名前をつけて作成します。

2_deploy_simple.js:

まずはERC20とクラウドセールのコントラクトに必要なパラメーターをそれぞれ定義します。

// ERC20パラメーター
const name = "SimpleToken";
const symbol = "ST";
const decimals = 18;
const initSupply = web3.utils.toBN(10*(10**decimals));
// Crowdsaleパラメーター
const rate = web3.utils.toBN(1);
const wallet = accounts[0];

続いてERC20トークンのコントラクト、次にクラウドセールのコントラクトといった順番にデプロイします。

return deployer.then(() => {
        // ERC20トークンのデプロイ
        return deployer.deploy(
            SimpleToken,
            name,
            symbol,
            decimals,
            initSupply
        );
    }).then(() => {
        // クラウドセールコントラクトのデプロイ
        return deployer.deploy(
            MyCrowdsale,
            rate,
            wallet,
            SimpleToken.address
        );
    })

これはクラウドセールのコントラクトにはERC20トークンのコントラクトアドレスが必要なため、先にERC20トークンのコントラクトをデプロイしています。

最後にクラウドセールのコントラクトに発行した全てのトークンを送って完了です。

// クラウドセールコントラクトに発行したトークンを送信
return SimpleToken.deployed().then(instance => {
    instance.transfer(MyCrowdsale.address, initSupply,{from:accounts[0]})
});

クラウドセールを動かす

デプロイ

ここではGanache(GUI)でプライベートネットを構築してデプロイしていきます。

truffle-config.js:

development: {
      host: "127.0.0.1",
      port: 7545,
      network_id: "*",
},

truffle-config.jsに必要な設定を書いたら、Ganacheを起動します。

次にターミナルを起動して、下記のコマンドを実行してコントラクトをデプロイしましょう。

$ truffle migrate

特にエラーもなく、下記の画像のように表示されればデプロイ完了です。

コントラクトを動かす

それでは作成したコントラクトを動かしていきます。

ターミナルから以下のコマンドを実行して、プライベートネットのノードにアクセスします。

$ truffle console

プライベートネットにアクセスしたらWeb3.jsを利用してコントラクトを操作していきます。

まずは下記のコードを入力して、Ganacheが生成したアカウントを取得してaccounts変数に格納しましょう。

> web3.eth.getAccounts().then(a=>accounts=a)

続いてMyCrowdsaleコントラクトのインスタンスを生成し、crowdsale変数に格納します。

> MyCrowdsale.deployed().then(c=>crowdsale=c)

次にクラウドセールで販売しているトークンのアドレスを取得して、address変数に格納します。

> crowdsale.token().then(a=>address=a)

クラウドセールで販売しているトークンのインスタンスを生成します。

> SimpleToken.at(address).then(t=>token=t)

クラウドセールコントラクトがトークンを所持しているかを確認します。

> token.balanceOf(crowdsale.address).then(b=>balance=b)
> web3.utils.fromWei(balance)

クラウドセールコントラクトが所持しているトークンの残高

こちらが指定した通り「10ST」所持していることが確認できました。

トークンを購入する

それではトークンを購入していきましょう。

交換レートには「1」と指定しているため「1ETH」送れば「1ST」もらえます。

> crowdsale.rate()

rateの確認

ここでは「6ETH」送って「6ST」もらえるか試していきます。

コントラクト上の取引はweiで行われるため、6ETHという単位をweiに変換し、結果をvalue変数に格納します。

> value = web3.utils.toWei('6', "ether")

6ETHをweiに変換

次にaccounts[1]からクラウドセールコントラクトに「6ETH」を送ります。

crowdsale.sendTransaction({from:accounts[1], value:value})

特にエラーもなくreceipt(レシート)が表示されればトランザクションに成功しています。

accoutns[1]のトークンの残高を確認してみます。

> token.balanceOf(accounts[1]).then(b=>balance=b)
> web3.utils.fromWei(balance)

ETH送信後のaccounts[1]のトークン残高

ちゃんと「6ST」受け取れています。

再度クラウドセールコントラクトのトークン残高も確認してみます。

> token.balanceOf(crowdsale.address).then(b=>balance=b)
> web3.utils.fromWei(balance)

ETH受け取り後のクラウドセールコントラクトのトークン残高

「6ST」送っているので残りはちゃんと「4ST」となっています。

おわりに

以上がOpenZepplinを利用したシンプルなクラウドセールコントラクトの実装でした。

OpenZepplinを利用すればまだまだクラウドセールの拡張が可能です。

時間制限をつけてみたり、ETHが送られるたびにトークンが発行されるようなクラウドセールにしてみたりと色々遊んでみてください!

ソースコード:

https://github.com/kojimaro/Crowdsale-tutorial

参考リンク:

Dapps開発のチュートリアル動画

Dapps開発のチュートリアル動画をYoutubeで公開しています!

よろしかったらチャンネル登録をよろしくお願いします!

ERC20トークンカテゴリの最新記事