首页 > 解决方案 > 如何为当前未知的合约编写合约调用?

问题描述

有一个合约叫做投票。sol 并且它可以接受提案并对这些提案进行投票。

我希望能够在人们创建提案时指定投票完成后将发生的调用。

调用应具有要调用的合约地址、要调用的函数以及要传递给函数的参数。

但是,在创建投票时,我们不知道这些(也不是称为 ABI 的合约)。仅当我们稍后创建提案时。

有没有办法做到这一点?

标签: ethereumsolidity

解决方案


你可以提前创建一个代理合约,在 Vol.sol 中固定它的地址,然后通过这个代理合约转移你需要的智能合约的地址。除了通过代理的地址,还可以传递ABI规范。如果您使用 bytes32 数组将参数传递给 Vol-contract 方法,那么您可以传递任意数量的不同类型的参数。

  1. 您部署合约代理并保存它的地址
  2. 在合约 VolUser 中使用代理地址初始化 public ProxyAddr
  3. 后期,在部署合约 Vol 之后,您调用 Proxy 方法 SetVol 并使用值 (Vol-address, "AnyFunction(bytes32[])"
  4. 调用 VolUser 合约的 CallVol 方法时,会调用 Vol 合约的 AnyFunction 方法。
    pragma solidity >=0.5.8 <0.6.0;
    
    contract Proxy
    {
    
        address  Owner ;
    
        address  VolAddr ;
         string  VolABI ;
    
    
       constructor() public
       {
            Owner=tx.origin ;
       }
    
       function SetVol(address VolAddr_, string memory VolABI_) public
       {
           if(tx.origin!=Owner)  require(false) ;
    
              VolAddr=VolAddr_ ;
              VolABI =VolABI_ ;
       }
    
       function GetVol() public view returns (address, string memory retVal)
       {
           return(VolAddr, VolABI) ;
       }
    
    }
    
    
    contract VolUser
    {
    
        Proxy  ProxyAddr ;
    
    
       constructor() public
       {
       }
    
       function CallVol() public
       {
              address           VolAddr ;
               string    memory VolABI ;
              bytes32[2] memory VolPars ;
                 bool           result ;
    
            (VolAddr, VolABI)=ProxyAddr.GetVol() ;
    
                     VolPars[0]=               "ABC" ;
                     VolPars[1]=bytes32(uint256(321)) ;
                 
            (result,)=address(VolAddr).call.gas(0x300000).value(0)(abi.encodeWithSignature(VolABI, VolPars)) ;
    
       }
    
    }
    
    contract Vol
    {
    
       constructor() public
       {
       }
    
       function AnyFunction(bytes32[] memory VolPars_) public
       {
    //     ...
       }
    
    }

推荐阅读