クリプト

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
クリプト

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

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

Uniswap(ユニスワップ)で$ALISのイールドファーミング(流動性提供)してみた

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

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

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

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

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

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

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

2021年1月以降バイナンスに上場した銘柄を140文字以内でざっくりレビュー(Twitter向け情報まとめ)

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

Uniswap v3を完全に理解した

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

バイナンスの信用取引(マージン取引)を徹底解説~アカウントの開設方法から証拠金計算例まで~

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

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

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

ジョークコインとして出発したDogecoin(ドージコイン)の誕生から現在まで。注目される非証券性🐶

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

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

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

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

Like token Tip token
21.49 ALIS