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)
}
}