diff --git a/x/asset/spec/02_state.md b/x/asset/spec/02_state.md index ac45452d..c054996a 100644 --- a/x/asset/spec/02_state.md +++ b/x/asset/spec/02_state.md @@ -14,7 +14,8 @@ The `x/asset` module keeps the following objects in state: | `Token` | Token information | `[]byte{2} + []byte(id)` | `[]byte{token}` | KV | | `TokenManager` | TokenManager info of a denom | `[]byte{3} + []byte(id)` | `[]byte{token_manager}` | KV | | `TokenDistributor` | TokenDistributor info of a denom | `[]byte{4} + []byte(id)` | `[]byte{token_distributor}`| KV | -| `FrozenAddresses` | Frozen Addresses bytecode | `[]byte{5} + []byte(id)` | `[]byte{[]address}` | KV | +| `WhitelistAddresses` | Whitelist Addresses bytecode | `[]byte{5} + []byte(id) + []byte(address)` | `[]byte{bool}` | KV | +| `DynamicPrecompiles` | Dynamic Contract Precompiles bytecode | `[]byte{6} + []byte(id) + []byte(address)` | `[]byte{bool}` | KV | ### Token @@ -28,6 +29,7 @@ type Token struct { Symbol string `protobuf:"bytes,4,opt,name=symbol,proto3" json:"symbol,omitempty"` Decimals uint32 `protobuf:"varint,5,opt,name=decimals,proto3" json:"decimals,omitempty"` Description string `protobuf:"bytes,6,opt,name=description,proto3" json:"description,omitempty"` + EVMAddress common.Address `protobuf:"bytes,7,opt,name=description,proto3" json:"description,omitempty"` } ``` @@ -35,10 +37,12 @@ The token id for the token will be derived from the Issuer and the Symbol with t The `issuer` is the address that create token. They can control all informations about the token, define other whitelist roles likes `manager` and `distributor`. `issuer` also can enable the token's single evm representation mode, which is showed in [EVM precompiles](README.md#asset-module-and-erc-20-precompiles). -### TokenManager +When create the token, `asset` module auto generate for it a evm address. This address is used as a dynamic precompiles. + +### TokenManagement ```go -type TokenManager struct{ +type TokenManagement struct{ Managers []string `protobuf:"bytes,7,rep,name=managers,proto3" json:"managers,omitempty"` AllowNewExtensions bool `protobuf:"varint,10,opt,name=allow_new_Extensions,json=allowNewExtensions,proto3" json:"allow_new_Extensions,omitempty"` ExtensionsList []string `protobuf:"bytes,11,rep,name=extensions_list,json=extensionsList,proto3" json:"extensions_list,omitempty"` @@ -48,27 +52,21 @@ type TokenManager struct{ By setting `allow_new_extensions`, `issuer` can specify whether they accept new extensions or not when creating a new token. If he permits it, when upgrading the chain, the new features will be automatically added to the `extensions_list`and the `manager` can then modify the `extensions_list` as he sees fit. Otherwise, the `manager` can not chaing the `extensions_list`. -### TokenDistributor +### TokenDistribution ```go -type TokenDistributor struct{ - Distributors []string `protobuf:"bytes,8,rep,name=distributors,proto3" json:"distributors,omitempty"` - DistributionSettings DistributionSettings `protobuf:"bytes,12,opt,name=distribution_settings,json=distributionSettings,proto3" json:"distribution_settings"` +type TokenDistribution struct{ + Distributors []string + MaxSupply math.Int } ``` -### DistributionSettings +`MaxSupply` defines the maximum number of tokens can be minted. -```go -type DistributionSettings struct{ - MaxSupply math.Int - MaxRatelimit math.Int -} -``` +### WhitelistAddresses -`MaxSupply` defines the maximum number of tokens can be minted. -`MaxRatelimit` defines the ratelimit of tokens can be minted per epoch (each epoch last 1 day). +`WhitelistAddresses` is a list of the address that's allow to create new token. -### FrozenAddress +### DynamicPrecompiles -List of addresses that is frozen by the manager. This only exists when the Token enable the `freeze` functionality. The addresses in list will not be able to execute any msg about the token. +`DynamicPrecompiles` is a list of the EVM precompile addresses. diff --git a/x/asset/spec/03_params.md b/x/asset/spec/03_params.md index 9cad431a..c7a05497 100644 --- a/x/asset/spec/03_params.md +++ b/x/asset/spec/03_params.md @@ -9,11 +9,7 @@ The asset module contains the following parameters: | Key | Type | Example | |----------------------|---------------|------------------------| | AllowExtensions | []string | ["burn","freeze"] | -| RatelimitDuration | time.Duration | "86400s" | -| WhitelistAddresses | []address | ["realio1..."] | ## Details - AllowExtensions: list of extensions that the module provides. They can be update after the chain upgrade to enable new extension add-on to the module. -- RatelimitDuration: duration of ratelimit for `mint` extension. -- WhitelistAddresses: list of the address that's allow to create new token. diff --git a/x/asset/spec/05_query.md b/x/asset/spec/05_query.md index 8faec520..5f7c6522 100644 --- a/x/asset/spec/05_query.md +++ b/x/asset/spec/05_query.md @@ -79,24 +79,3 @@ CLI: ```bash realio-networkd q all-tokens ``` - -## 4. QueryFrozenAddresses - -The `QueryFrozenAddresses` allows users to query all frozen addresses - -```go - type QueryFrozenAddressesRequest struct { - } -``` - -```go - type QueryFrozenAddressesResponse struct { - FrozenAddresses []address - } -``` - -CLI: - -```bash - realio-networkd q frozen-addresses -``` diff --git a/x/asset/spec/06_logic.md b/x/asset/spec/06_logic.md index 59a636cf..ba280ec3 100644 --- a/x/asset/spec/06_logic.md +++ b/x/asset/spec/06_logic.md @@ -6,61 +6,63 @@ order: 6 This file describes the core logics in this module. -## Functionality +## Extension -### Register new functionality +### Register new extension -To intergrate with the `asset module` Each type of functionality has to implement this interface +To intergrate with the `asset module` Each type of extension has to implement this interface ```go -type Functionality interface { +type Extension interface { RegisterInterfaces() MsgHandler() MsgHandler QueryHandler() QueryHandler CLI() *cobra.Command } -type MsgHandler func(context Context, funcMsg FunctionalityMsg) error +type MsgHandler func(context Context, funcMsg ExtensionMsg) error -type QueryHandler func(context Context, funcQuery FunctionalityMsg) error +type QueryHandler func(context Context, funcQuery ExtensionMsg) error ``` -This interface provides all the functionality necessary for a functionality, including a message handler, query handler and cli +This interface provides all the extension necessary for a extension, including a message handler, query handler and cli. -All the `FunctionalityMsg` of a functionality should return the name of that functionality when called `FunctionalityName()`. A message handler should handle all the `FunctionalityMsg` of that functionality. +All the `ExtensionMsg` of a extension should return the name of that extension when called `ExtensionName()`. A message handler should handle all the `ExtensionMsg` of that extension. -### Upgrade Functionalities +### Upgrade Extensions -All functionalities are located in a seperate packages, for example: asset/functionalities, therefore the exentsion or upgrade of functionalities is unrelated to core logic of `Asset` module, all the modification and addition happen in only asset/functionalities package. The core Asset module does not need to be aware of the specifics of functionality handling. It interacts with functionalitys through defined interfaces or protocols. +All extensions are located in a seperate packages, for example: asset/extensions, therefore the exentsion or upgrade of extensions is unrelated to core logic of `Asset` module, all the modification and addition happen in only asset/extensions package. The core Asset module does not need to be aware of the specifics of extension handling. It interacts with extensions through defined interfaces or protocols. -Each Priviliges has their own proto to define their state and execute/query messages. By assigning a distinct proto to each functionality, you ensure that the logic, messages, and data associated with one functionality do not interfere with or complicate the others. This also makes the design easier to understand, maintain, and scale. +Each Extensions has their own proto to define their state and execute/query messages. By assigning a distinct proto to each extension, you ensure that the logic, messages, and data associated with one extension do not interfere with or complicate the others. This also makes the design easier to understand, maintain, and scale. -When adding a `Functionality`, we calls `FunctionalityManager.AddFunctionality()` in `app.go` which inturn maps all the `FunctionalityMsg` of that functionality to its `MsgHandler`. This mapping logic will later be used when running a `MsgExecuteFunctionality`. +When adding a `Extension`, we calls `ExtensionRouting.AddExtension()` in `app.go` which inturn maps all the `ExtensionMsg` of that extension to its `MsgHandler`. This mapping logic will later be used when running a `MsgExecuteExtension`. ### Message/Query routing -The message we pass in `ExecuteFunctionality` is `msg.Any` type. This type refered that it could be any type of message. +The message we pass in `ExecuteExtension` is `msg.Any` type. This type refered that it could be any type of message. After receive this message, we will unpack the `msg.Any` type to an interface which implements what we want: ```go -type FunctionalityMsg interface { - FunctionalityName() string +type ExtensionMsg interface { + ExtensionName() string } ``` -As we defined the `AllowFunctionalities` in Params. If the message name is in the list, they will also exist there own interface in `FunctionalityRouting`. +As we defined the `AllowExtensions` in Params. If the message name is in the list, they will also exist there own interface in `ExtensionRouting`. -`FunctionalityRouting` acts as a centralized hub for routing messages, making it easy to manage and audit the flow of messages in the system. -It will route the `FunctionalityMsg` to its `MsgHandler` - where the msg is executed. In the `MsgHandler`, the message is further routed based on its type to the correct execution logic. This additional layer of routing within the MsgHandler ensures precise handling through message types, enabling fine-grained control and execution workflows. +`ExtensionRouting` acts as a centralized hub for routing messages, making it easy to manage and audit the flow of messages in the system. +It will route the `ExtensionMsg` to its `MsgHandler` - where the msg is executed. In the `MsgHandler`, the message is further routed based on its type to the correct execution logic. This additional layer of routing within the MsgHandler ensures precise handling through message types, enabling fine-grained control and execution workflows. -This flow will also work with `QueryHandler`, as long as we can unpack the `msg.Any` and get the name of the functionality. +This flow will also work with `QueryHandler`, as long as we can unpack the `msg.Any` and get the name of the extension. + +### Extension Store ## EVM interaction ### Enable EVM interface -The token includes a field named `evm_enable`, which allows it to integrate with the ERC20 standard and have an EVM-compatible contract address. This EVM address acts as an abstract interface layer that bypasses the typical logic within ERC20 or EVM contracts. Instead of executing logic directly in the contract, all actions are reflected to the `asset` module's predefined precompiles, where the token’s core state and functionalities are managed. +The token includes a field named `evm_enable`, which allows it to integrate with the ERC20 standard and have an EVM-compatible contract address. This EVM address acts as an abstract interface layer that bypasses the typical logic within ERC20 or EVM contracts. Instead of executing logic directly in the contract, all actions are reflected to the `asset` module's predefined precompiles, where the token’s core state and extensions are managed. -The token itself exists as a coin within the bank state, maintaining its own logic and functionalities independently of any ERC20 or EVM contract logic. The ERC20 contract deployed on the EVM serves purely as an interface, with its logic effectively bypassed. When other EVM contracts interact with this interface, their requests are forwarded via JSON-RPC calls to the `asset` module, which directly handles and executes the necessary operations. This is achieved by creating a `dynamic precompile` when `evm_enable` is activated, ensuring that the token’s behavior aligns with its internal state while still providing compatibility with the EVM ecosystem. +The token itself exists as a coin within the bank state, maintaining its own logic and extensions independently of any ERC20 or EVM contract logic. The ERC20 contract deployed on the EVM serves purely as an interface, with its logic effectively bypassed. When other EVM contracts interact with this interface, their requests are forwarded via JSON-RPC calls to the `asset` module, which directly handles and executes the necessary operations. This is achieved by creating a `dynamic precompile` when `evm_enable` is activated, ensuring that the token’s behavior aligns with its internal state while still providing compatibility with the EVM ecosystem. ### ERC20 Precompiles diff --git a/x/asset/spec/README.md b/x/asset/spec/README.md index 8871d2d7..1a34816e 100644 --- a/x/asset/spec/README.md +++ b/x/asset/spec/README.md @@ -11,9 +11,9 @@ parent: The Realio Asset module is centered around a token model where certain whitelisted accounts can issue their own token. A token issued by this module will be managed by two different roles, manager and distributor. These roles can be assigned to arbitrary accounts (could be either user accounts or module/contract account) by the token issuer. -Each token can choose to enable functionalities supported by the module. Currently, there are four functionalities supported: "mint", "freeze", "clawback", "transfer_auth", each handle a completely different logic. We wanna decouple the logic of these functionalities from the `Asset module`, meaning that they will be defined in separate packages/modules, thus, developers can customize new functionalities without modifying the `Asset Module`. Doing this allows our token model to be extensible while keeping the core logic of `Asset Module` untouched and simple, avoiding complicated migration when we integrating new features. +Each token can choose to enable extensions supported by the module. Currently, there are four extensions supported: "mint", "freeze", "clawback", "transfer_auth", each handle a completely different logic. We wanna decouple the logic of these extensions from the `Asset module`, meaning that they will be defined in separate packages/modules, thus, developers can customize new extensions without modifying the `Asset Module`. Doing this allows our token model to be extensible while keeping the core logic of `Asset Module` untouched and simple, avoiding complicated migration when we integrating new features. -The token manager's task is to choose what functionalities it wants to disable/enable for its token; and only the token manager can trigger those functionalities, except for the `mint` functionality which is handled by the `distributor`. +The token manager's task is to choose what extensions it wants to disable/enable for its token; and only the token manager can trigger those extensions, except for the `mint` extension which is handled by the `distributor`. ![asset_module](imgs/asset_module.png) @@ -27,9 +27,9 @@ To link an asset to ERC20 Precompile, user have to create a gov proposal so that ![asset_precompiles](imgs/asset_precompiles.png) -### Mapping functions +### Mapping extensions -ERC20 precompiles come with a limited number of functions which are: +ERC20 precompiles come with a limited number of extensions which are: - Transfer - TransferFrom @@ -37,9 +37,9 @@ ERC20 precompiles come with a limited number of functions which are: - IncreaseAllowance - DecreaseAllowance -These functions can be called from both AssetModule and EVM side (by metamask for example). +These extensions can be called from both AssetModule and EVM side (by metamask for example). -Other functions like: +Other extensions like: - Mint - Burn @@ -52,11 +52,15 @@ can only be called from Asset Module side. 1. **[Concept](01_concepts.md)** 2. **[State](02_state.md)** - - [Minter](02_state.md#minter) - - [Params](02_state.md#params) + - [Token](02_state.md#token) + - [TokenManagement](02_state.md#tokenmanagement) + - [TokenDistribution](02_state.md#tokendistribution) + - [WhitelistAddresses](02_state.md#whitelistaddresses) + - [DynamicPrecompiles](02_state.md#dynamicprecompiles) 3. **[Parameters](03_params.md)** 4. **[Messages](04_msgs.md)** -5. **[Client](05_client.md)** - - [CLI](05_client.md#cli) - - [gRPC](05_client.md#grpc) - - [REST](05_client.md#rest) +5. **[Query](05_query.md)** +6. **[Logic](06_logic.md)** + - [Extension](06_logic.md#extension) + - [EVM interaction](06_logic.md#evm-interaction) + \ No newline at end of file