This repository has been archived by the owner on Nov 30, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 161
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* evm: module specification * params and events * readme and messages * minor updates * concepts * genesis state concept * begin and end block * update parameters and genesis * state objects * state table * use permalink * init and export genesis * update abci * extra eips param * review comments * precision * link to photon doc
- Loading branch information
Showing
10 changed files
with
375 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
<!-- | ||
order: 1 | ||
--> | ||
|
||
# Concepts | ||
|
||
## EVM | ||
|
||
The Ethereum Virtual Machine [EVM](https://ethereum.org/en/developers/docs/evm/) is a state machine | ||
that provides the necessary tools to run or create a contract on a given state. | ||
|
||
## State DB | ||
|
||
The `StateDB` interface from geth represents an EVM database for full state querying of both | ||
contracts and accounts. The concrete type that fulfills this interface on Ethermint is the | ||
`CommitStateDB`. | ||
|
||
## State Object | ||
|
||
A `stateObject` represents an Ethereum account which is being modified. | ||
The usage pattern is as follows: | ||
|
||
* First you need to obtain a state object. | ||
* Account values can be accessed and modified through the object. | ||
|
||
## Genesis State | ||
|
||
The `x/evm` module `GenesisState` defines the state necessary for initializing the chain from a previous exported height. | ||
|
||
+++ https://github.com/cosmos/ethermint/blob/v0.3.1/x/evm/types/genesis.go#L14-L20 | ||
|
||
### Genesis Accounts | ||
|
||
The `GenesisAccount` type corresponds to an adaptation of the Ethereum `GenesisAccount` type. Its | ||
main difference is that the one on Ethermint uses a custom `Storage` type that uses a slice instead | ||
of maps for the evm `State` (due to non-determinism), and that it doesn't contain the private key | ||
field. | ||
|
||
It is also important to note that since the `auth` and `bank` SDK modules manage the accounts and | ||
balance state, the `Address` must correspond to an `EthAccount` that is stored in the `auth`'s | ||
module `AccountKeeper` and the balance must match the balance of the `EvmDenom` token denomination | ||
defined on the `GenesisState`'s `Param`. The values for the address and the balance amount maintain | ||
the same format as the ones from the SDK to make manual inspections easier on the genesis.json. | ||
|
||
+++ https://github.com/cosmos/ethermint/blob/v0.3.1/x/evm/types/genesis.go#L22-L30 | ||
|
||
### Transaction Logs | ||
|
||
On every Ethermint transaction, its result contains the Ethereum `Log`s from the state machine | ||
execution that are used by the JSON-RPC Web3 server for for filter querying. Since Cosmos upgrades | ||
don't persist the transactions on the blockchain state, we need to persist the logs the EVM module | ||
state to prevent the queries from failing. | ||
|
||
`TxsLogs` is the field that contains all the transaction logs that need to be persisted after an | ||
upgrade. It uses an array instead of a map to ensure determinism on the iteration. | ||
|
||
+++ https://github.com/cosmos/ethermint/blob/v0.3.1/x/evm/types/logs.go#L12-L18 | ||
|
||
### Chain Config | ||
|
||
The `ChainConfig` is a custom type that contains the same fields as the go-ethereum `ChainConfig` | ||
parameters, but using `sdk.Int` types instead of `*big.Int`. It also defines additional YAML tags | ||
for pretty printing. | ||
|
||
The `ChainConfig` type is not a configurable SDK `Param` since the SDK does not allow for validation | ||
against a previous stored parameter values or `Context` fields. Since most of this type's fields | ||
rely on the block height value, this limitation prevents the validation of of potential new | ||
parameter values against the current block height (eg: to prevent updating the config block values | ||
to a past block). | ||
|
||
If you want to update the config values, use an software upgrade procedure. | ||
|
||
+++ https://github.com/cosmos/ethermint/blob/v0.3.1/x/evm/types/chain_config.go#L16-L45 | ||
|
||
### Params | ||
|
||
See the [params](07_params.md) document for further information about parameters. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
<!-- | ||
order: 2 | ||
--> | ||
|
||
# State | ||
|
||
The `x/evm` module keeps the following objects in state: | ||
|
||
| | Key | Value | | ||
|-----------------|---------------------------------------------------|---------------------------| | ||
| Block Height | `[]byte{1} + []byte(block.Hash)` | `BigEndian(block.Height)` | | ||
| Bloom | `[]byte{2} + []byte(block.Height)` | `[]byte(Bloom)` | | ||
| Tx Logs | `[]byte{3} + []byte(tx.Hash)` | `amino([]Log)` | | ||
| Account Code | `[]byte{4} + []byte(code.Hash)` | `[]byte(Code)` | | ||
| Account Storage | `[]byte{5} + []byte(address) + []byte(state.Key)` | `[]byte(state.Value)` | | ||
| Chain Config | `[]byte{6}` | `amino(ChainConfig)` | | ||
|
||
## `CommitStateDB` | ||
|
||
`StateDB`s within the ethereum protocol are used to store anything within the IAVL tree. `StateDB`s | ||
take care of caching and storing nested states. It's the general query interface to retrieve | ||
contracts and accounts | ||
|
||
The Ethermint `CommitStateDB` is a concrete type that implements the EVM `StateDB` interface. | ||
Instead of using a trie and database for querying and persistence, the `CommitStateDB` uses | ||
`KVStores` (key-value stores) and Cosmos SDK `Keeper`s to facilitate state transitions. | ||
|
||
The `CommitStateDB` contains a store key that allows the DB to write to a concrete subtree of the | ||
multistore that is only accessible to the EVM module. | ||
|
||
+++ https://github.com/cosmos/ethermint/blob/v0.3.1/x/evm/types/statedb.go#L33-L85 | ||
|
||
The functionalities provided by the Ethermint `StateDB` are: | ||
|
||
* CRUD of `stateObject`s and accounts: | ||
* Balance | ||
* Code | ||
* Nonce | ||
* State | ||
* EVM module parameter getter and setter | ||
* State transition logic | ||
* Preparation: transaction index and hash, block hash | ||
* CRUD of transaction logs | ||
* Aggregate queries | ||
* Snapshot state | ||
* Identify current state with a revision | ||
* Revert state to a given revision | ||
* State transition and persistence | ||
* Preparation: tx and block context | ||
* Commit state objects | ||
* Finalise state objects | ||
* Export state for upgrades | ||
* Auxiliary functions | ||
* Copy state | ||
* Reset state | ||
|
||
## State Objects | ||
|
||
State objects are used by the VM which is unable to deal with database-level errors. Any error that occurs during a database read is memoized here and will eventually be returned by `StateDB.Commit`. | ||
|
||
The Ethermint `stateObject` is a concrete type that mimics the functionality from the `go-ethereum` | ||
private `stateObject` type. It keeps track of the interim values for the contract bytecode, storage | ||
state and balance of an `EthAccount`. | ||
|
||
The storage entries (original and "dirty") for each state object are represented as slices instead | ||
of maps since latter can cause non-deterministic block app hashes, which result in the chain | ||
halting. | ||
|
||
When a `stateObject` is committed during `EndBlock`. It sets sets the account contract code to store, as well as the dirty storage state. The account's nonce and the account balance are updated by calling the `auth` and `bank` module setter functions, respectively. | ||
|
||
+++ https://github.com/cosmos/ethermint/blob/v0.3.1/x/evm/types/state_object.go#L49-L81 | ||
|
||
The functionalities provided by the Ethermint `stateObject` are: | ||
|
||
* Storage state getter and setter (temporary) | ||
* Contract bytecode getter and setter (temporary) | ||
* Balance getter and setter (temporary) | ||
* Balance accounting (temporary) | ||
* Account nonce and address getter and setter (temporary) | ||
* Auxiliary functions: copy, RLP encoding, empty | ||
* Commit state object (final) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<!-- | ||
order: 3 | ||
--> | ||
|
||
# State Transitions | ||
|
||
<!-- define state transitions for accounts and storage --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<!-- | ||
order: 4 | ||
--> | ||
|
||
# Messages | ||
|
||
## MsgEthereumTx | ||
|
||
An EVM state transition can be achieved by using the `MsgEthereumTx`. This message encapsulates an | ||
Ethereum transaction as an SDK message and contains the necessary transaction data fields. | ||
|
||
One remark about the `MsgEthereumTx` is that it implements both the [`sdk.Msg`](https://github.com/cosmos/cosmos-sdk/blob/v0.39.2/types/tx_msg.go#L7-L29) and [`sdk.Tx`](https://github.com/cosmos/cosmos-sdk/blob/v0.39.2/types/tx_msg.go#L33-L41) | ||
interfaces (generally SDK messages only implement the former, while the latter is a group of | ||
messages bundled together). The reason of this, is because the `MsgEthereumTx` must not be included in a [`auth.StdTx`](https://github.com/cosmos/cosmos-sdk/blob/v0.39.2/x/auth/types/stdtx.go#L23-L30) (SDK's standard transaction type) as it performs gas and fee checks using the Ethereum logic from Geth instead of the Cosmos SDK checks done on the `auth` module `AnteHandler`. | ||
|
||
+++ https://github.com/cosmos/ethermint/blob/v0.3.1/x/evm/types/msg.go#L117-L124 | ||
|
||
+++ https://github.com/cosmos/ethermint/blob/v0.3.1/x/evm/types/tx_data.go#L12-L29 | ||
|
||
This message validation is expected to fail if: | ||
|
||
- `Data.Price` (i.e gas price) is ≤ 0. | ||
- `Data.Amount` is negative | ||
|
||
The transaction execution is expected to fail if: | ||
|
||
- Any of the custom `AnteHandler` Ethereum decorators checks fail: | ||
- Minimum gas amount requirements for transaction | ||
- Tx sender account doesn't exist or hasn't enough balance for fees | ||
- Account sequence doesn't match the transaction `Data.AccountNonce` | ||
- Message signature verification fails | ||
- EVM contract creation (i.e `evm.Create`) fails, or `evm.Call` fails |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<!-- | ||
order: 5 | ||
--> | ||
|
||
# ABCI | ||
|
||
## InitGenesis | ||
|
||
`InitGenesis` initializes the EVM module genesis state by setting the `GenesisState` fields to the | ||
store. In particular it sets the parameters, configuration, accounts and transaction logs. | ||
|
||
The function also performs the invariant that the EVM balance from the `GenesisAccount` matches the | ||
balance amount from the `EthAccount` as defined on the `auth` module. | ||
|
||
## ExportGenesis | ||
|
||
The `ExportGenesis` ABCI function exports the genesis state of the EVM module. In particular, it | ||
retrieves all the accounts with their bytecode, balance and storage, the transaction logs, and the | ||
EVM parameters and chain configuration. | ||
|
||
## BeginBlock | ||
|
||
The EVM module `BeginBlock` logic is executed prior to handling the state transitions from the | ||
transactions. The main objective of this function is to: | ||
|
||
* Set the block header hash mappings to the module state (`hash -> height` and `height -> hash`). | ||
This workaround is due to the fact that until the `v0.34.0` Tendermint version it wasn't possible | ||
to query and subscribe to a block by hash. | ||
|
||
* Reset bloom filter and block transaction count. These variables, which are fields of the EVM | ||
`Keeper`, are updated on every EVM transaction. | ||
|
||
## EndBlock | ||
|
||
The EVM module `EndBlock` logic occurs after executing all the state transitions from the | ||
transactions. The main objective of this function is to: | ||
|
||
* Update the accounts. This operation retrieves the current account and balance values for each | ||
state object and updates the account represented on the stateObject with the given values. This is | ||
done since the account might have been updated by transactions other than the ones defined by the | ||
`x/evm` module, such as bank send or IBC transfers. | ||
* Commit dirty state objects and delete empty ones from the store. This operation writes the | ||
contract code to the key value store in the case of contracts and updates the account's balance, | ||
which is set to the the bank module's `Keeper`. | ||
* Clear account cache. This clears cache of state objects to handle account changes outside of the | ||
EVM. | ||
* Store the block bloom to state. This is due for Web3 compatibility as the Ethereum headers contain | ||
this type as a field. The Ethermint RPC uses this query to construct an Ethereum Header from a | ||
Tendermint Header. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<!-- | ||
order: 6 | ||
--> | ||
|
||
# Events | ||
|
||
The EVM module emits the Cosmos SDK [events](./../../../docs/quickstart/events.md#sdk-and-tendermint-events) after a state execution. It can be expected that the type `message`, with an | ||
attribute key of `action` will represent the first event for each message being processed as emitted | ||
by the Cosmos SDK's `Baseapp` (i.e the the basic application that implements Tendermint Core's ABCI | ||
interface). | ||
|
||
## MsgEthereumTx | ||
|
||
| Type | Attribute Key | Attribute Value | | ||
|----------|---------------|-----------------| | ||
| ethereum | `"amount"` | `{amount}` | | ||
| ethereum | `"recipient"` | `{eth_address}` | | ||
| message | `"sender"` | `{eth_address}` | | ||
| message | `"action"` | `"ethereum"` | | ||
| message | `"module"` | `"evm"` | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
<!-- | ||
order: 7 | ||
--> | ||
|
||
# Parameters | ||
|
||
The evm module contains the following parameters: | ||
|
||
| Key | Type | Default Value | | ||
|----------------|--------|---------------| | ||
| `EVMDenom` | string | `"aphoton"` | | ||
| `EnableCreate` | bool | `true` | | ||
| `EnableCall` | bool | `true` | | ||
| `ExtraEIPs` | []int | TBD | | ||
|
||
## EVM denom | ||
|
||
The evm denomination parameter defines the token denomination used on the EVM state transitions and | ||
gas consumption for EVM messages. | ||
|
||
The EVM Denom is used on the following cases: | ||
|
||
* `AnteHandler`: for calculating sufficient balance to pay for gas cost or transaction fees. | ||
* `journal`: to revert certain state executions (`balanceChange` and `suicideChange`). | ||
* `stateObject`: to track the `evm_denom` balance of the object account. | ||
* `CommitStateDB`: to update account balance from an existing state object. | ||
|
||
For example, on Ethereum, the `evm_denom` would be `ETH`. In the case of Ethermint, the default denomination is the [atto photon](./../../../docs/basics/photon.md). In terms of precision, the `PHOTON` and `ETH` share the same value, _i.e_ `1 PHOTON = 10^18 atto photon` and `1 ETH = 10^18 wei`. | ||
|
||
::: danger | ||
SDK applications that want to import the EVM module as a dependency will need to set their own `evm_denom` (i.e not `"aphoton"`). | ||
::: | ||
|
||
## Enable Create | ||
|
||
The enable create parameter toggles state transitions that use the `vm.Create` function. When the | ||
parameter is disabled, it will prevent all contract creation functionality. | ||
|
||
## Enable Transfer | ||
|
||
The enable transfer toggles state transitions that use the `vm.Call` function. When the parameter is | ||
disabled, it will prevent transfers between accounts and executing a smart contract call. | ||
|
||
## Extra EIPs | ||
|
||
The extra EIPs parameter defines the set of activateable Ethereum Improvement Proposals ([EIPs](https://ethereum.org/en/eips/)) | ||
on the Ethereum VM `Config` that apply custom jump tables. | ||
The supported activateable EIPS are: | ||
|
||
* [EIP 1344](https://eips.ethereum.org/EIPS/eip-1344) | ||
* [EIP 1884](https://eips.ethereum.org/EIPS/eip-1884) | ||
* [EIP 2200](https://eips.ethereum.org/EIPS/eip-2200) | ||
* [EIP 2315](https://eips.ethereum.org/EIPS/eip-2315) | ||
* [EIP 2929](https://eips.ethereum.org/EIPS/eip-2929) |
Oops, something went wrong.