Structure
- Source Bytecode: combined from the contract source code
- Constructor Arguments Bytecode (optional): encoded from the constructor • parameter. It’s empty by default
constructor()
- Full Contract Creation Bytecode = concat (
Source Bytecode
,Constructor Arguments Bytecode
) - Calculate the Input Data for contract creation transaction = concat (
Init Code
,Full Contract Creation Bytecode
)- Where
Init Code
(Optional) = Create code, or function hash, function param
- Where
Example
- DETERMINISTIC_DEPLOYER:
0x4e59b44847b379578588920cA78FbF26c0B4956C
- Get
Contract Creation Bytecode
: Go to contract tab https://etherscan.io/address/0x4e59b44847b379578588920ca78fbf26c0b4956c#code- Data: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3
- Constructor Arguments Bytecode: empty
- Get
Input Data
: Go to transaction tx https://etherscan.io/tx/0xeddf9e61fb9d8f5111840daef55e5fde0041f5702856532cdbb5a02998033d26- Data = Init Code + Contract bytecode
- Init Code = 0x604580600e600039806000f350fe which is the creation/deploy code
- Get
- ENTRY_POINT_V08:
0x4337084d9e255ff0702461cf8895ce9e3b5ff108
- Get
Contract Creation Bytecode
: Go to contract tab https://etherscan.io/address/0x4337084d9e255ff0702461cf8895ce9e3b5ff108#code- Data in Contract Creation Code (NOT Deployed Bytecode): 0x6101806040523461019557604051610018604082610199565b6007815260208101……ad1146c1c11fab88cce1fdaa4c4a64736f6c634300081c0033
- Constructor Arguments Bytecode: empty
- Get
Input Data
: Go to transaction tx https://etherscan.io/tx/0xae4eafd1fd17e03b5200f6e2ecad4f669b41d9ba3a4fa0018e92cde985b33129- Data = Init Code + Contract bytecode
- Init Code = 0x0a59dbff790c23c976a548690c27297883cc66b4c67024f9117b0238995e35e9 which is the
SALT
(32 bytes = 64 hex chars) param
- Get
- SIMPLE_ACCOUNT_FACTORY_V08:
0x13E9ed32155810FDbd067D4522C492D6f68E5944
- Get
Contract Creation Bytecode
: Go to contract tab https://etherscan.io/address/0x13e9ed32155810fdbd067d4522c492d6f68e5944#code- Data: 0x60c0806040523461010d57602081612433803803809161001f8285610138…0df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a000000000000000000000000004337084d9e255ff0702461cf8895ce9e3b5ff108
- Constructor Arguments Bytecode: 0000000000000000000000004337084d9e255ff0702461cf8895ce9e3b5ff108
- The constructor is
constructor(IEntryPoint _entryPoint)
and the _entryPoint = 0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108
- The constructor is
- Get
Input Data
: Go to transaction tx https://etherscan.io/tx/0x9d6eda1cf3fc37b7e0c0ec258f2f9c51454f179b6c1b12a3204470fd71492144- Data = Init Code + Contract bytecode
- Init Code = 0x0000000000000000000000000000000000000000000000000000000000000000 which is the
SALT
(32 bytes = 64 hex chars) param
- Get
Deploy
There are 2 ways for deployment: Normal CREATE and CREATE2
- INIT wallet client EOA signer:
const walletClient = createWalletClient({
account: mnemonicToAccount( "" ),
chain: mainnnet,
transport: http(process.env.RPC_URL),
});
Create contract with Normal CREATE
: Create from EOA contract.
- Deploy transaction from
Input Data
const config = {
data,
gas,
nonce: nonce++,
chain,
};
await walletClient.sendTransaction(config);
- Calculate the contract address:
address = getContractAddress({
from: walletClient.account.address,
nonce: BigInt(nonce - 1),
});
Create contract with CREATE2
: Create a contract from another contract.
- Deploy transaction from
Input Data
. The EOA signer will send a transaction to the DETERMINISTIC contract with a creation bytecode, and new contract will be created under DETERMINISTIC (not EOA)
const config = {
data,
gas,
nonce: nonce++,
chain,
to: deterministicDeployer
};
await walletClient.sendTransaction(config);
- Calculate the contract address:
address = keccak256(0xFF ++ deployer_address ++ salt ++ keccak256(init_code))[12:]
const inputData = data.substring(2);
const salt: Hex = `0x${inputData.substring(0, 64)}`; // 32 bytes = 64 hex characters
const creationByteCode: Hex = `0x${inputData.substring(64)}`;
address = getCreate2Address({
from: deterministicDeployer,
salt: salt,
bytecodeHash: keccak256(creationByteCode),
});
Verify deployment: check if the contract has code
const verifyDeployed = async (addresses: Address[]) => {
for (const address of addresses) {
const bytecode = await client.getCode({
address,
});
if (!bytecode || bytecode === '0x') {
console.log(`CONTRACT ${address} NOT DEPLOYED!!!`);
// process.exit(1);
}
}
};