3.25 实战智能合约众筹1

这次我们来看看怎么实现以太坊的众筹智能合约案例,首先我们了解一下下面的概念 
1、什么是ICO? 
ICO是以初始产生的数字加密货币作为投资回报的一种筹措资金的方式,它的概念源自证券界的Initial Public Offering(IPO,首次公开发行)。

  相较于传统意义上的IPO,ICO具有可以缩短投融资链、降低投融资门槛、流动性佳、全球性投资等优势。常见的ICO里,数字货币和区块链项目向早期爱好者出售项目代币。项目团队通过ICO获取技术开发和市场拓展资金;而项目爱好者通过ICO支持项目,同时也可在对应代币进入交易市场后选择交易退出。

  当你有一个好的想法,需要大家的资金来资助你。你可以使用众筹合约来发起请求捐款。众筹合约的基本思路是,你设定一个众筹目标,在达到目标的最后期限时,如果没有完成众筹,所有的捐款将被退回,因此减少了捐赠者的风险。由于代码是开放的,可被审计的,也就不需要一个集中的、可信的平台来担保,每个捐款的人,只需要支付一定的gas。

2、众筹的奖励-代币 
  一般来说,那些筹集资金的人在资金筹集和资金管理不善之后,根本就不能说这笔钱是如何使用的,这常常导致项目根本无法交付任何东西。这时我们可以使用智能合适中投票的方式来做决定,这样对所有人都是公平的。(这个例子不在本文中介绍,可以参考链接)

  在下面的例子里,我们在众筹中,主要解决两个重要的问题:如何管理和保存用于奖励的代币;筹集奖金后如何使用。

  传统的众筹或奖励记录通常有一个中央数据库,来保存、跟踪所有捐助者的过程:谁错过了众筹的最后期限了,谁在众筹过程中捐赠了多少等。与之相反,在区块链中我们将以分散的方式来做这件事,只需创建一个标记来记录众筹的每一条记录、奖励了多少代币,后面每个捐赠者都可以得到一个他们可以交易、出售或保留的代币。如果要给予实物奖励,生产者只需要交换实物产品的代币。捐赠者也可以将代币做为纪念品保留,不管这个众筹项目有没有达到它的目标,都可以收藏。 
3、 接下来看看代码实现

pragma solidity ^0.4.18;
interface token {
    function transfer(address receiver, uint amount);
}
contract Crowdsale {
    /*存储结构*/
    uint public fundingGoal; // 众筹目标
    address public beneficiary; // 收款人地址
    uint public deadline; // 众筹截至时间
    uint public amountRaised; // 参与数量
    uint public price; // 众筹发放的代币与以太坊的兑换比例
    token public tokenReward; // 要卖的token
    // 状态
    // 1 判断是否已经达成众筹目标
    bool public fundingGoalReached = false;
    // 2 判断截至时间到了没有
    bool public crowdsaleClosed = false;
    // 地址对应余额
    mapping(address => uint) public balanceOf;
    /*事件*/
    event LogAmount(uint amount);
    // 达成众筹目标需要触发的时间
    event GoalReached(address recipient, uint totalAmountRaised);
    event FundTransfer(address backer, uint amount, bool isContribution);
    /*功能函数*/
    // 构造函数
    function Crowdsale(
        // 收款人地址
        address ifSuccessfulSendTo,
        // 众筹目标
        uint fundingGoalInEthers,
        // 持续时间
        uint durationInMinites,
        // 相对于以太坊的价值
        uint weiCostOfEtchToken,
        // 传入已经发布的合约地址,来创建实例
        address addressOfTokenUsedAsReward
    ){
        ifSuccessfulSendTo = beneficiary;
        fundingGoal = fundingGoalInEthers * 1 ether;
        deadline = now + durationInMinites * 1 minutes;
        price = weiCostOfEtchToken * 1 wei;
        tokenReward = token(addressOfTokenUsedAsReward);
    }
    // 收款的合约必须包含有payable的回退函数
    function() payable {
        require(!crowdsaleClosed); // 确保众筹还没关闭
        uint amount = msg.value;
        amountRaised += amount; // 更新已经得到的众筹额度
        balanceOf[msg.sender] += amount;
        LogAmount(amount);
        tokenReward.transfer(msg.sender, 1000*(amount/price)); // 转账
        FundTransfer(msg.sender, amount, true);
    }
    // 修改器
    modifier afterDeadline(){
        if(now > deadline) _; // 检查众筹是否已经截至
    }
    // 判断众筹是否完成了融资的目标
    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 {
                fundingGoalReached = false;
            }
        }
    }
}

 

 

  • 学院Go语言视频主页
    https://edu.csdn.net/lecturer/1928

  • 清华团队带你实战区块链开发

  • 扫码获取海量视频及源码   QQ群:721929980

你可能感兴趣的:(区块链)