如何經過以太坊智能合約來進行衆籌(ICO)

最新內容會更新在主站深刻淺出區塊鏈社區
原文連接:如何經過以太坊智能合約來進行衆籌(ICO)html

前面咱們有兩遍文章寫了如何發行代幣,今天咱們講一下如何使用代幣來公開募資,即編寫一個募資合約。app

寫在前面

本文所講的代幣是使用以太坊智能合約建立,閱讀本文前,你應該對以太坊、智能合約有所瞭解,若是你還不瞭解,建議你先看以太坊是什麼函數

衆籌

先簡單說下衆籌的概念:通常是這樣的,我一個很是好的想法,可是我沒有錢來作這事,因而我把這個想法發給你們看,說:我作這件事須要5百萬,你們有沒有興趣投些錢,若是你們在30天內投夠了5百萬我就開始作,到時你們都是原始股東,若是募資額不到5百萬,你們投的錢就還給你們。學習

如今ICO衆籌已經被各路大佬拿來割韭菜而被玩壞了(無論有無達標,都把錢捲走)。區塊鏈

其實區塊鏈技術本事很是適合解決衆籌的信任問題,藉助於智能合約,能夠實現當募資額完成時,募資款自動打到指定帳戶,當募資額未完成時,可退款。這個過程不須要看衆籌大佬的人品,不用依靠第三方平臺信用擔保。ui

代幣

傳統的衆籌在參與以後一般不容易交易(參與以後沒法轉給其餘人),而經過用代幣來參與衆籌,則很容易進行交易,衆籌的參與人可隨時進行買賣,待衆籌項目實施完成的時候,徹底根據代幣持有量進行回饋。code

舉個例子說明下,你們會更容易理解,有這一個衆籌:A有技術作一個能監測健康的指環,爲此向公衆募資200百萬,募資時100塊對應一個代幣,約定在指環上市以後,代幣的持有人能夠用一個代幣來兌換一個指環。而指環的研發週期是一年,所以在指環還未上市的一年裏,衆籌的參與人能夠隨時交易所持有的代幣。視頻

衆籌智能合約代碼

接下來就看看如何實現一個衆籌智能合約。htm

pragma solidity ^0.4.16;

interface token {
    function transfer(address receiver, uint amount);
}

contract Crowdsale {
    address public beneficiary;  // 募資成功後的收款方
    uint public fundingGoal;   // 募資額度
    uint public amountRaised;   // 參與數量
    uint public deadline;      // 募資截止期

    uint public price;    //  token 與以太坊的匯率 , token賣多少錢
    token public tokenReward;   // 要賣的token

    mapping(address => uint256) public balanceOf;

    bool fundingGoalReached = false;  // 衆籌是否達到目標
    bool crowdsaleClosed = false;   //  衆籌是否結束

    /**
    * 事件能夠用來跟蹤信息
    **/
    event GoalReached(address recipient, uint totalAmountRaised);
    event FundTransfer(address backer, uint amount, bool isContribution);

    /**
     * 構造函數, 設置相關屬性
     */
    function Crowdsale(
        address ifSuccessfulSendTo,
        uint fundingGoalInEthers,
        uint durationInMinutes,
        uint finneyCostOfEachToken,
        address addressOfTokenUsedAsReward) {
            beneficiary = ifSuccessfulSendTo;
            fundingGoal = fundingGoalInEthers * 1 ether;
            deadline = now + durationInMinutes * 1 minutes;
            price = finneyCostOfEachToken * 1 finney;
            tokenReward = token(addressOfTokenUsedAsReward);   // 傳入已發佈的 token 合約的地址來建立實例
    }

    /**
     * 無函數名的Fallback函數,
     * 在向合約轉帳時,這個函數會被調用
     */
    function () payable {
        require(!crowdsaleClosed);
        uint amount = msg.value;
        balanceOf[msg.sender] += amount;
        amountRaised += amount;
        tokenReward.transfer(msg.sender, amount / price);
        FundTransfer(msg.sender, amount, true);
    }

    /**
    *  定義函數修改器modifier(做用和Python的裝飾器很類似)
    * 用於在函數執行前檢查某種前置條件(判斷經過以後纔會繼續執行該方法)
    * _ 表示繼續執行以後的代碼
    **/
    modifier afterDeadline() { if (now >= deadline) _; }

    /**
     * 判斷衆籌是否完成融資目標, 這個方法使用了afterDeadline函數修改器
     *
     */
    function checkGoalReached() afterDeadline {
        if (amountRaised >= fundingGoal) {
            fundingGoalReached = true;
            GoalReached(beneficiary, amountRaised);
        }
        crowdsaleClosed = true;
    }


    /**
     * 完成融資目標時,融資款發送到收款方
     * 未完成融資目標時,執行退款
     *
     */
    function safeWithdrawal() afterDeadline {
        if (!fundingGoalReached) {
            uint amount = balanceOf[msg.sender];
            balanceOf[msg.sender] = 0;
            if (amount > 0) {
                if (msg.sender.send(amount)) {
                    FundTransfer(msg.sender, amount, false);
                } else {
                    balanceOf[msg.sender] = amount;
                }
            }
        }

        if (fundingGoalReached && beneficiary == msg.sender) {
            if (beneficiary.send(amountRaised)) {
                FundTransfer(beneficiary, amountRaised, false);
            } else {
                //If we fail to send the funds to beneficiary, unlock funders balance
                fundingGoalReached = false;
            }
        }
    }
}

部署及說明

在部署這個合約以前,咱們須要先部署一個代幣合約,請參考一步步教你建立本身的數字貨幣blog

  1. 建立衆籌合約咱們須要提供一下幾個參數:
    ifSuccessfulSendTo: 募資成功後的收款方(其實這裏能夠默認爲合約建立者)
    fundingGoalInEthers: 募資額度, 爲了方便咱們僅募3個ether
    durationInMinutes: 募資時間
    finneyCostOfEachToken 每一個代幣的價格, 這裏爲了方便使用了單位finney及值爲:1 (1 ether = 1000 finney)
    addressOfTokenUsedAsReward: 代幣合約地址。
    如:

    本文使用的參數爲:
"0xc6f9ea59d424733e8e1902c7837ea75e20abfb49",3, 100, 1,"0xad8972e2b583f580fc52f737b98327eb65d08f8c"
  1. 參與人投資的時候實際購買衆籌合約代幣,全部須要先向合約預存代幣,代幣的數量爲:募資額度 / 代幣的價格 , 這裏爲:3 * 1000/1 = 3000 (當能也能夠大於3000)。
    向合約預存代幣可使用myetherwallet錢包,或在remix中從新加載代幣合約,執行代幣合約tranfer()函數進行代幣轉帳。如使用myetherwallet轉帳如圖:

  2. 參與人投資行爲便是向買衆籌合約轉帳,轉帳時,會執行Fallback回退函數(即無名函數)向其帳戶打回相應的代幣。

  3. safeWithdrawl() 能夠被參與人或收益人執行,若是融資不達標參與人可收回以前投資款,若是融資達標收益人能夠拿到全部的融資款。

擴展

上面是一個很正規的募資合約。接下來說兩個募資合約的擴展,如何實現無限募資合約及割韭菜合約。
這部份內容獨家發佈在個人小專欄區塊鏈技術

如何建立代幣發行代幣,如今也錄製了對應的視頻教程:經過代幣學以太坊智能合約開發,目前咱們也在招募體驗師,能夠點擊連接瞭解。

若是你在學習中遇到問題,歡迎到個人知識星球提問,做爲星球成員福利,成員可加入區塊鏈技術付費交流羣。

參考文檔

深刻淺出區塊鏈 - 系統學習區塊鏈,打造最好的區塊鏈技術博客。

相關文章
相關標籤/搜索