Have you ever deployed a smart contract and noticed the deployed address? It seems to be a bunch of random characters, and while it is, that address is deterministic.
A quick primer on account and address in Ethereum - There are two types of accounts in Ethereum: Externally Owned Account (EOA) and Contract Account. Both types of accounts have an address associated with them. An address in Ethereum is a 42-character hexadecimal address.
E.g., Uniswap's UniswapV3Factory smart contract address is 0x1F98431c8aD98523631AE4a59f267346ea31F984 and is the same in Ethereum mainnet, Polygon, Optimism, Arbitrum, and Avalanche. The same is the case for Uniswap's all smart contracts.
How is the smart contract address generated?
The smart contract's address is derived from two values, the EOA user's address and the number of transactions the user has sent. That is the user's wallet address and nonce.
Primer on Nonce - Nonce, simply put, is the number of transactions a user has done in a given blockchain. Every time a user has an outgoing transaction, the nonce increases by one. The nonce is unique for each blockchain, meaning that sending a transaction in Ethereum will increase the account's nonce in Ethereum but not in Polygon.
Please note that we refer to the account nonce, which pertains to the user, and not to the block nonce.
As I mentioned at the start of the article, the smart contract address is deterministic. We can determine the address before the smart contract is actually deployed using the wallet's address from which the user will deploy the contract and their most recent nonce + 1.
Below is the example code using ether.js to compute the address pre-deployment. Verify the output
Finally, to answer the question, "How to deploy a smart contract to the same address across blockchains?"
In our wallet, I use Metamask, we should keep an account, and let's call it the deployment account, only to deploy the smart contracts. We should not do any transactions in it other than smart contract creation. Sending smart contract creation transactions in all the blockchains with the same nonce will result in the same smart contract address everywhere.
Having the same address makes the smart contract much more developer-friendly. It reduces the friction of maintaining addresses for different env (mainnet vs. testnet) and blockchains (Ethereum, Polygon, etc.). It makes it easier to socialize the launch as well.
I hope you found this useful! If you have any questions or feedback, please let me know in the comments, and I will be happy to answer.