salt
nonce,也可以自己生成
create
address = hash(msg.sender,nonce)
create2
deploymentData= creationCode+constructorArgs
address =hash(“0xff”,msg.sender,nonce,hash(deploymentData))
可以不用部署直接可以获取合约地址
address(this)
相当于A合约中调用了B(uint)的构造方法创建了B合约
// SPDX-License-Identifier: MIT pragma solidity 0.8.0; contract A{ function test8() public pure returns (bytes4 a,bytes4 b){ //获取methodId //合约名字,方法名字 a = B.getBalance.selector; b = bytes4(keccak256(abi.encodePacked("getBalance()"))); } function testCreate2(uint _number) public returns (address bAddr){ //获取createCode bytes memory cCode = type(B).creationCode; //构造方法参数编码 bytes memory args = abi.encode(_number); //生成bytescode bytes memory deploymentData = abi.encodePacked(cCode,args); //利用参数生成salt bytes32 salt = keccak256(abi.encodePacked(_number)); assembly { bAddr := create2(0x0, add(0x20, deploymentData), mload(deploymentData), salt) } require(address(bAddr) != address(0), "Create2 call failed"); } // 提前计算合约地址 function calculateAddr(uint _number) public view returns(address bAddr){ //获取createCode bytes memory cCode = type(B).creationCode; //构造方法参数编码 bytes memory args = abi.encode(_number); //生成bytescode bytes memory deploymentData = abi.encodePacked(cCode,args); //利用参数生成salt bytes32 salt = keccak256(abi.encodePacked(_number)); // 计算合约地址方法 hash() bytes memory params = abi.encodePacked( bytes1(0xff), address(this), salt, keccak256(deploymentData) ); bytes32 params2 = keccak256(params); uint params3 = uint(params2); bAddr = address(uint160(params3)); } } contract B{ uint public b = 10; constructor(uint _b) public{ b = _b; } event anTest(uint indexed addr) anonymous; function getBalance() view public returns (uint){ return address(this).balance; } receive () payable external{ emit anTest(msg.value); } fallback () payable external{ } }
clone-factory
// SPDX-License-Identifier: MIT pragma solidity 0.8.0; contract TestA{ uint public a; constructor(){} function setA(uint _a)public { a = _a; } function getAB(uint b) view public returns (uint c){ c= a+b; } } contract ContractFactory{ address public implementation; bytes public code; bytes32 public codeHash; event ProxyCreated(address indexed _address, bytes32 _salt); event ImplementationChanged(address indexed _implementation, bytes32 _codeHash, bytes _code); function getSalt(uint _number) pure public returns (bytes32){ return keccak256(abi.encodePacked(_number)); } function setImplementation(address _implementation) public { require( _implementation != address(0), "ContractFactory#_setImplementation: INVALID_IMPLEMENTATION" ); // Adapted from https://github.com/optionality/clone-factory/blob/32782f82dfc5a00d103a7e61a17a5dedbd1e8e9d/contracts/CloneFactory.sol code = abi.encodePacked( hex"3d602d80600a3d3981f3363d3d373d3d3d363d73", _implementation, hex"5af43d82803e903d91602b57fd5bf3" ); codeHash = keccak256(code); implementation = _implementation; emit ImplementationChanged(implementation, codeHash, code); } function getAddress(uint _number) public view returns (address _addr) { return address( uint160(uint256( keccak256( abi.encodePacked( bytes1(0xff), address(this), getSalt(_number), codeHash ) ) )) ); } function createProxy(uint _number, bytes memory _data) public virtual returns (address addr) { bytes memory slotcode = code; // solium-disable-next-line security/no-inline-assembly bytes32 salt = getSalt(_number); assembly { addr := create2(0, add(slotcode, 0x20), mload(slotcode), salt) } require(addr != address(0), "ContractFactory#createProxy: CREATION_FAILED"); emit ProxyCreated(addr, salt); if (_data.length > 0) { (bool success,) = addr.call(_data); require(success, "ContractFactory#createProxy: CALL_FAILED"); } } }
shr shl使用 两个值生成唯一的值,通过唯一值获取对应的两个值
function encodeTokenId(uint256 _itemId, uint256 _issuedId) public pure returns (uint256 id) { require(_itemId <= MAX_ITEM_ID, "encodeTokenId: INVALID_ITEM_ID"); require(_issuedId <= MAX_ISSUED_ID, "encodeTokenId: INVALID_ISSUED_ID"); // solium-disable-next-line security/no-inline-assembly assembly { id := or(shl(ISSUED_ID_BITS, _itemId), _issuedId) } } /** * @notice Decode token id * @dev itemId (`itemIdBits` bits) + issuedId (`issuedIdBits` bits) * @param _id - token id * @return itemId uint256 of the item id * @return issuedId uint256 of the issued id */ function decodeTokenId(uint256 _id) public pure returns (uint256 itemId, uint256 issuedId) { uint256 mask = MAX_ISSUED_ID; // solium-disable-next-line security/no-inline-assembly assembly { itemId := shr(ISSUED_ID_BITS, _id) issuedId := and(mask, _id) } }