
The Graveyard of dApps
Maybe blockchain is forever, but the dApps die fast.

How to implement a `mint` function in your NFT contract?
Here’s the simplest NFT contract:import '@openzeppelin/contracts/token/ERC721/ERC721.sol'; contract SimplestNFT is ERC721 { function mint(uint256 tokenId) external { _safeMint(msg.sender, tokenId); } }It delegates the heavy lifting to the base contract implementation (in this case, OpenZeppelin). _safeMint is responsible for matching the ERC721 spec: it does some checks, stores data about ownership, emits events and calls callbacks. But you don’t want to allow anyone to call this function wit...

How to get better at Solidity
1. Read “Mastering Ethereum”https://www.amazon.com/Mastering-Ethereum-Building-Smart-Contracts/dp/1491971940 Initially, I was skeptical. The book was released in 2018. The space moves so fast, surely the content won’t be relevant in 2022? But I’m so glad I gave it a chance! “Master Ethereum” is full of extremely helpful context: elliptic curve math, how wallet addresses work, why sha3 instruction is actually keccak256, the history of the original DAO, and the most famous hacks. It also talks ...

The Graveyard of dApps
Maybe blockchain is forever, but the dApps die fast.

How to implement a `mint` function in your NFT contract?
Here’s the simplest NFT contract:import '@openzeppelin/contracts/token/ERC721/ERC721.sol'; contract SimplestNFT is ERC721 { function mint(uint256 tokenId) external { _safeMint(msg.sender, tokenId); } }It delegates the heavy lifting to the base contract implementation (in this case, OpenZeppelin). _safeMint is responsible for matching the ERC721 spec: it does some checks, stores data about ownership, emits events and calls callbacks. But you don’t want to allow anyone to call this function wit...

How to get better at Solidity
1. Read “Mastering Ethereum”https://www.amazon.com/Mastering-Ethereum-Building-Smart-Contracts/dp/1491971940 Initially, I was skeptical. The book was released in 2018. The space moves so fast, surely the content won’t be relevant in 2022? But I’m so glad I gave it a chance! “Master Ethereum” is full of extremely helpful context: elliptic curve math, how wallet addresses work, why sha3 instruction is actually keccak256, the history of the original DAO, and the most famous hacks. It also talks ...
Subscribe to w1nt3r.eth
Subscribe to w1nt3r.eth
Share Dialog
Share Dialog


>8.2K subscribers
>8.2K subscribers
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.
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.
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.
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 :)
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.
Here's a general idea:
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.
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.
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();
}
}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.
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.
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.
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.
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.
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 :)
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.
Here's a general idea:
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.
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.
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();
}
}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.
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.
No activity yet