クリプト

ALISのICOスマートコントラクトを読む②

kenjiszk's icon'
  • kenjiszk
  • 2018/05/07 16:02
Content image

前回記事に引き続き、アリスのICOスマートコントラクトを読んでみることにします。今回は、クラウドセール実装部分について。

github : https://github.com/AlisProject/ico-contracts


クラウドセール実装部分

クラウドセールは、その名の通りICOをする時に発行したトークンを売るためのロジックです。ソースコードは以下ですが、ここでもほとんどの機能がopenzeppelin-solidityから提供されているため、Alis側ではそれらをAlisトークン用に書き換える、という処理を行なっているようです。

https://github.com/AlisProject/ico-contracts/blob/master/contracts/AlisCrowdsale.sol

以下のように、openzeppelin-solidityからimportしているのでそれぞれについてみていってみます。

import 'zeppelin/contracts/crowdsale/CappedCrowdsale.sol';
import 'zeppelin/contracts/crowdsale/RefundableCrowdsale.sol';
import 'zeppelin/contracts/token/MintableToken.sol';
import 'zeppelin/contracts/lifecycle/Pausable.sol';



CappedCrowdsale

CappedCrowdsaleはCrowdsaleを継承しているので、Crowdsaleを先に見てみます。

https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v1.6.0/contracts/crowdsale/Crowdsale.sol

Crowdsaleは、セールを始める(トークンを発行する)と、トークンを買う、の部分を担当している様子。

セールを始める(トークンを発行する)部分はこちら。

function Crowdsale(uint256 _startTime, uint256 _endTime, uint256 _rate, address _wallet) public {
  require(_startTime >= now);
  require(_endTime >= _startTime);
  require(_rate > 0);
  require(_wallet != address(0));
  token = createTokenContract();
  startTime = _startTime;
  endTime = _endTime;
  rate = _rate;
  wallet = _wallet;
}

最初4つはバリデーションです。

- クラウドセールの開始時間が未来であること

- セールの終了時間が開始時間よりも未来であること

- トークンのイーサリアムとの変換レートが正の数であること

- 集めたイーサリアムのアドレスが無効なものでないこと(address(0)はアドレスのセット忘れなどで生じる無効なアドレス)

その後、createTokenContract()でトークンを発行します。Crowdsale.solではここでMintableTokenを発行していますが、Alisトークンでは独自のトークンを発行するため、createTokenContract()はオーバーライドされています(後述)。


次に、トークンを買うはこちら。イーサリアムでトークンを購入します。

function buyTokens(address beneficiary) public payable {
  require(beneficiary != address(0));
  require(validPurchase());
  uint256 weiAmount = msg.value;
  // calculate token amount to be created
  uint256 tokens = getTokenAmount(weiAmount);
  // update state
  weiRaised = weiRaised.add(weiAmount);
  token.mint(beneficiary, tokens);
  TokenPurchase(msg.sender, beneficiary, weiAmount, tokens);
  forwardFunds();
}

送られて来たイーサリアムの数から、getTokenAmountでトークンの数を求めてその量をMintしていることがわかります。Mintについては前回の記事を参照してください。その後、送られて来たイーサリアムをforwardFunds()でウォレットに転送しています。

function forwardFunds() internal {
  wallet.transfer(msg.value);
}

と、ここまでがCrowdsaleですが、これを継承しているCappedCrowdsaleを見て見ます。

https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v1.6.0/contracts/crowdsale/CappedCrowdsale.sol

この中ではcapという変数により、イーサリアムの上限を定めています。二つのフラグが書かれており、すでに上限に達しているかを確かめるためのhasEnded()と、

function hasEnded() public view returns (bool) {
  bool capReached = weiRaised >= cap;
  return capReached || super.hasEnded();
}

現在の支払いによりcapに達してしまうかどうか(現在の支払いが有効かどうか)を確かめるvalidPurchase()が書かれています。

function validPurchase() internal view returns (bool) {
  bool withinCap = weiRaised.add(msg.value) <= cap;
  return withinCap && super.validPurchase();
}



RefundableCrowdsale

次に、RefundableCrowdsaleの処理を読んでいきます。Refundつまり返金の処理が書いてあります。クラウドセールなので目標額に達しなかった場合には返金をしっかりする、ということをあらかじめスマートコントラクトに書いておく、ということが大事になります。

https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v1.6.0/contracts/crowdsale/RefundableCrowdsale.sol

この中のRefundableCrowdsaleからnewされているRefundVaultがポイントなのでそこについて詳しく見ていきます。RefundVaultは直訳で払い戻し金庫です。

https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v1.6.0/contracts/crowdsale/RefundVault.sol

中を見てもらえばわかるように、RefundVaultを呼び出す事で払戻し金庫としてのwalletの初期化と、クラウドセールのStateを設定しています。

StateがActiveなうち、つまりクラウドセール中にはdeposit(資金集め)、close(資金受付停止)、enableRefunds(refund可能なステータスに変更)というfunctionが実行可能で、

enableRefunds()によってState.Refundingになった場合に、実際にrefundが実行できます。investorのアドレスに対して、deposited[investor]の分だけ払い戻ししていることがわかります。

function refund(address investor) public {
  require(state == State.Refunding);
  uint256 depositedValue = deposited[investor];
  deposited[investor] = 0;
  investor.transfer(depositedValue);
  Refunded(investor, depositedValue);
}

このRefundVaultをベースに作られているのが、RefundableCrowdsaleということになります。RefundableCrowdsaleはFinalizableCrowdsaleを継承していますが、これはクラウドセールが終了した時に呼び出されるfinalization()をオーバーライドするためです。

クラウドセールのゴールに達成していたら単純に資金集めを停止、達していなければrefund、という処理が書かれています。

function finalization() internal {
  if (goalReached()) {
    vault.close();
  } else {
    vault.enableRefunds();
  }
  super.finalization();
}


MintableToken

MintableTokenは前回の記事で紹介した通りです。


Pausable

https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v1.6.0/contracts/lifecycle/Pausable.sol

ICOの緊急停止用のmodifierを定義しているようです。whenNotPaused()とwhenPaused()があり、これをmodifierとして使うことで何かやばいことが起きた時にICOを緊急停止できると。


ということで、やっとAlisCrowdsaleのimport部分の解読完了。

次回は、AlisCrowdsale.sol.solの独自実装部分を見ていきます。

ALISのICOスマートコントラクトを読む③



公開日:2018/05/07
獲得ALIS:19.92
kenjiszk's icon'
  • kenjiszk
  • @kenjiszk
エンジニア。ブロックチェーン勉強中。

投稿者の人気記事
コメントする
コメントする
こちらもおすすめ!
Eye catch
クリプト

【初心者向け】$MCHCの基本情報と獲得方法

Like token Tip token
32.32 ALIS
Eye catch
クリプト

CoinList(コインリスト)の登録方法

Like token Tip token
15.55 ALIS
Eye catch
クリプト

UNISWAPでALISをETHに交換してみた

Like token Tip token
40.40 ALIS
Eye catch
クリプト

Uniswap v3を完全に理解した

Like token Tip token
18.92 ALIS
Eye catch
クリプト

クリプトスペルズで入手したMCHCを引き出す方法

Like token Tip token
196.20 ALIS
Eye catch
クリプト

約2年間ブロックチェ-ンゲームをして

Like token Tip token
61.20 ALIS
Eye catch
クリプト

Eth2.0のステークによるDeFiへの影響を考える。

Like token Tip token
44.10 ALIS
Eye catch
クリプト

17万円のPCでTwitterやってるのはもったいないのでETHマイニングを始めた話

Like token Tip token
46.60 ALIS
Eye catch
クリプト

コインチェックに上場が決まったEnjin Coin(エンジンコイン)コインを解説

Like token Tip token
21.49 ALIS
Eye catch
クリプト

Polygon(Matic)で、よく使うサイト(DeFi,Dapps)をまとめてみた

Like token Tip token
236.30 ALIS
Eye catch
クリプト

【第8回】あの仮想通貨はいま「テレグラム-TON/Gram」

Like token Tip token
69.90 ALIS
Eye catch
クリプト

NFT解体新書・デジタルデータをNFTで販売するときのすべて【実証実験・共有レポート】

Like token Tip token
121.79 ALIS