IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 区块链 -> 以太坊 day (6) -> 正文阅读

[区块链]以太坊 day (6)

一、众筹项目

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);
        //这里一定是storage 类型
        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 {
       //这里的lanch不能是launch=msg.sender,不然会变成合约工场的管理者
        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;
//本合约的作用是为了维护一个显示用户参与合约的mapping
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);
    }
}
  • 用户参与众筹时,加入参与众筹mapping
 function invest() public  payable{
        require(msg.value == 1000);
        investors.push(msg.sender);
        //用map记录具有投资资格的人
        isVoter[msg.sender] = true;
        //msg.sender:当前用户的地址,this:当前合约的地址
        joinFundingContract.setJoinFunding(msg.sender, this);
    }
  • 查看用户参与的所有的众筹
  function getAllJoinFunding() public view returns (address[]){
        return joinFundingContract.getJoinFunding(msg.sender);
    }
  区块链 最新文章
盘点具备盈利潜力的几大加密板块,以及潜在
阅读笔记|让区块空间成为商品,打造Web3云
区块链1.0-比特币的数据结构
Team Finance被黑分析|黑客自建Token“瞒天
区块链≠绿色?波卡或成 Web3“生态环保”标
期货从入门到高深之手动交易系列D1课
以太坊基础---区块验证
进入以太坊合并的五个数字
经典同态加密算法Paillier解读 - 原理、实现
IPFS/Filecoin学习知识科普(四)
上一篇文章      下一篇文章      查看所有文章
加:2021-11-09 19:34:31  更:2021-11-09 19:35:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 22:49:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码