This tutorial is meant for those with a basic knowledge of Ethereum and smart contracts, who have some knowledge of Solidity.
The purpose of building this blog is to write down the detailed operation history and my memo for learning the dApps and solidity programming.
If you are also interested and want to get hands dirty, just follow these steps below and have fun!~
Prerequisites
The create2 opcode gives us the ability to predict the contract address where a contract will be deployed. This opens up lots of possibilities to improve user onboarding and scalability.
contract overview
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.14;
//Use Create2 to know contract address before it is deployed.
contract DeployWithCreate2 {
address public owner;
constructor(address _owner) {
owner = _owner;
}
}
contract Create2Factory {
event Deploy(address addr);
// to deploy another contract using owner address and salt specified
function deploy(uint _salt) external {
DeployWithCreate2 _contract = new DeployWithCreate2{
salt: bytes32(_salt) // the number of salt determines the address of the contract that will be deployed
}(msg.sender);
emit Deploy(address(_contract));
}
// get the computed address before the contract DeployWithCreate2 deployed using Bytecode of contract DeployWithCreate2 and salt specified by the sender
function getAddress(bytes memory bytecode, uint _salt) public view returns (address) {
bytes32 hash = keccak256(
abi.encodePacked(
bytes1(0xff), address(this), _salt, keccak256(bytecode)
)
);
return address (uint160(uint(hash)));
}
// get the ByteCode of the contract DeployWithCreate2
function getBytecode(address _owner) public pure returns (bytes memory) {
bytes memory bytecode = type(DeployWithCreate2).creationCode;
return abi.encodePacked(bytecode, abi.encode(_owner));
}
}
We use Create2Factory to deploy the contract DeployWithCreate2. First we get the byteCode of the contract DeployWithCreate2 using the function
getBytecode
, and then we usebyteCode
and owner-specifiedsalt
to compute the address of contract DeployWithCreate2. Finally we use functiondeploy
to deploy the contract DeployWithCreate2 to see the actuall contract address.
Contract testing steps
getBytecode
getAddress
deploy with the same salt value
check logs
logs [
{
"from": "0xDA0bab807633f07f013f94DD0E6A4F96F8742B53",
"topic": "0x55ea6c6b31543d8e2ec6a72f71a79c0f4b72ed0d4757172b043d8f4f4cd84848",
"event": "Deploy",
"args": {
"0": "0x0B4f6a49C6a97B5dBB62F8A594cDefe5EabB4658",
"addr": "0x0B4f6a49C6a97B5dBB62F8A594cDefe5EabB4658"
}
}
Git repository
Welcome to visit the Git repo for source code (Create2.sol or Example-44), and feel free to reach me by leaving a message below or via email found in my profile.
Thank you!
hyc0812 / solidity-essentials
Solidity programming baby examples...
Solidity-Baby Steps...
The best path for earning Solidity is to approach examples.
Here are baby examples. Typing one-by-one is recommended.
References:
MyBlog explanation for using EnglishAuction and testing.
Example-1
updateBalance & getBalance
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract MyLedger {
mapping(address => uint) public balances;
function updateBalance(uint newBal) public {
balances[msg.sender] = newBal;
}
function getBalance() public view returns(uint) {
return balances[msg.sender];
}
}
Example-2
Inherited from Square
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
import "@openzeppelin/contracts/utils/Strings.sol";
contract Shape {
uint height;
uint width;
constructor(uint _height, uint _width) {
height = _height;
width = _width;
}
}
contract Square is Shape {
constructor(uint h, uint w) Shape(h, w) {}
function
…References
https://docs.openzeppelin.com/cli/2.8/deploying-with-create2
https://www.youtube.com/watch?v=883-koWrsO4&list=PLO5VPQH6OWdVQwpQfw9rZ67O6Pjfo6q-p&index=58
https://blog.openzeppelin.com/getting-the-most-out-of-create2/
Top comments (0)