Skip to content

Latest commit

 

History

History
131 lines (87 loc) · 14.2 KB

VADD.md

File metadata and controls

131 lines (87 loc) · 14.2 KB

VADD (Vanity Address / Deterministic Deployment)

Introduction

This document will explain how to generate a vanity address for a contract, and how to deploy a contract to a specific address, across different networks.

Seaport Factory

This approach uses the Seaport Factory contract to deploy a contract to a specific address. This contract is already deployed in multiple networks, such as mainnet, goerli, sepolia, polygon, mumbai, arbitum, etc.

The contract address is: 0x0000000000ffe8b47b3e2130213b802212439497

You can check the list of networks where it is deployed here.

Also you can check if the seaport factory is deployed in a specific network by running the following command:

yarn hardhat checkFactory --network <network>

In case you want to use it in a different network, you will have to deploy it yourself. You can find find the documentation here. Note that you don't need to do this if you are using one of the networks listed above.

Here are the steps in case the documentation is taken down:

  • Define the $RPC_URL variable with the RPC URL of the network you want to deploy the Factory to.
  • Define the $PK variable with the private key of the account you want to deploy the Factory from (will need to have enough funds to pay for the deployment).
  • Run the following commands:
  1. Send 0.01 Ether to the KEYLESS_CREATE2_DEPLOYER_ADDRESS
cast send --rpc-url ${RPC_URL} --value 0.01ether --private-key ${PK} 0x4c8D290a1B368ac4728d83a9e8321fC3af2b39b1
  1. Create the KEYLESS_CREATE2_ADDRESS by submitting this pre-signed transaction:
cast publish --rpc-url ${RPC_URL} 0xf87e8085174876e800830186a08080ad601f80600e600039806000f350fe60003681823780368234f58015156014578182fd5b80825250506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222
  1. Create the INEFFICIENT_IMMUTABLE_CREATE2_FACTORY_ADDRESS by submitting:
cast send --rpc-url ${RPC_URL} --private-key ${PK} 0x7a0d94f55792c434d74a40883c6ed8545e406d12 0x608060405234801561001057600080fd5b50610833806100206000396000f3fe60806040526004361061003f5760003560e01c806308508b8f1461004457806364e030871461009857806385cf97ab14610138578063a49a7c90146101bc575b600080fd5b34801561005057600080fd5b506100846004803603602081101561006757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166101ec565b604080519115158252519081900360200190f35b61010f600480360360408110156100ae57600080fd5b813591908101906040810160208201356401000000008111156100d057600080fd5b8201836020820111156100e257600080fd5b8035906020019184600183028401116401000000008311171561010457600080fd5b509092509050610217565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561014457600080fd5b5061010f6004803603604081101561015b57600080fd5b8135919081019060408101602082013564010000000081111561017d57600080fd5b82018360208201111561018f57600080fd5b803590602001918460018302840111640100000000831117156101b157600080fd5b509092509050610592565b3480156101c857600080fd5b5061010f600480360360408110156101df57600080fd5b508035906020013561069e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205460ff1690565b600083606081901c33148061024c57507fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008116155b6102a1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260458152602001806107746045913960600191505060405180910390fd5b606084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604051855195965090943094508b93508692506020918201918291908401908083835b6020831061033557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016102f8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905260408051929094018281037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00183528085528251928201929092207fff000000000000000000000000000000000000000000000000000000000000008383015260609890981b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602183015260358201969096526055808201979097528251808203909701875260750182525084519484019490942073ffffffffffffffffffffffffffffffffffffffff81166000908152938490529390922054929350505060ff16156104a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603f815260200180610735603f913960400191505060405180910390fd5b81602001825188818334f5955050508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461053a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260468152602001806107b96046913960600191505060405180910390fd5b50505073ffffffffffffffffffffffffffffffffffffffff8116600090815260208190526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790559392505050565b6000308484846040516020018083838082843760408051919093018181037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001825280845281516020928301207fff000000000000000000000000000000000000000000000000000000000000008383015260609990991b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166021820152603581019790975260558088019890985282518088039098018852607590960182525085519585019590952073ffffffffffffffffffffffffffffffffffffffff81166000908152948590529490932054939450505060ff909116159050610697575060005b9392505050565b604080517fff000000000000000000000000000000000000000000000000000000000000006020808301919091523060601b6021830152603582018590526055808301859052835180840390910181526075909201835281519181019190912073ffffffffffffffffffffffffffffffffffffffff81166000908152918290529190205460ff161561072e575060005b9291505056fe496e76616c696420636f6e7472616374206372656174696f6e202d20636f6e74726163742068617320616c7265616479206265656e206465706c6f7965642e496e76616c69642073616c74202d206669727374203230206279746573206f66207468652073616c74206d757374206d617463682063616c6c696e6720616464726573732e4661696c656420746f206465706c6f7920636f6e7472616374207573696e672070726f76696465642073616c7420616e6420696e697469616c697a6174696f6e20636f64652ea265627a7a723058202bdc55310d97c4088f18acf04253db593f0914059f0c781a9df3624dcef0d1cf64736f6c634300050a0032
  1. Create the IMMUTABLE_CREATE2_FACTORY_ADDRESS contract at 0x0000000000ffe8b47b3e2130213b802212439497 by submitting:
cast send --rpc-url ${RPC_URL} --private-key ${PK} 0xcfa3a7637547094ff06246817a35b8333c315196 0x64e030870000000000000000000000000000000000000000f4b0218f13a6440a6f02000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000853608060405234801561001057600080fd5b50610833806100206000396000f3fe60806040526004361061003f5760003560e01c806308508b8f1461004457806364e030871461009857806385cf97ab14610138578063a49a7c90146101bc575b600080fd5b34801561005057600080fd5b506100846004803603602081101561006757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166101ec565b604080519115158252519081900360200190f35b61010f600480360360408110156100ae57600080fd5b813591908101906040810160208201356401000000008111156100d057600080fd5b8201836020820111156100e257600080fd5b8035906020019184600183028401116401000000008311171561010457600080fd5b509092509050610217565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561014457600080fd5b5061010f6004803603604081101561015b57600080fd5b8135919081019060408101602082013564010000000081111561017d57600080fd5b82018360208201111561018f57600080fd5b803590602001918460018302840111640100000000831117156101b157600080fd5b509092509050610592565b3480156101c857600080fd5b5061010f600480360360408110156101df57600080fd5b508035906020013561069e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205460ff1690565b600083606081901c33148061024c57507fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008116155b6102a1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260458152602001806107746045913960600191505060405180910390fd5b606084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604051855195965090943094508b93508692506020918201918291908401908083835b6020831061033557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016102f8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905260408051929094018281037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00183528085528251928201929092207fff000000000000000000000000000000000000000000000000000000000000008383015260609890981b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602183015260358201969096526055808201979097528251808203909701875260750182525084519484019490942073ffffffffffffffffffffffffffffffffffffffff81166000908152938490529390922054929350505060ff16156104a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603f815260200180610735603f913960400191505060405180910390fd5b81602001825188818334f5955050508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461053a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260468152602001806107b96046913960600191505060405180910390fd5b50505073ffffffffffffffffffffffffffffffffffffffff8116600090815260208190526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790559392505050565b6000308484846040516020018083838082843760408051919093018181037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001825280845281516020928301207fff000000000000000000000000000000000000000000000000000000000000008383015260609990991b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166021820152603581019790975260558088019890985282518088039098018852607590960182525085519585019590952073ffffffffffffffffffffffffffffffffffffffff81166000908152948590529490932054939450505060ff909116159050610697575060005b9392505050565b604080517fff000000000000000000000000000000000000000000000000000000000000006020808301919091523060601b6021830152603582018590526055808301859052835180840390910181526075909201835281519181019190912073ffffffffffffffffffffffffffffffffffffffff81166000908152918290529190205460ff161561072e575060005b9291505056fe496e76616c696420636f6e7472616374206372656174696f6e202d20636f6e74726163742068617320616c7265616479206265656e206465706c6f7965642e496e76616c69642073616c74202d206669727374203230206279746573206f66207468652073616c74206d757374206d617463682063616c6c696e6720616464726573732e4661696c656420746f206465706c6f7920636f6e7472616374207573696e672070726f76696465642073616c7420616e6420696e697469616c697a6174696f6e20636f64652ea265627a7a723058202bdc55310d97c4088f18acf04253db593f0914059f0c781a9df3624dcef0d1cf64736f6c634300050a003200000000000000000000000000

It is recommended to put all these commands into a bash script that receives the RPC_URL and PK as parameters, and then runs the commands. This way, you can easily run the script with different parameters to deploy to different networks.

If an error arises regarding the EIP-1159, add the --legacy flag to the cast send commands.

After that, the Factory should be deployed to the network in the address 0x0000000000ffe8b47b3e2130213b802212439497.

Getting the init code hash

In order to get the vanity address, we need to calculate the salt. The salt is a 32-byte value that is used to generate the vanity address. The salt is now calculated in a different, more efficient process, implemented in the repo: https://github.com/MELD-labs/vadd

That process will just require the initCodeHash of the contract. The initCodeHash can be obtained by running the following command:

yarn hardhat initCode --contract <contractName> (--librariesfile <libraries-json-file>)[optional-param1] [optional-param2] ...
// Example:
yarn hardhat initCode --contract MeldToken 0xaaaa1A852b202305bc158aD2Ea413CD31D027dE4

Parameters

  • contract: The name of the contract
  • librariesfile: The path to the libraries file (optional)
  • constructorArgs: The constructor arguments (optional)

The libraries file should be a JSON file with the following format:

{
  "library1Name": "library1Address"
  "library2Name": "library2Address"
  ...
}

Checking the vanity address

Once the salt is calculated, it is recommended to check the vanity address. This can be done by running the following command:

yarn hardhat getAddress --initcodehash <initCodeHash> --salt <salt>
// Example
yarn hardhat getAddress --initcodehash 0x3df8e498ac03fac1409a16f7ee161f7fd31b17f3b199b69a4dcf0cdfee071c83 --salt 40200182

Parameters:

  • salt: The salt to use to deploy the contract
  • initcodehash: The init code hash of the contract

Deploying the contract

Once the salt is calculated, we can deploy the contract. The salt is set using the --salt parameter. The network where it will be deployed must be specified using the --network parameter. Note that the network must be configured in the hardhat.config.js file. The task will deploy the contract indicated with the --contract flag and the constructor parameters must be indicated after that (if there are any).

The address of the deployed contract will only depend on the salt, and not in the address that sends the transaction. This means that the contract can be deployed by anyone, and the address will be the same.

The task will be executed as follows:

yarn hardhat deployDeterministically --network <network> --salt <salt> --contract <contractName> (--librariesfile <libraries-json-file>) [optional-param1] [optional-param2] ...
// Example
yarn hardhat deployDeterministically --network localhost --salt 40200182 --contract MeldToken 0xaaaa1A852b202305bc158aD2Ea413CD31D027dE4

Parameters:

  • salt: The salt to use to deploy the contract
  • contract: The name of the contract
  • librariesfile: The path to the libraries file (optional)
  • constructorArgs: The constructor arguments (optional)

The libraries file should be a JSON file with the following format:

{
  "library1Name": "library1Address"
  "library2Name": "library2Address"
  ...
}