智能合约经典代码实战(三)——多人钱包管理合约

今天通过视频学习,写了一个多人钱包的合约,其本质与众筹差不太多,只不过多了一个需要达到一定数量参与者统一,交易才能执行。

视频链接如下:戳我看视频

pragma solidity >=0.4.0;
 
contract MultiSigWallet{
    
    struct Transaction {
        address to;
        uint value;
        bytes data;
        bool executed;
        mapping (address=>bool) isConfirmed;
        uint numCOnfirmations;
    }
    //投钱事件
    event Deposit(address indexed sender,uint amount,uint balance);
    //提交一个交易
    event SubmitTransaction(
        address indexed owner,
        uint indexed txIndex,
        address indexed to,
        uint value,
        bytes data
    ); 
    //用户赞成一个交易
    event ConfirmTransaction(address indexed owner,uint indexed txIndex);
    //参与用户执行某交易
    event ExecuteTransaction(address indexed owner,uint indexed txIndex);
    //撤回赞成
    event RevokeConfirmation(address indexed owner,uint indexed txIndex);
    //参与者数组
    address[] public owners;
    //通过一个交易需要的赞成数
    uint public numConfirmationRequired;
    //交易记录
    Transaction[] public transactions;
    //标记是否为参与投资者
    mapping(address=>bool)public isOwner;
    //部署创建
    constructor(address[] memory _owners, uint _numConfirmationRequired)public{
        require(_owners.length>0);
        require(_numConfirmationRequired>0&&_numConfirmationRequired<=_owners.length);
        for(uint i=0;i<_owners.length;i++){
            address owner=_owners[i];
            require(owner!=address(0));
            require(!isOwner[owner]);
            isOwner[owner]=true;
            owners.push(owner);
        }
        numConfirmationRequired=_numConfirmationRequired;
    }
    //修饰,只能参与者才能执行下列函数
    modifier onlyOwner(){
        require(isOwner[msg.sender]);
        _;
    }
    //修饰,判断是否存在该交易
    modifier txExists(uint _txIndex){
        require(_txIndex<transactions.length);
        _;
    }
    //修饰,判断是否已经执行该交易
    modifier notExecuted(uint _txIndex){
        require(!transactions[_txIndex].executed);
        _;
    }
    //修饰,判断该项目用户是否赞成
    modifier notConfirmed(uint _txIndex){
        require(!transactions[_txIndex].isConfirmed[msg.sender]);
        _;
    }
    //fallback函数
    function() payable external{
        emit Deposit(msg.sender,msg.value,address(this).balance);
    }
    //投资函数
    function deposit() payable external{
        emit Deposit(msg.sender,msg.value,address(this).balance);
    }
    
    //提交投资申请:接收方+代币数量+附带数据
    function submitTransaction(address _to,uint _value,bytes memory _data)public onlyOwner{
        uint txIndex=transactions.length;
        transactions.push(Transaction({
            to:_to,
            value:_value,
            data:_data,
            executed:false,
            numCOnfirmations:0
        }));
        emit SubmitTransaction(msg.sender,txIndex,_to,_value,_data);
    }
    //赞同某交易请求函数:交易代号
    function confirmTransaction(uint _txIndex)public onlyOwner txExists(_txIndex) notExecuted(_txIndex) notConfirmed(_txIndex){
        Transaction storage transaction=transactions[_txIndex];
        transaction.isConfirmed[msg.sender]=true;
        transaction.numCOnfirmations+=1;
        emit ConfirmTransaction(msg.sender,_txIndex);
    }
    //执行交易:交易代号
    function executeTransaction(uint _txIndex)public payable onlyOwner txExists(_txIndex) notExecuted(_txIndex){
        Transaction storage transaction=transactions[_txIndex];
        require(transaction.numCOnfirmations>=numConfirmationRequired);
        transaction.executed=true;
        (bool success,)=transaction.to.call.value(transaction.value)(transaction.data);
        require(success);
        emit ExecuteTransaction(msg.sender,_txIndex);
    }
    //撤回赞成交易:交易代号
    function revokeConfirmation(uint _txIndex)public onlyOwner txExists(_txIndex) notExecuted(_txIndex){
        Transaction storage transaction=transactions[_txIndex];
        transaction.isConfirmed[msg.sender]=false;
        transaction.numCOnfirmations-=1;
        emit RevokeConfirmation(msg.sender,_txIndex);
    }

}
//测试合约。用来测试执行交易时附带参数的,可以通过getData获取调用callMe的十六进制数据,将该数据附带发给该合约
contract TestContract{
    //通过i值判断是否执行成功
    uint public i;
    
    function callMe(uint j)public returns(bool){
        i+=j;
        return true;
    }
    
    function getData()public view returns(bytes memory){
        return abi.encodeWithSignature("callMe(uint256)",123);
    }
}

 

posted @ 2021-10-27 14:45  爱做梦的7ixia  阅读(336)  评论(0)    收藏  举报