Here are a few reasons why you should always use a burner wallet to deploy new contracts. In the end, I also have an example of how I do this for my own projects.
1. Security
Every time someone asks you for your private key, you should get very suspicious. Even if it's a developer tool for deploying smart contracts. Malicious software and browser extensions can monitor your keyboard or clipboard and steal your private key as you are typing it. Vendor attacks are becoming more popular.
The developers might not have malicious intentions, but the software is complex and bugs happen. In 2022 a wallet named Slope accidentally logged users' seed phrases to a log aggregation service. The result: millions of funds drained.
If malicious actors get access to the private key that deployed your contract, they'll be able to steal all the funds stored in that wallet. Additionally, they can call "admin" level functions that you added to your contract, e.g. withdrawing funds or minting without limits.
Foundry supports hardware wallets. You should use that! But there are still a few reasons why even with a hardware wallet it's still a good idea to use a new address.
2. Privacy
All data on the blockchain is public. However, you might not want to have the deployed contract associated with you. For example, for high-profile projects that do many NFT drops, smart users figured out a way to find the contract via the developer's Ethereum account history and mint the project before everyone else has a chance to.
As a consultant, you might also want to keep all your clients' projects separate.
Unfortunately, TornadoCash has recently been banned in the USA. While it's a superior option, even funding your burner wallet from a centralized exchange (like Coinbase) already provides a decent level of privacy from the general public.
3. Same address on multiple chains
EVM-compatible L2s and sidechains become more and more popular. Some projects, like OpenSea's SeaPort, have been deployed to the same address on all these chains. How did they do it?
The secret is that the contract address is deterministic: it's a hash of your wallet address and account nonce (i.e. number of transactions your wallet has published). This means that if your wallet's first transaction is deploying a contract, it will get the same address on all L2s you deploy it to.
For example, Button DAO was deployed this way.
Note that there are more complex ways of doing this. OpenSea is using very clever tricks (via CREATE2
opcode) to allow anyone to deploy SeaPort to any EVM-compatible chain without publishing their private keys. Subscribe to learn more :)
4. Vanity address
Using the same idea from the previous point, you can use some software that will generate millions of Ethereum addresses to find the one that combined with nonce 0 would produce a nice-looking contract address.
For example, Runes of Ethereum was deployed this way. Its address is a beautiful 0x555555551777611fd8eb00df11ea0904b560cf74
(referring to the 5 runes available up for grabs). MEV bots use the same trick to get an address that has a lot of zeros in it (because 00
bytes in calldata cost less gas when making transactions).
I used a tool called profanity to generate a new wallet.
How I do it
Here's a general idea:
1. Get a wallet address
You can generate a random new wallet using command line tools or Metamask. If you have a hardware wallet and use Foundry, you can simply add a new address there to use for running your scripts. You can also use tools like profanity
to get a nice-looking address.
2. Fund it from TC or CEX
Before deployment, send an estimated amount of ETH to your burner wallet. You can use a centralized exchange — the curious minds will only be able to see that the wallet was funded via "Coinbase 4" (but Coinbase will know).
Add 20-50% more to your estimate because the gas prices will fluctuate.
3. Deploy the contract
With Foundry, you can use forge script
command with the following script:
contract HotChainSVGDeploy is Script {
function run() external {
vm.startBroadcast();
HotChainSVG nft = new HotChainSVG();
nft.setOwner(0x1E79b045Dc29eAe9fdc69673c9DCd7C53E5E159D);
vm.stopBroadcast();
}
}
4. Transfer ownership
If you are using Ownable
or AccessControl
, make sure to transfer admin access to another wallet. This way if the burner wallet is exposed (via malicious attack or accidental log), it won't be able to access your funds.
Notice that in the forge script above we call nft.setOwner()
. If you deployed the contract via another system, make sure to call the appropriate functions manually.
5. Send the rest of the funds back
After your contract is deployed, you'll have some funds remaining in your burner wallet. If you care about privacy, don't send the funds back to your main wallet, use a centralized exchange or mixer.
If you have more questions, feel free to reach out via Twitter: @w1nt3r_eth. Definitely subscribe.