Welcome to the world of Ethereum smart contracts! Today, we’re diving into the magical realm of the CREATE2 opcode, introduced in the Constantinople update. This tutorial will guide you on how to predetermine a smart contract address off-chain and deploy it using CREATE2 directly from another smart contract. Let’s get started!
What is CREATE2?
CREATE2 is a special opcode that allows you to create smart contracts at deterministic addresses, which means you can predict the address before deploying it. This provides preciseness and helps with things like pre-funding contracts before they are created.
Setup and Contract Implementation
We will be working with two contracts: Factory.sol for deploying other contracts, and Account.sol which will be instantiated using the Factory.
Factory.sol
pragma solidity ^0.4.99 <=0.6.0;
contract Factory {
event Deployed(address addr, uint256 salt);
function deploy(bytes memory code, uint256 salt) public {
address addr;
assembly {
addr := create2(0, add(code, 0x20), mload(code), salt)
}
if iszero(extcodesize(addr)) {
revert(0, 0)
}
emit Deployed(addr, salt);
}
}
Here’s a quick analogy: think of the Factory contract as a custom bakery that can create a unique cake (smart contract) whenever someone gives it a specific recipe (bytecode) and a secret ingredient (salt).
Account.sol
pragma solidity ^0.4.99 <=0.6.0;
contract Account {
address public owner;
constructor(address payable _owner) public {
owner = _owner;
}
function setOwner(address _owner) public {
require(msg.sender == owner);
owner = _owner;
}
function destroy(address payable recipient) public {
require(msg.sender == owner);
selfdestruct(recipient);
}
function() payable external {}
}
Using our bakery analogy again, the Account contract is like a special cake that has an owner (the person that created it) who can change the recipe or even dispose of it when required.
Steps for Deterministically Computing a Smart Contract Address
-
Compute the Contract Address Off-chain: Call the function
buildCreate2Address
to get the future address. - Send ETH to the Address: You can send Ethereum to the computed address even if the contract isn’t deployed.
- Deploy the Contract: Use the Factory to deploy the Account contract when you’re ready.
Code Implementation
Here’s how to compute and deploy using JavaScript:
const computedAddr = buildCreate2Address(factoryAddress, numberToUint256(salt), bytecode);
console.log(await isContract(computedAddr)); // false
const factory = new web3.eth.Contract(factoryAbi, factoryAddress);
const result = await factory.methods.deploy(bytecode, salt).send({ from: account, gas: 4500000, gasPrice: 10000000000 });
const addr = result.events.Deployed.returnValues.addr.toLowerCase();
console.log(computedAddr == addr); // true
console.log(await isContract(computedAddr)); // true
Troubleshooting
If you encounter issues while deploying, consider the following:
- Ensure that you are using the correct version of Solidity.
- Check the gas limit; it should be sufficiently high to accommodate the deployment.
- Make sure your Ethereum address is correctly configured and has enough funds.
For more insights, updates, or to collaborate on AI development projects, stay connected with fxis.ai.
Final Thoughts
CREATE2 simplifies the deployment process by allowing a contract to be funded before it even exists on-chain. As you delve deeper into the world of Ethereum, embracing techniques like CREATE2 can enhance your smart contract development experience significantly.
At fxis.ai, we believe that such advancements are crucial for the future of AI, as they enable more comprehensive and effective solutions. Our team is continually exploring new methodologies to push the envelope in artificial intelligence, ensuring that our clients benefit from the latest technological innovations.
Further Resources
For detailed documentation regarding CREATE2 and its benefits, check out the following resources:
Credits
Special thanks to @stanislaw-glogowski for the initial implementation example.