mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-25 15:55:18 +00:00
update evmutil specs (#1356)
This commit is contained in:
parent
07661b17f9
commit
583711789d
@ -8,38 +8,36 @@ order: 1
|
|||||||
|
|
||||||
In order to use the EVM and be compatible with existing clients, the gas denom used by the EVM must be in 18 decimals. Since `ukava` has 6 decimals of precision, it cannot be used as the EVM gas denom directly.
|
In order to use the EVM and be compatible with existing clients, the gas denom used by the EVM must be in 18 decimals. Since `ukava` has 6 decimals of precision, it cannot be used as the EVM gas denom directly.
|
||||||
|
|
||||||
In order to use the Kava token on the EVM, the `evmutil` module provides an `EvmBankKeeper` that is responsible for the conversion of `ukava` and `akava`. A user's `akava` balance is stored in the `evmutil` store, while it's `ukava` balance remains stored in the cosmos-sdk `bank` module.
|
To use the Kava token on the EVM, the evmutil module provides an `EvmBankKeeper` that is responsible for the conversion of `ukava` and `akava`. A user's excess `akava` balance is stored in the `x/evmutil` store, while its `ukava` balance remains in the cosmos-sdk `x/bank` module.
|
||||||
|
|
||||||
## `EvmBankKeeper` Overview
|
## `EvmBankKeeper` Overview
|
||||||
|
|
||||||
The `EvmBankKeeper` provides access to an account's **total** `akava` balance and the ability to transfer, mint, and burn `akava`. If anything other than the `akava` denom is requested, the `EvmBankKeeper` will panic.
|
The `EvmBankKeeper` provides access to an account's total `akava` balance and the ability to transfer, mint, and burn `akava`. If anything other than the `akava` denom is requested, the `EvmBankKeeper` will panic.
|
||||||
|
|
||||||
```go
|
This keeper implements the `x/evm` module's `BankKeeper` interface to enable the usage of `akava` denom on the EVM.
|
||||||
type BankKeeper interface {
|
|
||||||
evmtypes.BankKeeper
|
|
||||||
SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
|
|
||||||
SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The keeper implements the `x/evm` module's `BankKeeper` interface to enable the usage of `akava` denom on the EVM.
|
### `x/evm` Parameter Requirements
|
||||||
|
|
||||||
### `x/evm` Parameter
|
|
||||||
|
|
||||||
Since the EVM denom `akava` is required to use the `EvmBankKeeper`, it is necessary to set the `EVMDenom` param of the `x/evm` module to `akava`.
|
Since the EVM denom `akava` is required to use the `EvmBankKeeper`, it is necessary to set the `EVMDenom` param of the `x/evm` module to `akava`.
|
||||||
|
|
||||||
### `akava` Balance Calculation
|
### Balance Calculation of `akava`
|
||||||
|
|
||||||
The `akava` balance of an account is derived from an account's **spendable** `ukava` balance times 10^12 (to derive its `akava` equivalent), plus the account's excess `akava` balance that can be accessed by the module `Keeper`.
|
The `akava` balance of an account is derived from an account's **spendable** `ukava` balance times 10^12 (to derive its `akava` equivalent), plus the account's excess `akava` balance that can be accessed via the module `Keeper`.
|
||||||
|
|
||||||
### Conversions Between `akava` & `ukava`
|
### `akava` <> `ukava` Conversion
|
||||||
|
|
||||||
When an account does not have sufficient `akava` to cover a transfer or burn, the `EvmBankKeeper` will try to swap 1 `ukava` to its equivalent `akava` amount. It does this by transferring 1 `ukava` from the sender to the `evmutil` module account, then adding the equivalent `akava` amount to the sender's balance via the keeper's `AddBalance`.
|
When an account does not have sufficient `akava` to cover a transfer or burn, the `EvmBankKeeper` will try to swap 1 `ukava` to its equivalent `akava` amount. It does this by transferring 1 `ukava` from the sender to the `x/evmutil` module account, then adding the equivalent `akava` amount to the sender's balance in the module state.
|
||||||
|
|
||||||
In reverse, if an account has enough `akava` balance for one or more `ukava`, the excess `akava` balance will be converted to `ukava`. This is done by removing the excess `akava` balance tracked by `evmutil` module store, then transferring the equivalent `ukava` coins from the `evmutil` module account to the target account.
|
In reverse, if an account has enough `akava` balance for one or more `ukava`, the excess `akava` balance will be converted to `ukava`. This is done by removing the excess `akava` balance in the module store, then transferring the equivalent `ukava` coins from the `x/evmutil` module account to the target account.
|
||||||
|
|
||||||
The swap logic ensures that all `akava` is backed by the equivalent `ukava` balance stored in the module account.
|
The swap logic ensures that all `akava` is backed by the equivalent `ukava` balance stored in the module account.
|
||||||
|
|
||||||
|
## ERC20 token <> sdk.Coin Conversion
|
||||||
|
|
||||||
|
`x/evmutil` enables the conversion between ERC20 tokens and sdk.Coins. This done through the use of the `MsgConvertERC20ToCoin` & `MsgConvertCoinToERC20` messages (see **[Messages](03_messages.md)**).
|
||||||
|
|
||||||
|
Only ERC20 contract address that are whitelist via the `EnabledConversionPairs` param (see **[Params](05_params.md)**) can be converted via these messages.
|
||||||
|
|
||||||
## Module Keeper
|
## Module Keeper
|
||||||
|
|
||||||
The module Keeper provides access to an account's excess `akava` balance and the ability to update the balance.
|
The module Keeper provides access to an account's excess `akava` balance and the ability to update the balance.
|
||||||
|
@ -4,15 +4,35 @@ order: 2
|
|||||||
|
|
||||||
# State
|
# State
|
||||||
|
|
||||||
## Genesis state
|
## Parameters and Genesis State
|
||||||
|
|
||||||
`GenesisState` defines the state that must be persisted when the blockchain stops/restarts in order for normal function of the committee module to resume.
|
`Parameters` define the list of conversion pairs allowed to be converted between Kava ERC20 tokens and sdk.Coins.
|
||||||
|
|
||||||
|
```protobuf
|
||||||
|
// Params defines the evmutil module params
|
||||||
|
message Params {
|
||||||
|
// enabled_conversion_pairs defines the list of conversion pairs allowed to be
|
||||||
|
// converted between Kava ERC20 and sdk.Coin
|
||||||
|
repeated ConversionPair enabled_conversion_pairs = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConversionPair defines a Kava ERC20 address and corresponding denom that is
|
||||||
|
// allowed to be converted between ERC20 and sdk.Coin
|
||||||
|
message ConversionPair {
|
||||||
|
// ERC20 address of the token on the Kava EVM
|
||||||
|
bytes kava_erc20_address = 1;
|
||||||
|
// Denom of the corresponding sdk.Coin
|
||||||
|
string denom = 2;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`GenesisState` defines the state that must be persisted when the blockchain stops/restarts in order for normal function of the evmutil module to resume.
|
||||||
|
|
||||||
```protobuf
|
```protobuf
|
||||||
message GenesisState {
|
message GenesisState {
|
||||||
repeated Account accounts = 1;
|
repeated Account accounts = 1 [(gogoproto.nullable) = false];
|
||||||
|
Params params = 2 [(gogoproto.nullable) = false];
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Account
|
## Account
|
||||||
@ -30,4 +50,4 @@ message Account {
|
|||||||
|
|
||||||
## Store
|
## Store
|
||||||
|
|
||||||
For complete implementation details for how items are stored, see [keys.go](../types/keys.go). The `evmutil` module store state consists of accounts.
|
For complete implementation details for how items are stored, see [keys.go](../types/keys.go). `x/evmutil` store state consists of accounts.
|
||||||
|
65
x/evmutil/spec/03_messages.md
Normal file
65
x/evmutil/spec/03_messages.md
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<!--
|
||||||
|
order: 3
|
||||||
|
-->
|
||||||
|
|
||||||
|
# Messages
|
||||||
|
|
||||||
|
Users can submit various messages to the evmutil module which trigger state changes detailed below.
|
||||||
|
|
||||||
|
## MsgConvertERC20ToCoin
|
||||||
|
|
||||||
|
`MsgConvertCoinToERC20` converts a Kava ERC20 coin to sdk.Coin.
|
||||||
|
|
||||||
|
```protobuf
|
||||||
|
service Msg {
|
||||||
|
// ConvertERC20ToCoin defines a method for converting Kava ERC20 to sdk.Coin.
|
||||||
|
rpc ConvertERC20ToCoin(MsgConvertERC20ToCoin) returns (MsgConvertERC20ToCoinResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
// MsgConvertERC20ToCoin defines a conversion from Kava ERC20 to sdk.Coin.
|
||||||
|
message MsgConvertERC20ToCoin {
|
||||||
|
// EVM 0x hex address initiating the conversion.
|
||||||
|
string initiator = 1;
|
||||||
|
// Kava bech32 address that will receive the converted sdk.Coin.
|
||||||
|
string receiver = 2;
|
||||||
|
// EVM 0x hex address of the ERC20 contract.
|
||||||
|
string kava_erc20_address = 3;
|
||||||
|
// ERC20 token amount to convert.
|
||||||
|
string amount = 4 [
|
||||||
|
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### State Changes
|
||||||
|
|
||||||
|
- The `EnabledConversionPairs` param from `x/evmutil` is checked to ensure the conversion pair is enabled.
|
||||||
|
- The initiator's ERC20 token from `kava_erc20_address` is locked by transferring it from the initiator's 0x address to the `x/evmutil` module account's 0x address.
|
||||||
|
- The same amount of sdk.Coin are minted for the corresponding denom of the `kava_erc20_address` in the `EnabledConversionPairs` param. The coins are then transferred to the receiver's Kava address.
|
||||||
|
|
||||||
|
## MsgConvertCoinToERC20
|
||||||
|
|
||||||
|
`MsgConvertCoinToERC20` converts sdk.Coin to Kava ERC20.
|
||||||
|
|
||||||
|
```protobuf
|
||||||
|
service Msg {
|
||||||
|
// ConvertCoinToERC20 defines a method for converting sdk.Coin to Kava ERC20.
|
||||||
|
rpc ConvertCoinToERC20(MsgConvertCoinToERC20) returns (MsgConvertCoinToERC20Response);
|
||||||
|
}
|
||||||
|
|
||||||
|
// MsgConvertCoinToERC20 defines a conversion from sdk.Coin to Kava ERC20.
|
||||||
|
message MsgConvertCoinToERC20 {
|
||||||
|
// Kava bech32 address initiating the conversion.
|
||||||
|
string initiator = 1;
|
||||||
|
// EVM 0x hex address that will receive the converted Kava ERC20 tokens.
|
||||||
|
string receiver = 2;
|
||||||
|
// Amount is the sdk.Coin amount to convert.
|
||||||
|
cosmos.base.v1beta1.Coin amount = 3;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### State Changes
|
||||||
|
|
||||||
|
- The `EnabledConversionPairs` param from `x/evmutil` is checked to ensure the conversion pair is enabled.
|
||||||
|
- The specified sdk.Coin is moved from the initiator's address to the module account and burned.
|
||||||
|
- The same amount of ERC20 coins are sent from the `x/evmutil` module account to the 0x receiver address.
|
31
x/evmutil/spec/04_events.md
Normal file
31
x/evmutil/spec/04_events.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<!--
|
||||||
|
order: 4
|
||||||
|
-->
|
||||||
|
|
||||||
|
# Events
|
||||||
|
|
||||||
|
The evmutil module emits the following events:
|
||||||
|
|
||||||
|
## Handlers
|
||||||
|
|
||||||
|
### MsgConvertERC20ToCoin
|
||||||
|
|
||||||
|
| Type | Attribute Key | Attribute Value |
|
||||||
|
| --------------------- | ------------- | ------------------ |
|
||||||
|
| convert_erc20_to_coin | erc20_address | `{erc20 address}` |
|
||||||
|
| convert_erc20_to_coin | initiator | `{initiator}` |
|
||||||
|
| convert_erc20_to_coin | receiver | `{receiver}` |
|
||||||
|
| convert_erc20_to_coin | amount | `{amount}` |
|
||||||
|
| message | module | evmutil |
|
||||||
|
| message | sender | {'sender address}' |
|
||||||
|
|
||||||
|
### MsgConvertCoinToERC20
|
||||||
|
|
||||||
|
| Type | Attribute Key | Attribute Value |
|
||||||
|
| --------------------- | ------------- | ------------------ |
|
||||||
|
| convert_coin_to_erc20 | initiator | `{initiator}` |
|
||||||
|
| convert_coin_to_erc20 | receiver | `{receiver}` |
|
||||||
|
| convert_coin_to_erc20 | erc20_address | `{erc20_address}` |
|
||||||
|
| convert_coin_to_erc20 | amount | `{amount}` |
|
||||||
|
| message | module | evmutil |
|
||||||
|
| message | sender | {'sender address}' |
|
22
x/evmutil/spec/05_params.md
Normal file
22
x/evmutil/spec/05_params.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<!--
|
||||||
|
order: 5
|
||||||
|
-->
|
||||||
|
|
||||||
|
# Parameters
|
||||||
|
|
||||||
|
The evmutil module contains the following parameters:
|
||||||
|
|
||||||
|
| Key | Type | Example |
|
||||||
|
| ---------------------- | ---------------------- | ------------- |
|
||||||
|
| EnabledConversionPairs | array (ConversionPair) | [{see below}] |
|
||||||
|
|
||||||
|
Example parameters for `ConversionPair`:
|
||||||
|
|
||||||
|
| Key | Type | Example | Description |
|
||||||
|
| ------------------ | ------ | -------------------------------------------- | ---------------------------------- |
|
||||||
|
| kava_erc20_Address | string | "0x43d8814fdfb9b8854422df13f1c66e34e4fa91fd" | ERC20 contract address |
|
||||||
|
| denom | string | "erc20/chain/usdc" | sdk.Coin denom for the ERC20 token |
|
||||||
|
|
||||||
|
## EnabledConversionPairs
|
||||||
|
|
||||||
|
The enabled conversion pairs parameter is an array of ConversionPair entries mapping an erc20 address to a sdk.Coin denom. Only erc20 contract addresses that are in this list can be converted to sdk.Coin and vice versa.
|
@ -13,15 +13,23 @@ parent:
|
|||||||
|
|
||||||
1. **[Concepts](01_concepts.md)**
|
1. **[Concepts](01_concepts.md)**
|
||||||
2. **[State](02_state.md)**
|
2. **[State](02_state.md)**
|
||||||
|
3. **[Messages](03_messages.md)**
|
||||||
|
4. **[Events](04_events.md)**
|
||||||
|
5. **[Params](05_params.md)**
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
The `evmutil` module provides additional functionalities on top of the `evm` module by storing additional state data for evm accounts and exposing an `EvmBankKeeper` that should be used by the `x/evm` keeper for bank operations.
|
The evmutil module provides additional functionalities on top of the evm module.
|
||||||
|
|
||||||
Two keepers are exposed by the module, `EvmBankKeeper` and the module `Keeper`.
|
### EVM `akava` Usage
|
||||||
|
|
||||||
The main purpose of the `EvmBankKeeper` is to allow the usage of the `akava` balance on the EVM through an account's existing `ukava` balance.
|
evmutil stores additional state data for evm accounts and exposes an `EvmBankKeeper` that should be used by the `x/evm` keeper for bank operations.
|
||||||
This is needed because the EVM gas token use 18 decimals, and since `ukava` has 6 decimals, it cannot be used as the EVM gas denom directly.
|
The purpose of the `EvmBankKeeper` is to allow the usage of the `akava` balance on the EVM via an account's existing `ukava` balance. This is needed because the EVM gas token use 18 decimals, and since `ukava` has 6 decimals, it cannot be used as the EVM gas denom directly.
|
||||||
|
|
||||||
The module `Keeper` provides access to an account's excess `akava` balance and the ability to update `akava` balances. This is needed by the `EvmBankKeeper` to store
|
For additional details on how balance conversions work, see **[Concepts](01_concepts.md)**.
|
||||||
excess `akava` balances since the `ukava` token only has 6 decimals of precision.
|
|
||||||
|
### ERC20 Token <> sdk.Coin Conversion
|
||||||
|
|
||||||
|
evmutil exposes messages to allow for the conversion of Kava ERC20 tokens and sdk.Coins via a whitelist.
|
||||||
|
|
||||||
|
For additional details on how these messages work, see **[Messages](03_messages.md)**.
|
||||||
|
Loading…
Reference in New Issue
Block a user