EIP1167创建最小合约代理的应用及其原理

一、背景

本文主要是想写一写以太坊EIP1167的内容,应为在网上没有找到比较好的讲解,EIP1167还是非常好的提案,对于批量创建智能合约非常有用

二、应用

2.1应用场景

比如我们需要一个合约工厂创建打量同质化的合约,就可以这样写

pragma solidity ^0.4.15;
import "./Factory.sol";
import "./MultiSigWallet.sol";

contract MultiSigWalletFactory is Factory {

    /*
     * Public functions
     */
    /// @dev Allows verified creation of multisignature wallet.
    /// @param _owners List of initial owners.
    /// @param _required Number of required confirmations.
    /// @return Returns wallet address.
    function create(address[] _owners, uint _required)
        public
        returns (address wallet)
    {
        wallet = new MultiSigWallet(_owners, _required);
        register(wallet);
    }
}

但是这样写会创建大量重复逻辑代码的合约,如何将这些逻辑相同的代码进行复用呢?可以这样

contract WalletFactory is CloneFactory {
   address Template = 0x692a70D2e424a56D2C6C27aA97D1a86395877b3A;
   function createWallet() external returns (address newWallet) {
        newWallet = createClone(Template);
    }
}

三、原理

首先我们来看看createClone的源码

contract CloneFactory {

  function createClone(address target) internal returns (address result) {
    bytes20 targetBytes = bytes20(target);
    assembly {
      let clone := mload(0x40) 
      mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
      mstore(add(clone, 0x14), targetBytes)
      mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
      result := create(0, clone, 0x37)
    }
  }
}

是不是完全看不懂,其实就是创建了一个合约代理
用文字说就是
接收请求数据
将请求数据通过 DELEGATECALL 指令传递给目标实现合约。
得到合约调用的返回数据
将结果返回给调用者或者将交易回滚
那为什么上面那段代码就可以时间这种功能呢?
这就涉及到EVM字节码技术
我们一步一步来

3.1 接收请求数据

我们看看需要哪些指令才能将call中的数据获取到

Code 指令 虚拟机栈 虚拟机内存
36 CALLDATASIZE calldatasize
3d RETURNDATASIZE 0 calldatasize
3d RETURNDATASIZE 0 0 calldatasize
37 CALLDATACOPY

这个过程就构成了363d3d37

3.1 接收请求数据

你可能感兴趣的:(区块链开发solidity)