Skip to content

Latest commit

 

History

History
110 lines (95 loc) · 4.91 KB

README.md

File metadata and controls

110 lines (95 loc) · 4.91 KB

Universal Deployer

A tool to generate single-use keyless transactions to deploy smart contracts across chains. It uses a process similar to Nick's method:

  • Build a transaction to deploy the given contract
  • Generate a random valid signature for the transaction
  • Reverse-lookup the address that "signed" the transaction
    • Note the private key for this address is verifiably unknown (signatures generated by this tool are clearly artificial as they have 31 bytes of all 1s in r and many 0s in s)

Once finished with this process, you just send some ETH to this single-use address on any chain and send the raw transaction.

Benefits over traditional deployment methods

  • Easily deploy a contract to the same address across chains
    • No need to manage deployer key nonces, and no risk of accidentally using up the nonce
  • Simple trust model
    • If you trust the contract address on one chain, you can trust it on all chains
    • If the address is the same, the code & args must be the same as well
  • Decentralized deployments
    • Contract deployments can be publicly shared and deployed to any chain by anybody

Features

  • Efficient vanity address generation
    • Specify a prefix
    • Specify a number of 0-bytes
    • NOTE: these apply to the deployed contract, not the single-use address

Installation

Clone the repository

git clone [email protected]:marktoda/universal-deployer.git

Install with Cargo

> cargo install --path .
> universal-deployer --help

Usage

> universal-deployer --help
universal-deployer 0.1.0
Tool to generate single-use keyless contract deployment transactions

USAGE:
    universal-deployer [FLAGS] [OPTIONS] <bytecode-or-artifact>

FLAGS:
    -h, --help       Prints help information
    -j, --json       Print output in json format
    -V, --version    Prints version information

OPTIONS:
    -c, --constructor-args <constructor-args>    ABI encoded constructor args to pass to the deployment
        --gas-limit <gas-limit>
            The gas limit to use for the transaction. Recommended to use a generally overestimated limit to allow
            confirmation on many chains
        --gas-price <gas-price>
            The gas price to use for the transaction. Recommended to use a generally high price to allow confirmation on
            many chains [default: 100000000000]
    -n, --num-zero-bytes <num-zero-bytes>        The number of zero bytes to exist in the deployed contract address
    -p, --prefix <prefix>                        A prefix for the deployed contract address
    -r, --rpc-url <rpc-url>                      Optional RPC url to estimate deployment gas limit
    -s, --s-start <s-start>
            The S value to start with, useful when running multiple instances to grind


ARGS:
    <bytecode-or-artifact>    Path to a contract artifact file or hex contract bytecode

Example

You have a smart contract that you want to create a deployment transaction for - let's go through the flow!

  1. Install universal-deployer as described above
  2. Run universal deployer with your desired arguments, for example:
> universal-deployer \
    /path/to/artifact.json \ # provides the bytecode of the contract to deployer
    --prefix 0x00000000 \ # the tool will attempt to make the contract address begin with 4 0-bytes
    --constructor-args <abi-encoded args> \ # generated through a tool like `cast abi-encode`
    --rpc-url https://mainnet.infura.io/v3/<infura-api-key>  # optional to estimate gas limit more accurately 
  1. The tool will run (for awhile, depending on how many constraints you gave it). It outputs the current best match found as it goes
> universal-deployer ...
Starting search for deployment signature with config: 
Address Generation Config
	- Prefix: 00000000
	- S start: 1
Found new best signature with contract: 0x0174…7a2a, match_count: 1
Found new best signature with contract: 0x00ea…e09b, match_count: 2
Found new best signature with contract: 0x0003…09fa, match_count: 3
  1. If you get tired of waiting, you can stop it with a sigint (ctrl-c) and it will output the details of the best match
  2. Eventually the tool finishes, and outputs the final result:
Info: Sig: 0x....
Contract: 0x00000000....
Deployer: 0x....
Raw Tx: 0x....
  1. Fund the deployer address with enough ETH (or other native gas-paying token) to deploy the contract. By default this is 0.1
  2. Send the raw transaction to the blockchain. Some suggested tools to do this:
  • Etherscan "Broadcast Raw Transaction" tool
  • cast publish
  • send an eth_sendRawTransaction RPC call to a full-node or RPC service
  1. Save the transaction! It can be used in the future to deploy to other chains.

Limitations

  • If a contract includes args which may be different chain-to-chain (i.e. WETH), this tool is not very useful as the args can't be changed without changing the contract address.