一、背景
本文次要是想写一写以太坊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