2019-01-15 23:15:25 +00:00
|
|
|
---
|
2019-01-15 23:19:13 +00:00
|
|
|
eip: 1702
|
2019-01-15 23:15:25 +00:00
|
|
|
title: Generalized Account Versioning Scheme
|
|
|
|
author: Wei Tang (@sorpaas)
|
2019-01-15 23:20:02 +00:00
|
|
|
discussions-to: https://github.com/sorpaas/EIPs/issues/2
|
2019-01-15 23:15:25 +00:00
|
|
|
status: Draft
|
|
|
|
type: Standards Track
|
|
|
|
category: Core
|
|
|
|
created: 2017-12-30
|
|
|
|
---
|
|
|
|
|
|
|
|
## Abstract
|
|
|
|
|
2019-04-02 13:35:24 +00:00
|
|
|
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.
|
2019-01-15 23:15:25 +00:00
|
|
|
|
|
|
|
## Motivation
|
|
|
|
|
2019-04-02 13:35:24 +00:00
|
|
|
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.
|
2019-01-15 23:15:25 +00:00
|
|
|
|
2019-04-02 13:35:24 +00:00
|
|
|
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.
|
2019-01-15 23:15:25 +00:00
|
|
|
|
|
|
|
## Specification
|
|
|
|
|
|
|
|
### Account State
|
|
|
|
|
2019-04-02 13:35:24 +00:00
|
|
|
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.
|
2019-01-15 23:15:25 +00:00
|
|
|
|
2019-04-02 13:35:24 +00:00
|
|
|
### Contract Deployment
|
2019-01-15 23:15:25 +00:00
|
|
|
|
2019-04-02 13:35:24 +00:00
|
|
|
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.
|
2019-01-15 23:15:25 +00:00
|
|
|
|
2019-04-02 13:35:24 +00:00
|
|
|
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`.
|
2019-01-15 23:15:25 +00:00
|
|
|
|
2019-04-02 13:35:24 +00:00
|
|
|
### Validation
|
2019-01-15 23:15:25 +00:00
|
|
|
|
2019-04-02 13:35:24 +00:00
|
|
|
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.
|
2019-01-15 23:15:25 +00:00
|
|
|
|
2019-04-02 13:35:24 +00:00
|
|
|
If the validation phrase fails, deployment does not proceed and return
|
|
|
|
out-of-gas.
|
2019-01-15 23:15:25 +00:00
|
|
|
|
2019-04-02 13:35:24 +00:00
|
|
|
### Contract Execution
|
2019-01-15 23:15:25 +00:00
|
|
|
|
2019-04-02 13:35:24 +00:00
|
|
|
VM version used in contract execution is determined via calling
|
2019-04-02 19:29:11 +00:00
|
|
|
`address` (`I_a` in yellow paper).
|
2019-01-15 23:15:25 +00:00
|
|
|
|
2019-04-02 13:35:24 +00:00
|
|
|
### 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.
|
2019-01-15 23:15:25 +00:00
|
|
|
|
2019-04-02 19:29:11 +00:00
|
|
|
### Precompiled Contract and Externally-owned Address
|
|
|
|
|
|
|
|
Precompiled contracts and externally-owned addresses do not have
|
|
|
|
`version`. If a message-call transaction or `CALL` / `CALLCODE` /
|
|
|
|
`STATICCALL` / `DELEGATECALL` touches a new externally-owned address
|
|
|
|
or a non-existing precompiled contract address, it is always created
|
|
|
|
with `version` field being `0`.
|
|
|
|
|
2019-01-15 23:15:25 +00:00
|
|
|
## Discussions
|
|
|
|
|
|
|
|
### Performance
|
|
|
|
|
2019-04-02 13:35:24 +00:00
|
|
|
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.
|
2019-01-15 23:15:25 +00:00
|
|
|
|
|
|
|
### WebAssembly
|
|
|
|
|
2019-04-02 13:35:24 +00:00
|
|
|
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.
|