Last active
December 22, 2016 10:29
-
-
Save akirattii/f9c787eeb50758ce600d70cf0db2ed67 to your computer and use it in GitHub Desktop.
Ethereum クラウドセール・コントラクト(β)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| pragma solidity ^0.4.7; | |
| // ======================================================= | |
| // クラウドセール・コントラクトのおおまかな処理 | |
| // ======================================================= | |
| // + コンストラクタで独自コインの総量などを決定 | |
| // | |
| // + 出資者からの資金提供と引き換えに独自コインを渡す | |
| // | |
| // + 募集期限終了後、誰でもクラウドセール終了のトリガーを引ける | |
| // | |
| // - 調達額が目標に届いた場合: | |
| // - 終了のトリガーを引いたのがオーナーだった場合: | |
| // + オーナーは調達資金を手に入れる | |
| // + 成功フラグを立てる | |
| // - 終了のトリガーを引いたのがオーナー*以外*だった場合: | |
| // + 成功フラグを立てる | |
| // | |
| // - 調達が目標に届かなかった場合: | |
| // - 終了のトリガーを引いたのが誰であろうと: | |
| // + 出資者はオーナーにコインを返却 | |
| // + 出資者はオーナーから資金を取り戻す | |
| // + 成功フラグを倒す | |
| // | |
| // クラウドセール・コントラクト | |
| contract Crowdsale { | |
| // クラウドセールの成功フラグ | |
| bool public succeeded; | |
| // コイン保有者一覧 | |
| mapping (address => uint) public coinBalanceOf; | |
| // 出資者に対して発行するコインの単価(ether) | |
| uint public coinPrice; | |
| // コントラクトの作成者 | |
| address public owner; | |
| // 調達目標額 | |
| uint public fundingGoal; | |
| // 調達額 | |
| uint public amountRaised; | |
| // 募集期限 | |
| uint public deadline; | |
| // 出資者 | |
| Funder[] public funders; | |
| // 出資者の構造体 | |
| struct Funder { | |
| address addr; | |
| uint amount; | |
| } | |
| // コイン送金イベント | |
| event CoinTransfer(address sender, address receiver, uint amount); | |
| // 資金送信イベント | |
| event FundTransfer(address backer, uint amount, bool isContribution); | |
| // デバッグログイベント | |
| event Log(string method, address sender, string message); | |
| // このコントラクトのコンストラクタ | |
| function Crowdsale( | |
| uint _fundingGoal, | |
| uint _duration, | |
| uint _coinPrice, | |
| uint _coinSupply | |
| ) { | |
| Log("Constructor", msg.sender, ""); | |
| succeeded = false; | |
| owner = msg.sender; // オーナーはコントラクト作成者 | |
| fundingGoal = _fundingGoal; | |
| deadline = now + _duration * 1 minutes; | |
| coinPrice = _coinPrice; | |
| coinBalanceOf[msg.sender] = _coinSupply; | |
| } | |
| // 無名関数 | |
| // Note: 誰かが資金を送信する度に実行されます | |
| function() payable { | |
| Log("Payable anonymous function", msg.sender, ""); | |
| uint amount = msg.value; | |
| // 資金送信者を出資者として登録 | |
| funders[funders.length++] = Funder({addr: msg.sender, amount: amount}); | |
| // 出資額に加算 | |
| amountRaised += amount; | |
| // 出資額に見合った数のコインを出資者に発行 | |
| sendCoin(owner, msg.sender, amount / coinPrice); | |
| // 資金送信イベント発火 | |
| FundTransfer(msg.sender, amount, true); | |
| } | |
| // コイン送金 | |
| // @param {address} コイン送金人 | |
| // @param {address} コイン受取人 | |
| // @param {uint} 数量 | |
| function sendCoin(address from, address to, uint amount) returns(bool sufficient) { | |
| Log("sendCoin", msg.sender, ""); | |
| if (coinBalanceOf[from] < amount) return false; | |
| // コインを移転 | |
| coinBalanceOf[from] -= amount; | |
| coinBalanceOf[to] += amount; | |
| // コイン送信イベント発火 | |
| CoinTransfer(from, to, amount); | |
| return true; | |
| } | |
| // 「募集期限満了後」のみ関数を実行するためのmodifier | |
| modifier afterDeadline() { if (now >= deadline) _; } | |
| // 「コントラクトの作成者の場合」のみ関数を実行するためのmodifier | |
| modifier onlyOwner() { if (owner == msg.sender) _; } | |
| // 目標到達をチェックする関数 | |
| // Note: 募集期限満了後に実行できます。 | |
| function checkGoalReached() afterDeadline { | |
| Log("checkGoalReached", msg.sender, ""); | |
| uint i; | |
| if (amountRaised >= fundingGoal){ | |
| // ***************************************** | |
| // 目標達成 | |
| // ***************************************** | |
| // オーナーによる実行の場合は、オーナーへ調達額を送金 | |
| if(msg.sender == owner && owner.send(amountRaised)){ | |
| // sendに成功したら資金送金イベント発火 | |
| FundTransfer(owner, amountRaised, false); | |
| } | |
| // 成功フラグを立てる | |
| succeeded = true; | |
| Log("checkGoalReached", msg.sender, "Fundraise succeeded!"); | |
| } else { | |
| // ***************************************** | |
| // 目標未達 | |
| // ***************************************** | |
| // FundTransfer(0, 11, false); // ??? | |
| // 全出資者に対してループ | |
| for (i = 0; i < funders.length; ++i) { | |
| // 予め受け取っていたトークンをオーナーに返却 | |
| if (sendCoin(funders[i].addr, owner, coinBalanceOf[funders[i].addr])) { | |
| // トークンを戻すことに成功したら、出資者に返金 | |
| if (funders[i].addr.send(funders[i].amount)) { | |
| // 返金に成功したら資金送金イベント発火 | |
| FundTransfer(funders[i].addr, funders[i].amount, false); | |
| } | |
| } | |
| } | |
| // 成功フラグを倒す(つまり失敗) | |
| succeeded = false; | |
| Log("checkGoalReached", msg.sender, "Fundraise failed :("); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment