Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spec update #18

Merged
merged 1 commit into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 4 additions & 8 deletions x/asset/spec/01_concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,14 @@ order: 1

## The Realio Asset Token Model

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 a set of `manager` and `distributor` accounts. These accounts are assigned role by the issuer of the asset.
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 `manager` accounts assigned by the issuer of the asset.

### System of privileged accounts
### Token extensions

Privileged accounts of a token are accounts that can execute certain actions for that token. There're are several types of extensions, each has its own state and logic to define the actions which accounts of said type can execute. We wanna decouple the logic of these extensions from the `Asset module` logic, meaning that extensions will be defined in separate packages/modules, thus, developers can customize their type of extension without modifying the `Asset Module`. Doing this allows our extensions system to be extensible while keeping the core logic of `Asset Module` untouched and simple, avoiding complicated migration when we expand our extensions system.

In order for a extension to integrate into the `Asset Module`. It has to implement the `Extension` interface and has its implementation registered via the method `AddExtension`. Once that is done, we can make said extension available onchain by executing `SoftwareUpgradeProposal` like a regular chain upgrade process.

Currently, there are 2 type of privileged accounts: `manager` and `distributor`. Each can execute different extensions. While `distributor` can control the `mint` extension and custom the `DistributionSettings`, the `manager` can execute the other extensions like `burn` or `freeze` and could modify the `extensions_list`. It's important to note that the `manager` can choose what extensions it wants to disable for its token.
Token extensions are additional features that can be flug-in for each token. There're are four types of extensions `Mint`, `Burn`, `Transfer Auth` and `Freeze`. The `Issuer` can choose what extensions to be included for his token at creation time, and only the `manager` can trigger the extension's logic.

### EVM enable

While it is useful to represent the token in bank module, enabling the token to be in action in evm environment is very convenient and pave the possibility of integrating new features into the ecosystem.
While it is the asset token in represented in the bank module, enabling the token interface in evm environment is very convenient and open up the possibility of integrating new features into the ecosystem.

Each token is automatically enabled to work in the evm environment when created, which means user can interact with the token through evm side like metamask or anyother evm wallet and more other protocol integrated in the future.
5 changes: 0 additions & 5 deletions x/asset/spec/02_state.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,3 @@ type TokenDistribution struct{

`WhitelistAddresses` is a list of the address that's allow to create new asset.

### ExtenstionStore

Each extension has its own store, which can be used in that extension execute or query operations. The store will be passed to the extension each time the extension is executed.

Each extension store has its own namespace, which is defined by token identifiers and extension name, which means that a combination of token and extension will create a new substore derived from the Asset module store.
64 changes: 19 additions & 45 deletions x/asset/spec/06_logic.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,60 +6,34 @@ order: 6

This file describes the core logics in this module.

## Extension

### Register new extension

To intergrate with the `asset module` Each type of extension has to implement this interface

```go
type Extension interface {
RegisterInterfaces()
MsgHandler() MsgHandler
QueryHandler() QueryHandler
CLI() *cobra.Command
}

type MsgHandler func(context Context, extensionStore store.KVStore, funcMsg ExtensionMsg) error

type QueryHandler func(context Context, extensionStore store.KVStore, funcQuery ExtensionMsg) error
```

This interface provides all the extension necessary for a extension, including a message handler, query handler and cli.
## Token namespace

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.
The token id/denom for the token will be derived from the Issuer and the Symbol with the format of asset/{Issuer}/{Symbol-Lowercase}. This allow many different issuers to issue token with the same symbol, differentiate their denom by including in their creator.

### Upgrade Extensions
## Token creation

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.
The token creation process involves the `Issuer` executing `MsgIssueToken` that defines info fields for the tokens. Amount those fields, these are the important feilds that dictacts how the token is operated:

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.
- List of extensions (imutable):
Choose what exetensions to enable for the token when creating it. The set of extensions is fixed, meaning that all extensions that are not enabled is permanently disabled.
- Manager (mutable):
Assign the manager account which could be an user account or smart contract account. If this field is blank then the manager will set to be the `issuer` of the token.
- Symbol (imutable):
This field will be used to derive the token denom, in the format `asset/{Issuer}/{Symbol-Lowercase}`.
- Initial Supply (imutable):
Upon creation an amount equal to the initial supply will be minted thus create a circulating supply for the token.
- Distributor (imutable):
Think of this account as the treasury manager account whose task is to distribute the token to holders. The initial supply will be minted to this account.

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 `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 ExtensionMsg interface {
ExtensionName() string
}
```

As we defined the `AllowExtensions` in Params. If the message name is in the list, they will also exist there own interface in `ExtensionRouting`.

`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.
## Extension

This flow will also work with `QueryHandler`, as long as we can unpack the `msg.Any` and get the name of the extension.
We'll go into details on how each of the extension works

### Extension Store
### Mint extension

Each extension has its own store, which can be used in that extension execute or query operations. The store will be passed to the extension each time the extension is executed and altered on execution.
### Burn extension

This structure help the extension achieve the isolation characteristic of the store, which helps maintain modularity and reduces the risk of unintended interactions or dependencies between extensions.
###

## EVM interaction

Expand Down
Loading