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