Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow replay of transactions that are designed to be replayable #27935

Closed
SKYBITDev3 opened this issue Aug 15, 2023 · 7 comments
Closed

Allow replay of transactions that are designed to be replayable #27935

SKYBITDev3 opened this issue Aug 15, 2023 · 7 comments

Comments

@SKYBITDev3
Copy link

SKYBITDev3 commented Aug 15, 2023

Rationale

Innovative and useful blockchains have been increasingly appearing, resulting in a growing field of cross-chain platforms and tools, and the need to deploy contracts to the same addresses across many blockchains.

The CREATE2 opcode and CREATE3 method make it easier to deploy contracts to the same address on multiple blockchains (because nonce is not used in address calculation). But first CREATE2 and CREATE3 factory contracts need to be deployed before CREATE2 and CREATE3 can be used.

Such factory contracts need to be deployed to the same address on multiple blockchains in order for the contracts that are deployed from them to have the same address.

One example is Deterministic Deployment Proxy by MicahZoltu, whom we know is an Ethereum core developer and EIP author. It offers a CREATE2 factory packaged as a replayable serialized signed raw deployment transaction:

0xf87e8085174876e800830186a08080ad601f80600e600039806000f350fe60003681823780368234f58015156014578182fd5b80825250506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222

Transaction type and chain ID are 0, with hardcoded gas limit and price.

As long as this deployment transaction is broadcast as-is, the transaction hash will always be 0x8ee59123fee2379c81c6fed5fa4310d24b0e40027b3bb04684bde87f0e3caaf1 and the created contract will always have address 0x7a0d94f55792c434d74a40883c6ed8545e406d12. See the raw transaction processed on Base: https://basescan.org/getRawTx?tx=0x8ee59123fee2379c81c6fed5fa4310d24b0e40027b3bb04684bde87f0e3caaf1, which matches with the 0xf87e80... above.

This CREATE2 factory has actually been successfully deployed to the same address on over 20 blockchains, just by pushing the raw transaction 0xf87e80... to each: https://blockscan.com/address/0x7A0D94F55792C434d74a40883C6ed8545E406D12

Now with increased enforcement of chain ID as first described in the Geth v1.10.0 announcement, rejections of such deployment transactions with chain ID 0 are becoming more common with node service providers.

If we respond to the rejections by setting chain ID to match the blockchain that we want to deploy the factory contract onto, then the raw transaction will be different for each blockchain (as changing other values like gas price would too), hence the address will be different on each blockchain, which is the opposite of what is needed.

--rpc.allow-unprotected-txs is only relevant for those running nodes. Not everyone runs nodes due to the high hardware requirements, and there are now many node service providers. But node service providers may not enable --rpc.allow-unprotected-txs, and you also said in the Geth v1.10.0 announcement "that this is a temporary mechanism that will be removed long term". Such a heavy-handed banning of transaction replay would be the wrong approach. Such intolerance would stifle innovation in the cross-chain field.

Factory contracts are a valid use case for replayable transactions. I'm aware that there are security risks when there's no replay protection. So then let's come up with a way to maintain secuirty whilst allowing transactions that are meant to be replayed.

Implementation

One idea is to agree on a value for chain ID that would indicate that the transaction was designed to be replayable. e.g. if chainId === -1 then let it through. No wallet app would set a negative chain ID (and none would've done so in the past so there's no risk of replay of past transactions), so normal crypto users remain safe.

Also consider whether there should be other checks e.g. allow if the transaction is only for contract deployment.

Let's discuss and work towards a solution.

@SKYBITDev3
Copy link
Author

SKYBITDev3 commented Aug 17, 2023

Factory contracts is just one use case which depends on same contract addresses across all blockchains.

Another use case is with proxy contracts. e.g. Axelar have cross-chain services, with gateway and gas service proxy contracts on 14 testnets and 13 mainnets:
https://docs.axelar.dev/dev/reference/mainnet-contract-addresses
https://docs.axelar.dev/dev/reference/testnet-contract-addresses

They used EOAs for deployment, which means different From addresses and nonces caused different addresses for their gateway proxy contracts. For their gas service proxy contracts they managed to keep the account and nonce same when deploying, so the addresses are same.

Replayable deployment transactions would have helped them a lot for keeping the same addresses across the many blockchains that they support, as then nonce and account would not matter.

@SKYBITDev3
Copy link
Author

SKYBITDev3 commented Aug 18, 2023

I've mentioned factories and proxies as valid use cases, but there would of course be others that we ourselves may not know of, as we shouldn't assume that we can imagine all possible use cases in the present or future.

Basically any application / platform / framework that deals with multiple blockchains would benefit from having their contracts at the same addresses across all blockchains, as it makes things simpler and more elegant.

e.g. OpenGSN supports 13 different blockchains with 7 contracts on each. Currently they record 7 addresses for each blockchain, so over 90 addresses: https://github.com/opengsn/docs/blob/master/networks/gsn-networks.json. If they could have the same address on all blockchains for each of the contracts then they'd only have to work with 7 different addresses.

@SKYBITDev3
Copy link
Author

SKYBITDev3 commented Aug 20, 2023

Several EIPs require contracts to be deployed for public use. e.g. singleton contracts in EIP-1820 and EIP-2429, and factory contract in EIP-4337. EIP-1820 itself outlines the keyless deployment method using an already-signed deployment transaction (with no chainId or chainId: 0), which would require EIP-155 to be unenforced.

@MariusVanDerWijden
Copy link
Member

I think this is the wrong place to discuss a change like this, the best way to get such a scheme discussed is to open an EIP and start a discussion on the ethereum magicians forum https://ethereum-magicians.org/top?period=quarterly

@SKYBITDev3
Copy link
Author

Yes, I had already created a thread at ethereum magicians: https://ethereum-magicians.org/t/transaction-replay-blanket-ban-is-wrong

I hope that we can find an acceptable solution.

Thank you for listening.

@holiman
Copy link
Contributor

holiman commented Aug 21, 2023

So then let's come up with a way to maintain secuirty whilst allowing transactions that are meant to be replayed.

I don't see what the problem is.

Geth does not avoid putting them into blocks, nor reject blocks which contain them, and geth does not refuse to relay them to peers. All geth does is not accept them when users submit them over RPC.

At one point in the lifetime of the chain, someone needs to use a modded geth to accept such a transaction over RPC, to then relay it to the network. Or use some other means of getting them into a block, e.g. use a custom block builder such as MEV.

@SKYBITDev3
Copy link
Author

All geth does is not accept them when users submit them over RPC.

I'm a developer, and RPC via node service providers is how I get things done on the many different blockchains that are now out there.

I don't have the resources to set up and run my own nodes (I'd need a different one for each blockchain) just to be able to occasionally replay a transaction.

So I'd welcome more suggestions that wouldn't require much resources.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants