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

Standardized Ethereum Recovery Proposals (ERPs) #867

Merged
merged 5 commits into from Apr 16, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
177 changes: 177 additions & 0 deletions EIPS/eip-867.md
@@ -0,0 +1,177 @@
---
eip: 867
title: Standardized Ethereum Recovery Proposals
author: Dan Phifer (dp@musiconomi.com), James Levy (james@taptrust.com), Reuben Youngblom (reuben@taptrust.com)
discussions-to: https://ethereum-magicians.org/t/eip-867-standardized-ethereum-recovery-proposals-erps/139
type: Meta
status: Draft
created: 2018-02-02
---

## Simple Summary
Provide a standardized format for Ethereum Recovery Proposals (ERPs), which relate to recovery of certain classes of lost funds. Individual ERPs will follow the same process as any EIP, but will be formatted and evaluated in a standard way to ensure consistency and transparency.

**This EIP does not advocate for or against the acceptance of any particular recovery proposals, nor would its acceptance alone result in any state changes to the blockchain.**

## Abstract
This proposal identifies a common solution method that can be used to address certain classes of lost funds on the Ethereum blockchain. In particular, it is intended to address cases where there is no disagreement about the right outcome between directly affected parties, enabling timely and low-risk solutions to many issues that have already occurred or are likely to occur again as Ethereum grows.

The solution method is divided into three parts:

1. Standards that will need to be met by any follow-on ERP in order to be considered for approval.
2. Recommendations for a common format for ERPs to use to specify a set of corrective actions that can be interpreted by clients.
3. Guidelines for client teams to implement code that can read, interpret, and apply the corrective actions at a specific block. The set of possible corrective actions is intentionally limited to minimize risk associated with any ERP.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ERP process is a useful solution, but this step 3 should be removed and be replaced by an alternative way to gather these funds without needing client teams or irregular state changes

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I can follow this suggestion. Could you expand on that how to recover funds without state changes? Let's use the Parity Multi-Sig example if you don't mind.



## Motivation
The issue of fund recovery on the Ethereum blockchain is often controversial. Frozen fund recovery proposals are almost never successful due to the relatively ad-hoc nature of such requests and the subjectivity that is often required to evaluate the merits. This EIP attempts to remove these barriers by providing both a standardized format for fund recovery EIPs and an objective standard by which to measure future proposals.

## Specification
This EIP describes a common format to be used for a subclass of EIPs, referred to as ethereum recovery proposals (ERPs), that propose an irregular state change required to address a fund recovery scenario that cannot be addressed using the standard protocol. Each ERP will reference this EIP will follow the guidelines set out here.

The purpose of each ERP is (a) to clearly describe the issue to be corrected, (b) to describe why an irregular state change is both necessary and justified, and (c) to demonstrate that the proposed actions will achieve the ERP's objectives.

Each ERP will be required to use a standard format to represent the set of proposed state changes and must include a verification script that can reliably generate those changes. ERPs that do not meet (at least) these requirements will not be considered for approval.

Each ERP should contain the following items:

- **Preamble**: EIP (RFC 822) header containing metadata about the ERP, including the EIP number, a short title (44 character maximum), and the real names (and optional contact information) for each author.
- **Simple Summary**: A simplified and layman-accessible explanation of the ERP.
- **Detailed description**: A human-readable description of the proposed corrective actions and the criteria used to determine the proposed actions.
- **Justification**: A concise description of why the corrective actions are both reasonable and unlikely to be challenged by any directly affected party.
- **Verification script**: A machine-readable script that outputs one State Change Object. The script should clearly implement the selection and action generating logic outlined in the description such that reviewers can independently re-generate an identical State Change Object.
- **State Change Object**: The output of the verification script and the input to the ethereum clients. Primarily, it specifies the complete set of proposed state change actions.
- **Appendix (optional)**: with supporting evidence. Attachments in the appendix may include documents verifying details specified as part of the recovery proposal description.

The following sections give more detailed descriptions of the expectations for the Justification, Verification Script, and the format of the State Change Object.

### Justification
A concise description of why this action is both reasonable (cannot be accomplished without an irregular state change) and unlikely to be challenged by a *directly* affected party.

**Considerable example** (concise, includes supporting evidence, no negative impact):
*A crowdsale run by XYZ incorrectly published the testnet address of their crowdsale contract to their public website at the start of their crowdsale on Jan 19, 2018. 501 ETH was sent by 328 users on the mainnet to the incorrect address between block 4,235,987 and 4,236,050. See here for the testnet contract, and see here for the transactions to the same address on the mainnet. See here for a statement made by XYZ on their website. Because there is a contract at this address on the testnet and the corresponding nonce for the creator address has already been used on the mainnet, it is considered effectively impossible that anyone coincidentally holds the private key. We have verified that all transactions came from addresses with no associated code, so there should be no issue returning eth to the senders.*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just as a thought, to avoid this particular case, wouldn't it be better to not have any address duplicated on different networks, so that it is impossible to create an address on one network that will be the same as an address on another network (used or not)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will you file an EIP for that? For example, the address calculation can take the chainID into account.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, ;)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made an EIP: #887.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example doesn't seem to be considerable as per @realcodywburns comment at #887 (comment).

If and before this EIP is merged I suggest that you use another example.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still concerned that this example may be misleading as per the discussion at #887. Can we sort this out as well please?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the discussion in #887 makes this a bad example. It just explains how future developers can avoid the situation by managing nonces on multiple chains carefully. The problem also could have been avoided by just not publishing a testnet contract address to a website. The point of this example is that the problem did occur and there is no regular state transition that can resolve the problem, only an irregular state transition can resolve the problem.

Personally, I think this is a good example for all of the reasons that @phiferd indicated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ultimately, all of the irregular state transitions that ERPs would address are caused by "someone made a mistake". Sometimes that mistake is a bug in a contract (Parity multisig), sometimes it is someone typing something wrong (off by one addresses), sometimes it is someone not realizing what JS does with big numbers (truncation ICO). Claiming that this example is bad because it was "human error" is really just arguing that the entire ERP process is bad.

Humans are the source of all problems in computing. Any bug/exploit/problem can be traced back to a human making a mistake. Computers don't make mistakes, that is a human thing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, granted.


**Insufficient example** (not enough detail, no supporting evidence):
*We accidentally put the wrong contract address up on our website. Can you please refund any eth sent to 0x1234 back to the senders. Thanks.*

**Unacceptable example** (not objective, one person’s word against another):
*I sent tokens to X for services and he did a lousy job. I want my money back, but he won’t refund me. Please help!!*

### Verification Script
A machine-readable script that outputs a single State Change Object. This script should be implemented so that it is easily audited by a reviewer. Verification scripts should be javascript files that may use the [web3.js](https://github.com/ethereum/web3.js/) library.

There are a few guidelines for verification scripts:

- Scripts should always be written to be as concise as reasonably possible, and anyone executing the verification script should review it first to verify that it does not contain any unsafe operations.
- No verification script should ever require an unlocked ethereum wallet
- The script should hardcode the highest block included during execution (otherwise the results may differ between runs).

The purpose of the ERP Verification script is to unambiguously specify (through code) the criteria used to compute the set of State Change Actions. The script’s output, as described above, will be the input used by all Ethereum clients. Client teams should avoid manually pre-processing the artifact or using the artifact to simply guide changes in the code. Instead, the artifact should be bundled with the client and processed directly by the client at the specified block. This will minimize the amount of client effort required for each ERP and help to ensure compatibility between clients. We anticipate that some ERP Verification scripts may be trivial, but we recommend their inclusion for consistency.

### State Change Object
The State Change Object is a standard format that will be interpretable by all Ethereum clients.

It is a single JSON object containing the following fields:
- **erpId**: A string identifier for this ERP (likely the associated EIP number, e.g. “EIP-1234”). This will be converted from ascii to a hex string, then added as extra data on the target block.
- **targetBlock**: The block at which the stateChange should be applied. Clients would use this to determine when a set of state changes should occur
- **actions**: An array of State Change Actions.
- **metadata**
- **sourceBlock**: The highest block considered by the script when it was run.
- **version**: The version of the verification script when it was run.

### State Change Actions
A State Change action is a JSON object that includes a “type” field and a set of “data” fields, where the contents of the data fields are dependent on the type and must follow the schema defined for that type. This allows clients to support a limited set of operations initially and add more based on a subsequent EIP if needed. Support for the following action types should be implemented by clients upon adoption of this EIP:

#### weiTransfer
The `weiTransfer` action transfers ETH from one address to another.

*Data fields*

- **type** (*string*): `weiTransfer`
- **fromAddress** (*hex string*): The address from which ETH should be transferred
- **toAddress** (*hex string*): The address to which ETH should be sent
- **value** (*decimal string*): The amount of ETH to be transferred, in units of wei. The value must be a whole number greater than zero.


#### storeCode
The `storeCode` action stores the given code at the given address.

*Data fields*

- **type** (*string*): `storeCode`
- **toAddress** (*hex string*): The address to which the contract should be restored.
- **expectedCodeHash** (*hex string*): the expected hash of the code already at the toAddress.The empty string should be used if no code is expected at the toAddress. In all other cases, the “0x” prefix is optional.
- **code** (*hex string*): the new bytecode associated with the contract

### Appendix (Optional)
The appendix can include additional supporting evidence or attachments that will help reviewers understand or verify the claims made in the ERP.

For the storeCode operation, it should include the proposed contract source (e.g. Solidity) as well as the other details required such that a reviewer can compile the source and generate the same bytecode. It should also include the source that was originally stored at that address, if possible/applicable. If the two contracts are not identical, changes should be noted. If they are identical, the author should indicate why no changes are necessary (this is unlikely). Additionally, any relevant reviews, audits, and test cases should be included to the extent that they address the issues encountered with the original contract.

If accepted, an ERP could easily compile the block at while the changes are to take place, and the source of the actions (which would be the output of the script, in a standardized object output). These can be bundled with the client for seamless execution.


## ERP Approval Process
ERPs are a subclass of EIPs and will, therefore, follow the same approval process.

### Testing
*The ERP authors are currently seeking feedback from client teams about the proper testing procedures*

## Ethereum Client Implementation
Clients that choose to adopt the proposal outlined in this EIP will implement a module that scans a designated directory for SCO files (each time the client process launches) to construct a mapping between target blocks and SCO file names. When starting work on a new block, clients should first consult the set of SCO target blocks discovered and determine if there are any recovery actions required for the current block.

E.g. in this example, `erpsByTargetBlock` is the mapping between the target block number associated with each ERP's State Change Object and a reference (i.e. file name) to the resource with the actual data.

```
if (erpsByTargetBlock.get(currentBlock) != null) {
try {
applyRecoveryActions(erpsByTargetBlock.get(currentBlock));
}
catch (e) {
// recovery actions should be treated as a batch.
// If one fails, they all fail.
}
}
// continue with normal block processing...
```

The `applyRecoveryActions` method must apply the recovery actions in the same order as they are stored in the SCO file. Clients are responsible for ensuring that no State Change Action will result in an account transferring an amount that is greater than its current balance. The `toAddress` for both `weiTransfer` and `storeCode` should always be a valid address (i.e. never `0x0`).

Additionally, each block affected by an ERP should include extra data to indicate that the state change occurred. The extra data included in the block should be the erpId found in the SCO file, converted to hex (i.e. `hexStringToBytes(asciiToHex(erpId))`). Clients should also validate that the expected header appears in the target block if the block is received from a peer.

The ERP should link to pull requests for each client repository, and these pull requests should link back to the ERP and also contain its EIP preamble and summary.

Each PR associated with an ERP should consist of a single file (the SCO file) added to the client’s designated SCO directory. No additional client code should be required.

### Limitations of this EIP

This EIP is focused on standardizing how recovery proposals can be formatted, to optimize readability and eliminate or minimize as much as possible the potential for mistakes or intentional abuses.

The following are considered out of scope from this EIP:
- Which fund recovery proposals, if any, should be accepted for implementation.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which fund recovery proposals to accept is the only thing that matters. This EIP does all of the easy work and none of the hard work.

IMHO, this is leveraging the protocol to make it easier to increase the burden on human governance, whereas we should be seeking to minimize this burden.

- How common classes of recovery proposal plaintiff may organize ERPs representing a collective group of individual parties


## Rationale
The primary consideration for the approach described above was to minimize the amount of risk associated with recovery actions that would otherwise not have a viable solution. A secondary consideration was to standardize the format used in the proposals for recovery actions.

First, including a verification script guarantees that the way in which the recovery actions were determined is unambiguous. This does not mean that the recovery actions are necessarily correct, only that the logic used to determine them is fully specified and auditable.

Second, requiring that the output of the verification script is directly interpretable by client programs minimizes the work necessary for each client to adopt a particular ERP. It also reduces the risk that two clients will make different decisions about the implementation of a particular ERP.

Third, action types are intentionally limited and inflexible, which reduces the likelihood of unintended consequences or maliciously constructed files affecting the blockchain state. The format is easily extensible with new actions types if needed but that would require a separate EIP.


## Implementation
A reference implementation has been written for the EthereumJ platform. See the pull request [here](https://github.com/ethereum/ethereumj/pull/1004#commits-pushed-1105610).


## ERP Examples

This section will include examples and SCO resource files, as well as a brief tutorial on how to test using a private testnet.


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