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

RFC: Cross Blockchain Transaction Replay Protection without IAN #127

Closed
konradkonrad opened this issue Jun 30, 2016 · 4 comments
Closed

Comments

@konradkonrad
Copy link

Description

Status Quo

In order to mitigate transaction replays from testnet to mainnet for dual-use accounts, there is an account nonce offset ("IAN" or "accountStartNonce") of 2**20 implemented in the testnet ECS:

  • Initial Account Nonce (IAN) is 2^20 (instead of 0 in all previous networks).
    • All accounts in the state trie have nonce >= IAN.
    • Whenever an account is inserted into the state trie it is initialised with nonce = IAN.

This greatly reduces the risk of applicable signed transactions from the testnet to be reapplied on the mainchain.

Proposal

Since the goal is to tie signed transactions to a specific blockchain, using IAN offsets in the ECS is only a partial solution, since account reuse can also happen across other ("private") ethereum blockchains.

A cleaner solution would be to use the genesis_hash as part of the transaction signature. Instead of signing the transaction hash

sign(sha3(rlp(tx)))

this would become

sign(sha3(rlp(tx)) + genesis_hash)

Since the genesis_hash is known to all parties involved in signing and verifying, this adds no extra cost to blockchain size.

Problems Adressed

Inequality of Account Nonces and Transaction Count

In order to sign transactions locally in an rpc-client, the client needs to learn the correct nonce for the transaction. The rpc spec only provides eth_getTransactionCount(address), but does not allow for querying the "accountStartNonce" from the ECS.
This proposal solves this problem, because the genesis_hash can be learned by a client within the current rpc spec.

Replay possibility between other chains

Ethereum blockchains are not forced to specify "accountStartNonce", so replay from other chains than testnet/morden are still possible.
This proposal solves this problem as described above.

Complexity in Ethereumclients

This also reduces the complexity involved in determining the transaction count for an account and it simplifies the ECS.

@konradkonrad konradkonrad changed the title Cross Blockchain Transaction Replay Protection without IAN RFC: Cross Blockchain Transaction Replay Protection without IAN Jul 1, 2016
@ebuchman
Copy link

ebuchman commented Jul 2, 2016

this is also quite relevant for the upcoming hard fork! we should ensure something like it gets included. an alternative is to add a network id to the transaction being signed (networkid doesnt need to be propogated or hashed into the tx id, since everyone has it, but should be concatenated to the tx before signing)

@konradkonrad
Copy link
Author

Having learned from the hard fork, I feel like above proposal still doesn't solve what it is trying to solve. So for a more involved approach, I believe a scheme where the signatory can define a block number n at will, which block's hash shall be part of the signature, would be desirable:

sign(sha3(rlp(tx)) + block(n).hash)

In the default case n can be 0, i.e. the genesis block. However in a fork scenario, a signatory may want to chose a certain block number in the past.

But I see that this may require more changes, because the current transaction layout has no obvious field where n could be attached to. Also it would lose many of the nice properties of the original idea, since

  • now there is extra data in transactions necessary (i.e. more data to be stored and sent over network)
  • signature verification will need dynamic access to the blockchain

I'd be happy to hear comments on this!

@ebuchman Regarding the network_id I'm unsure. network_id in my view should be a factor of the genesis_hash -- I don't see the point why two distinct networks that want to start with the same state (== genesis block) will need to start with the same genesis_hash, too?

@konradkonrad
Copy link
Author

konradkonrad commented Aug 4, 2016

One more thought: the signature has a fixed length, so without any protocol changes on transactions themselves it should be possible to attach n to the signature, right?

signature = sign(sha3(rlp(tx)) + block(n).hash) + n

@konradkonrad
Copy link
Author

close in favour of #134 and implications of #86

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

No branches or pull requests

2 participants