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
1
s in r and many0
s in s)
- 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
Once finished with this process, you just send some ETH to this single-use address on any chain and send the raw transaction.
- 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
- 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
git clone git@github.com:marktoda/universal-deployer.git
> cargo install --path .
> universal-deployer --help
> 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
You have a smart contract that you want to create a deployment transaction for - let's go through the flow!
- Install universal-deployer as described above
- 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
- 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
- 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
- Eventually the tool finishes, and outputs the final result:
Info: Sig: 0x....
Contract: 0x00000000....
Deployer: 0x....
Raw Tx: 0x....
- Fund the deployer address with enough ETH (or other native gas-paying token) to deploy the contract. By default this is 0.1
- 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
- Save the transaction! It can be used in the future to deploy to other chains.
- 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.