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

Method to check if a chainID is valid at a specific block Number #1965

Merged
merged 8 commits into from
May 19, 2019
Merged
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions EIPS/eip-1965.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
eip: 1965
title: Valid ChainID with blockNumber
wighawag marked this conversation as resolved.
Show resolved Hide resolved
author: Ronan Sandford (@wighawag)
category: Core
type: Standards Track
discussions-to: https://ethereum-magicians.org/t/eip-1965-valid-chainid-for-specific-blocknumber-protect-all-forks/3181
status: Draft
created: 2019-04-20
---
wighawag marked this conversation as resolved.
Show resolved Hide resolved

## Abstract
This EIP adds an precompile that returns whether a specific chainID (EIP-155 unique identifier) is valid at a specific blockNumber. ChainID are assumed to be valid up to the blockNumber at which they get replaced by a new chainID.

## Motivation
[EIP-155](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md) proposes to use the chain ID to prevent replay attacks between different chains. It would be a great benefit to have the same possibility inside smart contracts when handling signatures, especially for Layer 2 signature schemes using [EIP-712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md).

[EIP-1344](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1344.md) is attempting to solve this by giving smart contract access to the tip of the chainID history. This is insuficient as such value is changing. Hence why EIP-1344 describes a contract based solution to work arround the problem. It would be better to solve it in a simpler, cheaper and safer manner, removing the potential risk of misuse present in EIP-1344. Furthermore EIP-1344 can't protect replay properly for minority-led hardfork as the caching system cannot guarantee accuracy of the blockNumber at which the new chainID has been introduced.
wighawag marked this conversation as resolved.
Show resolved Hide resolved

[EIP-1959](https://github.com/ethereum/EIPs/pull/1959) solves the issue of EIP-1344 but do not attempt to protect from minority-led hardfork as mentioned in the rationale. We consider this a mistake, since it remove some freedom to fork. We consider that all fork should be given equal oportunities. And while there will always be issues we can't solve for the majority that ignore a particular fork, **users that decide to use both the minority-fork and the majority-chain should be protected from replay without having to wait for the majority chain to update its chainID.**

## Specification
Adds a new precompile which uses 2 argument : a uint256 value that represent the chainID to test and a uint256 value representing the blockNumber at which the chainID is tested. It return ```true``` if the chainID is valid at the specific blockNumber, ```false``` otherwise. Note that chainID are considered valid up to the blockNumber at which they are replaced. So they are valid for every blockNumber past their replacement.
wighawag marked this conversation as resolved.
Show resolved Hide resolved

The operation costs `G_blockhash` + `G_verylow` to execute.
wighawag marked this conversation as resolved.
Show resolved Hide resolved

The cost of the operation might need to be adjusted later as the number of chainID in the history of the chain grows.
wighawag marked this conversation as resolved.
Show resolved Hide resolved

## Rationale

The rationale at EIP-1959 applies here as well too :

- An opcode is better than a caching system for past chainID, It is cheaper, safer and do not include gaps.
- Direct access to the latest chainID is dangerous since it make it easy for contract to use it as a replay protection mechanism while preventing otherwise valid old messages to be valid after a fork that change the chainID. This can have disastrous consequences on users.
- all off-chain messaged signed before a fork should be valid across all side of the fork.

The only difference is that this current proposal propose a solution to protect hardfork led by a minority.

To summarize there is 2 possible fork scenario :

1) The majority decide to make an hardfork but a minority disagree with it (ETC is such example). The fork is planned for block X. If the majority is not taking any action to automate the process of assigning a different chainID for both, the minority has plenty of time to plan for a chainID upgrade to happen at that same block X. Now if they do not do it, their users will face the problem that their messages will be replayable on the majority chain (Note that this is not true the other way around). As such there is no reason that they’ll leave it that way.

2) A minority decide to create an hardfork that the majority disagree with (or simply ignore). Now, the same as above can happen but since we are talking about a minority there is a chance that the majority do not care about the minority. In that case, there would be no incentive for the majority to upgrade the chainID. This means that user of both side of the fork will have the messages meant for the majority chain replayable on the minority-chain unless extra precaution is taken.

The solution is to add the blockNumber representing the time at which the message was signed and use it as an argument to the opcode proposed here. This way, when the minority forks with a new chainID, the previous chainID become invalid from that time onward. So new messages destinated to the majority chain can't be replayed on the minority fork.


## Backwards Compatibility

EIP-712 is still in draft but would need to be updated to include the blockNumber as part of the values that wallets need to verify for the protection of their users.

Since chainID and blockNumber will vary, they should not be part of the domain separator (meant to be generated once) but another part of the message.

While the pair could be optional for contract that do not care about replays or have other ways to prevent them, if chainID is present, the blockNumber must be present too. And if any of them is present, wallet need to ensure that the chainID is indeed the latest one of the chain being used, while the blockNumber is The latest one at the point of signing. During fork transition, the wallet can use the blockNumber to know which chainID to use.

## References
This was previously suggested as part of [EIP1959 discussion](https://ethereum-magicians.org/t/eip-1959-valid-chainid-opcode/3170).

## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).