mirror of https://github.com/status-im/EIPs.git
Merge pull request #1702 from sorpaas/sp-account-versioining
EIP-1702: Generalized Account Versioning Scheme
This commit is contained in:
commit
29f9e1842e
|
@ -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.
|
Loading…
Reference in New Issue