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

EIP-1702: Generalized Account Versioning Scheme #1702

Merged
merged 8 commits into from
Apr 2, 2019
129 changes: 129 additions & 0 deletions EIPS/eip-1702.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
---
eip: 1702
title: Generalized Account Versioning Scheme
author: Wei Tang (@sorpaas)
discussions-to: https://github.com/sorpaas/EIPs/issues/2
status: Draft
type: Standards Track
category: Core
created: 2017-12-30
---

## Abstract

This defines a method of hard forking while maintaining the exact
functionality of existing account by allowing multiple versions of the
virtual machines to execute in the same block. This is also useful to
define future account state structures when we introduce the on-chain
WebAssembly virtual machine.

## Motivation

By allowing account versioning, we can execute different virtual
machine for contracts created at different times. This allows breaking
features to be implemented while making sure existing contracts work
as expected.

Note that this specification might not apply to all hard forks. We
have emergency hard forks in the past due to network attacks. Whether
they should maintain existing account compatibility should be
evaluated in individual basis. If the attack can only be executed once
against some particular contracts, then the scheme defined here might
still be applicable. Otherwise, having a plain emergency hard fork
might still be a good idea.

## Specification

### Account State

Re-define account state stored in the world state trie to have 5
items: `nonce`, `balance`, `storageRoot`, `codeHash`, and
`version`. The newly added field `version` is a 256-bit integer. When
`version` is zero, the account is RLP-encoded with the first 4
items. When `version` is not zero, the account is RLP-encoded with 5
items.

### Contract Deployment

In Ethereum, a contract has a deployment method, either by a contract
creation transaction, or by another contract. If we regard this
deployment method a contract's *parent*, then we find them forming a
family of contracts, with the *root* being a contract creation
transaction.

We let a family of contracts to always have the same `version`. That
is, `CREATE` and `CREATE2` will always deploy contract that has the
same `version` as the calling `address`.

### Validation

A new phrase, *validation* is added to contract deployment (by
`CREATE` / `CREATE2` opcodes, or by contract creation
transaction). When `version` is `0`, the phrase does nothing and
always succeeds. Future VM versions can define additional validation
that has to be passed.

If the validation phrase fails, deployment does not proceed and return
out-of-gas.

### Contract Execution

VM version used in contract execution is determined via calling
`address` (`I_a` in yellow paper). Precompiled contract does not have
version.

### Contract Creation Transaction

Define `LATEST_VERSION` in a hard fork to be the latest supported VM
version. A contract creation transaction is always executed in
`LATEST_VERSION`. Before a contract creation transaction is executed,
run *validation* on the contract creation code. If it does not pass,
return out-of-gas.

#### Alternative Design for Contract Creation Transaction

This provides an alternative design that allows contract to be created
in multiple versions.

Add an additional field `version` (256-bit integer) in contract
creation transaction. So it becomes `nonce`, `gasprice`, `startgas`,
`to`, `value`, `data`, `v`, `r`, `s`, `version`. When signing or
recovering, sign ten items, with `v`, `r`, `s` as defined by EIP-155.

The transaction would be executed in `version` supplied. If `version`
is not supported or *validation* does not pass, return out-of-gas.

## Discussions

### Performance

Currently nearly all full node implementations uses config parameters
to decide which virtual machine version to use. Switching vitual
machine version is simply an operation that changes a pointer using a
different set of config parameters. As a result, this scheme has
nearly zero impact to performance.

### Smart Contract Boundary and Formal Verification

Many current efforts are on-going for getting smart contracts formally
verified. However, for any hard fork that introduces new opcodes or
change behaviors of existing opcodes would break the verification of
an existing contract has previously be formally verified. Using the
scheme described here, we define the boundary of how a smart contract
interacts with the blockchain and it might help the formal
verification efforts:

* A smart contract has only immutable access to information of
blockchain account balances and codes.
* A smart contract has only immutable access of block information.
* A smart contract or a contract creation transaction can modify only
its own storage and codes.
* A smart contract can only interact with the blockchain in a mutable
way using `CALL` or `CREATE`.

### WebAssembly

This scheme can also be helpful when we deploy on-chain WebAssembly
virtual machine. In that case, WASM contracts and EVM contracts can
co-exist and the execution boundary and interaction model are clearly
defined as above.