本文首发于深刻浅出区块链社区 原文连接:如何经过以太坊智能合约来进行众筹(ICO)原文已更新,请读者前往原文阅读app
前面咱们有两遍文章写了如何发行代币,今天咱们讲一下如何使用代币来公开募资,即编写一个募资合约。函数
本文所讲的代币是使用以太坊智能合约建立,阅读本文前,你应该对以太坊、智能合约有所了解,若是你还不了解,建议你先看以太坊是什么学习
先简单说下众筹的概念:通常是这样的,我一个很是好的想法,可是我没有钱来作这事,因而我把这个想法发给你们看,说:我作这件事须要5百万,你们有没有兴趣投些钱,若是你们在30天内投够了5百万我就开始作,到时你们都是原始股东,若是募资额不到5百万,你们投的钱就还给你们。区块链
如今ICO众筹已经被各路大佬拿来割韭菜而被玩坏了(无论有无达标,都把钱卷走)。ui
其实区块链技术本事很是适合解决众筹的信任问题,借助于智能合约,能够实现当募资额完成时,募资款自动打到指定帐户,当募资额未完成时,可退款。这个过程不须要看众筹大佬的人品,不用依靠第三方平台信用担保。code
传统的众筹在参与以后一般不容易交易(参与以后没法转给其余人),而经过用代币来参与众筹,则很容易进行交易,众筹的参与人可随时进行买卖,待众筹项目实施完成的时候,彻底根据代币持有量进行回馈。blog
举个例子说明下,你们会更容易理解,有这一个众筹:A有技术作一个能监测健康的指环,为此向公众募资200百万,募资时100块对应一个代币,约定在指环上市以后,代币的持有人能够用一个代币来兑换一个指环。而指环的研发周期是一年,所以在指环还未上市的一年里,众筹的参与人能够随时交易所持有的代币。token
接下来就看看如何实现一个众筹智能合约。事件
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; } } } }
在部署这个合约以前,咱们须要先部署一个代币合约,请参考一步步教你建立本身的数字货币。ip
"0xc6f9ea59d424733e8e1902c7837ea75e20abfb49",3, 100, 1,"0xad8972e2b583f580fc52f737b98327eb65d08f8c"
参与人投资的时候实际购买众筹合约代币,因此须要先向合约预存代币,代币的数量为:募资额度 / 代币的价格 , 这里为:3 * 1000/1 = 3000 (当能也能够大于3000)。 向合约预存代币可使用myetherwallet钱包,或在remix中从新加载代币合约,执行代币合约tranfer()函数进行代币转帐,转帐的地址就是咱们建立合约的地址。如使用myetherwallet转帐如图:
投资人向众筹合约转帐(发送以太币)便是参与众筹行为,转帐时,会执行Fallback回退函数(即无名函数)向其帐户打回相应的代币。
safeWithdrawl() 能够被参与人或收益人调用,若是融资不达标参与人可收回以前投资款,若是融资达标收益人能够拿到全部的融资款。
上面是一个很正规的募资合约。接下来说两个募资合约的扩展,如何实现无限募资合约及割韭菜合约。 这部份内容独家发布在个人小专栏区块链技术
若是你在学习中遇到问题,欢迎到个人**知识星球**提问,做为星球成员福利,成员可加入区块链技术付费交流群。
☛ 深刻浅出区块链 - 系统学习区块链,打造最好的区块链技术博客。
☛ 个人知识星球为各位解答区块链技术问题,欢迎加入讨论。
☛ 关注公众号“深刻浅出区块链技术”第一时间获取区块链技术信息。