一、众筹项目
1.1 众筹规则
二、众筹合约实现
2.1 字段
pragma solidity ^0.4.26;
contract Funding{
string public pro_name;
uint256 public endtime;
uint256 public need_money;
uint256 public peo_money;
address public launch;
constructor(string pro_name1,uint256 endtime1,uint256 need_money1,uint256 peo_money1) public {
launch = msg.sender;
pro_name = pro_name1;
endtime = block.timestamp + endtime1;
peo_money = peo_money1;
need_money = need_money1;
}
function getName() public view returns (string){
return pro_name;
}
}
2.2 添加投资函数
function invest() public payable{
require(msg.value == 1000);
investors.push(msg.sender);
}
function getContractBalance() public view returns (uint256){
return address(this).balance;
}
function getInvestors() public view returns (address[]){
return investors;
}
2.3 发起人请求花费的结构体定义
enum appliStatue{
voting, approved, finish
}
struct application{
string spendReason;
address seller;
appliStatue statue;
uint256 approve;
uint256 cost;
mapping(address=>bool) isVotedMap;
}
2.4 众筹失败,原路退回资金
function refund() public {
require(msg.sender == launch);
for (uint256 i = 0;i < investors.length; i ++){
investors[i].transfer(supportMoney);
}
delete investors;
}
2.5 甲方创建花费请求
function createEat(string _spendReason, address _seller,uint256 _cost ) public {
Application memory myRequest = Application({
spendReason : _spendReason,
seller : _seller,
statue : AppliStatue.voting,
approve : 0,
cost :_cost
});
allApplication.push(myRequest);
}
2.6 投资人对花费请求进行投票
function voteRequest(uint256 i) public{
require(isVoter[msg.sender] == true);
Application storage app = allApplication[i];
require(app.isVotedMap[msg.sender] == false);
app.approve = app.approve+ 1;
app.isVotedMap[msg.sender] == true;
}
2.7 执行花费动作
- 判断投票是否过半
- 判断合约的钱是否大于请求的钱
- 将花费的钱转给商家
- 更新花费申请的状态
function startSpend(uint256 i) public{
Application storage app = allApplication[i];
require(app.approve * 2 > investors.length);
require(address(this).balance > app.cost);
app.seller.transfer(app.cost);
app.statue = AppliStatue.finish;
}
2.8 辅助函数
- 权限控制
- 返回投资人数
- 返回申请请求详细信息
- 返回众筹剩余时间
modifier onlyManager(){
require(msg.sender == launch);
_;
}
function getInvestNum() public view returns (uint256){
return investors.length;
}
function leftTime() public view returns (uint256){
return endtime - block.timestamp;
}
function detailApplication(uint256 i) public view returns (string, address, uint256, uint256, AppliStatue){
Application storage app = allApplication[i];
return (app.spendReason, app.seller, app.cost, app.approve, app.statue);
}
2.9 怎么快速检验是不是投资人
mapping (address=>bool) isVoter;
三、工厂合约
3.1工厂合约包含的内容
- 所有的合约
address[] - 我参加的众筹合约
mapping(address=>address[]) - 我参与的众筹合约
mapping(address=>address[]) - 平台管理员
address public FactoryManager;
address [] public allCrowdFunding;
mapping(address=>address[]) ownCrowdFunding;
mapping(address=>address[]) joinCrowdFunding;
3.2 创建众筹项目
function createCrowdFunding(string pro_name1,uint256 endtime1,uint256 need_money1,uint256 supportMoney1) public {
address funding = new Funding(pro_name1,endtime1,need_money1,supportMoney1);
allCrowdFunding.push(funding);
ownCrowdFunding[msg.sender].push(funding);
}
3.3 辅助函数
function getAllFunding() public view returns(address[]){
return allCrowdFunding;
}
function getAllCreatefunding() public view returns(address[]){
return ownCrowdFunding[msg.sender];
}
function fetAllJoinFunding() public view returns(address[]){
return joinCrowdFunding[msg.sender];
}
3.4 切换用户,创建的合约中的创建人的地址是合约管理者的地址
function createCrowdFunding(string pro_name1,uint256 endtime1,uint256 need_money1,uint256 supportMoney1) public {
address funding = new Funding(pro_name1,endtime1,need_money1,supportMoney1,msg.sender);
allCrowdFunding.push(funding);
ownCrowdFunding[msg.sender].push(funding);
}
-合约工厂
constructor(string pro_name1,uint256 endtime1,uint256 need_money1,uint256 supportMoney1, address launch1) public {
launch = launch1;
pro_name = pro_name1;
endtime = block.timestamp + endtime1;
supportMoney = supportMoney1;
need_money = need_money1;
}
3.5 获取投资人参与的所有的众筹
mapping(address=>address[]) joinCrowdFunding;
- 合约中的invest()方法需要将加入的众筹加入上述合约工厂中的joinCrowdFunding字段,但是mapping类型的数据无法通过合约工厂的function createCrowdFundin()函数传递
解决方法:通过中间合约来解决。
3.6 显示用户所有的参与的众筹
pragma solidity ^0.4.26;
contract JoinFundingContract{
mapping(address=>address[]) public joinFunding;
function getJoinFunding(address _user) public view returns (address[]){
return joinFunding[_user];
}
function setJoinFunding(address _user, address _fund) public {
joinFunding[_user].push(_fund);
}
}
function invest() public payable{
require(msg.value == 1000);
investors.push(msg.sender);
isVoter[msg.sender] = true;
joinFundingContract.setJoinFunding(msg.sender, this);
}
function getAllJoinFunding() public view returns (address[]){
return joinFundingContract.getJoinFunding(msg.sender);
}
|