From b8680b90808b9111f43d7b0a5f361c53f7d48836 Mon Sep 17 00:00:00 2001 From: yito88 Date: Wed, 14 Jun 2023 16:03:35 +0900 Subject: [PATCH 1/4] update for multitoken --- .../specs/pages/base-ledger/fungible-token.md | 26 +----- packages/specs/pages/interoperability/ibc.md | 91 +++++++------------ 2 files changed, 38 insertions(+), 79 deletions(-) diff --git a/packages/specs/pages/base-ledger/fungible-token.md b/packages/specs/pages/base-ledger/fungible-token.md index d11ff4e2..8445096e 100644 --- a/packages/specs/pages/base-ledger/fungible-token.md +++ b/packages/specs/pages/base-ledger/fungible-token.md @@ -2,28 +2,10 @@ The fungible token validity predicate authorises token balance changes on the basis of conservation-of-supply and approval-by-sender. Namada implements a "multitoken" validity predicate, in that all tokens have the same logic and can share one VP (with appropriate storage distinctions). -A token balance is stored with a storage key. The token balance key should be `{token_addr}/balance/{owner_addr}` or `{token_addr}/{sub_prefix}/balance/{owner_addr}`. `{sub_prefix}` can have multiple key segments. These keys can be made with [token functions](https://github.com/anoma/namada/blob/5da82f093f10c0381865accba99f60c557360c51/core/src/types/token.rs). +A token balance is stored with a storage key. The token balance key should be `#Multitoken/{token_addr}/balance/{owner_addr}`. These keys can be made with [token functions](https://github.com/anoma/namada/blob/5da82f093f10c0381865accba99f60c557360c51/core/src/types/token.rs). -We can have multitoken balances with the same token and the same owner by `{sub_prefix}`, e.g. a token balance received over IBC is managed in `{token_addr}/ibc/{ibc_token_hash}/balance/{receiver_addr}`. It is distinguished from the receiver's original balance in `{token_addr}/balance/{receiver_addr}` to know which chain the token was transferred from. +We can have multitoken balances for the same owner by `{token_addr}`, e.g. a token balance received over IBC is managed in `#Multitoken/{ibc_token}/balance/{receiver_addr}`. It is distinguished from the receiver's original balance in `#Multitoken/{token_addr}/balance/{receiver_addr}` to know which chain the token was transferred from. -The transfers between the following keys are allowed: +Transfers between the balances with the same `{token_addr}` are allowed. Specifically, we can transfer a token from `#Multitoken/{token_addr}/balance/{sender_addr}` to `#Multitoken/{token_addr}/balance/{receiver_addr}`. -| Source | Target | -|----|----| -| `{token_addr}/balance/{sender_addr}` | `{token_addr}/balance/{receiver_addr}` | -| `{token_addr}/{sub_prefix}/balance/{sender_addr}` | `{token_addr}/{sub_prefix}/balance/{receiver_addr}` | - -A transfer can be allowed from a balance without `{sub_prefix}` to another one without `{sub_prefix}` and between balances with the same `{sub_prefix}`. The `{sub_prefix}` can be given with `--sub-prefix` argument when Namada CLI `namadac transfer`. - -Some special transactions can transfer to another balance with the different `{sub_prefix}`. IBC transaction transfers from a balance with `{sub_prefix}` to another balance with a different `{sub_prefix}`. IBC transfers handle the sub prefix `ibc/{port_id}/{channel_id}` for the IBC escrow, mint, and burn accounts and the sub prefix `ibc/{ibc_token_hash}` for receiving a token. IBC transaction transfers a token between the following keys: - -| IBC operation | Source | Target | -|----|----|----| -| Send (as the source) | `{token_addr}/balance/{sender_addr}` | `{token_addr}/ibc/{port_id}/{channel_id}/balance/IBC_ESCROW` | -| Send (to the source) | `{token_addr}/balance/{sender_addr}` | `{token_addr}/ibc/{port_id}/{channel_id}/balance/IBC_BURN` | -| Refund (when sending as the source) | `{token_addr}/ibc/{port_id}/{channel_id}/balance/IBC_ESCROW` | `{token_addr}/balance/{sender_addr}` | -| Refund (when sending to the source) | `{token_addr}/ibc/{port_id}/{channel_id}/balance/IBC_BURN` | `{token_addr}/balance/{sender_addr}` | -| Receive (as the source) | `{token_addr}/ibc/{port_id}/{channel_id}/balance/IBC_ESCROW` | `{token_addr}/balance/{receiver_addr}` | -| Receive (from the source) | `{token_addr}/ibc/{port_id}/{channel_id}/balance/IBC_MINT` | `{token_addr}/ibc/{ibc_token_hash}/balance/{receiver_addr}` | - -[IBC token validity predicate](https://github.com/anoma/namada/blob/5da82f093f10c0381865accba99f60c557360c51/shared/src/ledger/ibc/vp/token.rs) should validate these transfers. These special transfers like IBC should be validated by not only the fungible token validity predicate but also other validity predicates. \ No newline at end of file +These balance changes are validated by the multitoken validity prediccate. It also checks the minted or burned token. If a token is minted or burned, i.e. when `#Multitoken/{token_addr}/balance/#Mint` is updated in the transaction, not only the total minted balance is checked but also calling the minter's validity predicate is checked. The minter should be set in a transaction minting the token. For example, when a token is received over IBC, the received token will be minted for the receiver's balance `#Multitoken/{ibc_token}/balance/{receiver_addr}`. The minted balance `#Multitoken/{ibc_token/balance/#Mint` is also increased by the amount of the received token. The minted amount should be checked by the multitoken validity predicate. And, the multitoken validity predicate checks if the minter's validity predicate, the IBC validity predicate in this case, will be called (IBC validity predicate checks the minted amount is correct for the corresponding IBC operation). diff --git a/packages/specs/pages/interoperability/ibc.md b/packages/specs/pages/interoperability/ibc.md index 21bade76..5d2d41a6 100644 --- a/packages/specs/pages/interoperability/ibc.md +++ b/packages/specs/pages/interoperability/ibc.md @@ -1,30 +1,35 @@ # IBC integration * [IBC (Inter-blockchain communication protocol) spec](https://github.com/cosmos/ibc) -* [IBC integration in Namada](https://github.com/anoma/namada/blob/yuji/design_ibc/docs/src/explore/design/ledger/ibc.md) ## IBC transaction -An IBC transaction [`tx_ibc.wasm`](https://github.com/anoma/namada/blob/e3c2bd0b463b35d66fcc6d2643fd0e6509e03d99/wasm/wasm_source/src/tx_ibc.rs) is provided. We have to set an IBC message to the transaction data corresponding to execute an IBC operation. +An IBC transaction [`tx_ibc.wasm`](https://github.com/anoma/namada/blob/a5bad396992e5f66351088bde3bec73d83e769ba/wasm/wasm_source/src/tx_ibc.rs) is provided. We have to set an IBC message to the transaction data corresponding to execute an IBC operation. -The transaction decodes the data to an IBC message and handles IBC-related data, e.g. it makes a new connection ID and writes a new connection end for `MsgConnectionOpenTry`. The operations are implemented in [`IbcActions`](https://github.com/anoma/namada/blob/e3c2bd0b463b35d66fcc6d2643fd0e6509e03d99/core/src/ledger/ibc/actions.rs). The transaction doesn't check the validity for the state changes. IBC validity predicate and IBC token validity predicate are in charge of the validity. +The transaction decodes the data to an IBC message and handles IBC-related data, e.g. it makes a new connection ID and writes a new connection end for `MsgConnectionOpenTry`. The operations are implemented in [`IbcActions`](https://github.com/anoma/namada/blob/a5bad396992e5f66351088bde3bec73d83e769ba/core/src/ledger/ibc/mod.rs#L63). The transaction doesn't check the validity for the state changes. IBC validity predicate is in charge of the validity for IBC-related data. ## IBC validity predicate -[IBC validity predicate](https://github.com/anoma/namada/blob/e3c2bd0b463b35d66fcc6d2643fd0e6509e03d99/shared/src/ledger/ibc/vp/mod.rs) checks if an IBC transaction satisfies IBC protocol. When an IBC transaction is executed, i.e. a transaction changes the state of the key that contains [`InternalAddress::Ibc`](https://github.com/anoma/namada/blob/e3c2bd0b463b35d66fcc6d2643fd0e6509e03d99/core/src/types/address.rs#L446), IBC validity predicate (one of the native validity predicates) is executed. For example, if an IBC connection end is created in the transaction, IBC validity predicate validates the creation. If the creation with `MsgConnectionOpenTry` is invalid, e.g. the counterpart connection end doesn't exist, the validity predicate makes the transaction fail. +[IBC validity predicate](https://github.com/anoma/namada/blob/a5bad396992e5f66351088bde3bec73d83e769ba/shared/src/ledger/ibc/vp/mod.rs) checks if an IBC transaction satisfies IBC protocol. When an IBC transaction is executed, i.e. a transaction changes the state of the key that contains [`InternalAddress::Ibc`](https://github.com/anoma/namada/blob/a5bad396992e5f66351088bde3bec73d83e769ba/core/src/types/address.rs#L481), IBC validity predicate (one of the native validity predicates) is executed. For example, if an IBC connection end is created in the transaction, IBC validity predicate validates the creation. If the creation with `MsgConnectionOpenTry` is invalid, e.g. the counterpart connection end doesn't exist, the validity predicate makes the transaction fail. + +Specifically, the validity predicate mainly consists of two parts. +* Checking the state changes with the psuedo-execution +* Validating the IBC-related data + +The first part is the state change check. It executes the corresponding IBC operation and gets the post-states of the IBC-related data. Then, it checks whether the actual states of IBC-related data by the transaction are equal to the result of the pseudo execution. The second part is the validation of the IBC-related data. It validates that the corresponding data conforms to the IBC protocol. The psuedo-execution and the validation functions are imported from `ibc-rs`. ## Fungible Token Transfer The transfer of fungible tokens over an IBC channel on separate chains is defined in [ICS20](https://github.com/cosmos/ibc/blob/master/spec/app/ics-020-fungible-token-transfer/README.md). -In Namada, the sending tokens is triggered by a transaction having [MsgTransfer](https://github.com/informalsystems/ibc-rs/blob/0a952b295dbcf67bcabb79ce57ce92c9c8d7e5c6/modules/src/applications/ics20_fungible_token_transfer/msgs/transfer.rs#L20-L37) as transaction data. A packet including [`FungibleTokenPacketData`](https://github.com/anoma/namada/blob/e3c2bd0b463b35d66fcc6d2643fd0e6509e03d99/core/src/ledger/ibc/data.rs#L392) is made from the message in the transaction execution. +In Namada, the sending tokens is triggered by a transaction having [MsgTransfer](https://github.com/cosmos/ibc-rs/blob/014fec6958fedcfe9ed6ebfb2d0c28c2cb6487af/crates/ibc/src/applications/transfer/msgs/transfer.rs) as transaction data. A packet including [`PacketData`](https://github.com/cosmos/ibc-rs/blob/014fec6958fedcfe9ed6ebfb2d0c28c2cb6487af/crates/ibc/src/applications/transfer/packet.rs) for the transfer is made from the message in the transaction execution. -Namada chain receives the tokens by a transaction having [MsgRecvPacket](https://github.com/informalsystems/ibc-rs/blob/0a952b295dbcf67bcabb79ce57ce92c9c8d7e5c6/modules/src/core/ics04_channel/msgs/recv_packet.rs#L19-L23) which has the packet including `FungibleTokenPacketData`. +A Namada instance receives the tokens by a transaction having [MsgRecvPacket](https://github.com/cosmos/ibc-rs/blob/014fec6958fedcfe9ed6ebfb2d0c28c2cb6487af/crates/ibc/src/core/ics04_channel/msgs/recv_packet.rs) which has the packet including `PacketData` for the transfer. -The sending and receiving tokens in a transaction are validated by not only IBC validity predicate but also [IBC token validity predicate](https://github.com/anoma/namada/blob/e3c2bd0b463b35d66fcc6d2643fd0e6509e03d99/shared/src/ledger/ibc/vp/token.rs). IBC validity predicate validates if sending and receiving the packet is proper. IBC token validity predicate is also one of the native validity predicates and checks if the token transfer is valid. If the transfer is not valid, e.g. an unexpected amount is minted, the validity predicate makes the transaction fail. +The sending and receiving tokens in a transaction are validated by not only IBC validity predicate but also [IBC token validity predicate](https://github.com/anoma/namada/blob/e3c2bd0b463b35d66fcc6d2643fd0e6509e03d99/shared/src/ledger/ibc/vp/token.rs). IBC validity predicate validates if sending and receiving the packet is proper. If the transfer is not valid, e.g. an unexpected amount is minted, the validity predicate makes the transaction fail. -A transaction escrowing/unescrowing a token changes the escrow account's balance of the token. The key is `{token_addr}/ibc/{port_id}/{channel_id}/balance/IbcEscrow`. A transaction burning a token changes the burn account's balance of the token. The key is `{token_addr}/ibc/{port_id}/{channel_id}/balance/IbcBurn`. A transaction minting a token changes the mint account's balance of the token. The key is `{token_addr}/ibc/{port_id}/{channel_id}/balance/IbcMint`. The key including `IbcBurn` or `IbcMint` have the balance temporarily for validity predicates. It isn't committed to a block. `IbcEscrow`, `IbcBurn`, and `IbcMint` are addresses of [`InternalAddress`](https://github.com/anoma/namada/blob/e3c2bd0b463b35d66fcc6d2643fd0e6509e03d99/core/src/types/address.rs#L446) and actually they are encoded in the storage key. When these addresses are included in the changed keys after transaction execution, IBC token validity predicate is triggered. +A transaction escrowing/unescrowing a token changes the escrow account's balance of the token. The key is `#Multitoken/{token_addr}/balance/#Ibc`. A transaction burning a token decreases the minted balance of the token. The key is `#Multitoken/{token_addr}/balance/#Mint`. A transaction minting a token increases the minted balance of the token. The key is `#Multitoken/{token_addr}/balance/#Mint`. `#Multitoken`, `#Mint` and `#Ibc` are addresses of [`InternalAddress`](https://github.com/anoma/namada/blob/a5bad396992e5f66351088bde3bec73d83e769ba/core/src/types/address.rs#L473) and actually they are encoded in the storage key. Also, the multitoken validity predicate will be triggered and check the balance changes. -The receiver's account is `{token_addr}/ibc/{ibc_token_hash}/balance/{receiver_addr}`. `{ibc_token_hash}` is a hash calculated with the denomination prefixed with the port ID and channel ID. It is NOT the same as the normal account `{token_addr}/balance/{receiver_addr}`. That's because it should be origin-specific for transferring back to the source chain. We can transfer back the received token by setting `ibc/{ibc_token_hash}` or `{port_id}/{channel_id}/{token_addr}` as `denom` in `MsgTransfer`. +The receiver's account is `#Multitoken/{ibc_token}/balance/{receiver_addr}`. `{ibc_token}` is [`IbcToken(hash)`](https://github.com/anoma/namada/blob/a5bad396992e5f66351088bde3bec73d83e769ba/core/src/types/address.rs#L483) which has a hash calculated with the denomination prefixed with the port ID and channel ID. It is NOT the same as the normal account `#Multitoken/{src_token_addr}/balance/{receiver_addr}` of the token address on the source chain. That's because it should be origin-specific for transferring back to the source chain by binding the token address with the port and channel ID. We can transfer back the received token by setting `{ibc_token}` as `denom` in `MsgTransfer`. -For example, we transfer a token `#my_token` from a user `#user_a` on Chain A to a user `#user_b` on Chain B, then transfer back the token from `#user_b` to `#user_a`. The port ID and channel ID on Chain A for Chain B are `transfer` and `channel_42`, those on Chain B for Chain A are `transfer` and `channel_24`. The denomination in the `FungibleTokenTransferData` at the first transfer should be `#my_token`. +For example, we transfer a token `#my_token` from a user `#user_a` on Chain A to a user `#user_b` on Chain B, then transfer back the token from `#user_b` to `#user_a`. The port ID and channel ID on Chain A for Chain B are `transfer` and `channel_42`, those on Chain B for Chain A are `transfer` and `channel_24`. The denomination in the `PacketData` at the first transfer should be `#my_token`. 1. User A makes `MsgTransfer` as a transaction data and submits a transaction from Chain A ```rust let token = Some(Coin { @@ -32,40 +37,39 @@ For example, we transfer a token `#my_token` from a user `#user_a` on Chain A to amount: "100000".to_string(), }); let msg = MsgTransfer { - source_port, // transfer - source_channel, // channel_42 + port_id_on_a, // transfer + chan_id_on_a, // channel_42 token, - sender, // #user_a - receiver, // #user_b - timeout_height: Height::new(0, 1000), - timeout_timestamp: (Timestamp::now() + Duration::new(100, 0)).unwrap(), + sender, // #user_a + receiver, // #user_b + timeout_height_on_b, + timeout_timestamp_on_b, }; ``` -2. On Chain A, the specified amount of the token is transferred from the sender's account `#my_token/balance/#user_a` to the escrow account `#my_token/ibc/transfer/channel_42/balance/IbcEscrow` -3. On Chain B, the amount of the token is transferred from `#my_token/ibc/transfer/channel_24/balance/IbcMint` to `#my_token/ibc/{hash}/balance/#user_b` - - The `{hash}` is calculated from a string `transfer/channel_24/#my_token` with SHA256 - - The `{hash}` is a fixed length because of hashing even if the original denomination becomes too long with many prefixes after transferring through many chains +2. On Chain A, the specified amount of the token is transferred from the sender's account `#Multitoken/#my_token/balance/#user_a` to the escrow account `#Multitoken/#my_token/balance/#Ibc` +3. On Chain B, `#Multitoken/#my_token/balance/#Mint` is increased by the amount of the token, and `#Multitoken/{ibc_token}/balance/#user_b` + - The `{ibc_token}` is made with a hash calculated from a string `transfer/channel_24/#my_token` with SHA256 4. To transfer back, User B makes `MsgTransfer` and submits a transaction from Chain B ```rust let token = Some(Coin { - denom, // ibc/{hash} or transfer/channel_24/#my_token + denom, // {ibc_token} amount: "100000".to_string(), }); let msg = MsgTransfer { - source_port, // transfer - source_channel, // channel_24 + port_id_on_a, // transfer + chan_id_on_a, // channel_24 token, - sender, // #user_b - receiver, // #user_a - timeout_height: Height::new(0, 1000), - timeout_timestamp: (Timestamp::now() + Duration::new(100, 0)).unwrap(), + sender, // #user_b + receiver, // #user_a + timeout_height_on_b, + timeout_timestamp_on_b, }; ``` -5. On Chain B, the amount of the token is transferred from `#my_token/ibc/{hash}/balance/#user_b` to `#my_token/ibc/transfer/channel_24/IbcBurn` -6. On Chain A, the amount of the token is transferred from `#my_token/ibc/transfer/channel_42/balance/IbcEscrow` to `#my_token/balance/#user_a` +5. On Chain B, `#Multitoken/{ibc_token}/balance/#user_b` and `#Multitoken/{ibc_token}/balance/#Mint` are decreased by the amount of the token +6. On Chain A, the amount of the token is transferred from `#Multitoken/#my_token/balance/#Ibc` to `#Multitoken/#my_token/balance/#user_a` ## IBC message - +Basically, you don't need to make each IBC message. Namada CLI has `ibc-transfer` to transfer tokens over IBC. For other IBC operations, [Hermes](https://github.com/heliaxdev/hermes/tree/1.3.0-namada) can submit Namada transactions with [Hermes commands](https://hermes.informal.systems/documentation/commands/index.html). IBC messages are defined in `ibc-rs`. The message should be encoded with Protobuf (NOT with Borsh) as the following code to set it as a transaction data. ```rust @@ -78,30 +82,3 @@ pub fn make_ibc_data(message: impl Msg) -> Vec { tx_data } ``` - -* Client - - [MsgCreateAnyClient](https://github.com/informalsystems/ibc-rs/blob/5ddec6d2571b1376de7d9ebe7e353b3cd726c2d3/modules/src/core/ics02_client/msgs/create_client.rs#L19-L23) - - [MsgSubmitAnyMisbehaviour](https://github.com/informalsystems/ibc-rs/blob/1448a2bbc817da10b183b8479548a12344ba0e9c/modules/src/core/ics02_client/msgs/misbehavior.rs#L17-L24) (NOT supported yet) - - [MsgUpdateAnyClient](https://github.com/informalsystems/ibc-rs/blob/5ddec6d2571b1376de7d9ebe7e353b3cd726c2d3/modules/src/core/ics02_client/msgs/update_client.rs#L20-L24) - - [MsgUpgradeAnyClient](https://github.com/informalsystems/ibc-rs/blob/1448a2bbc817da10b183b8479548a12344ba0e9c/modules/src/core/ics02_client/msgs/upgrade_client.rs#L24-L31) - -* Connection - - [MsgConnectionOpenInit](https://github.com/informalsystems/ibc-rs/blob/1448a2bbc817da10b183b8479548a12344ba0e9c/modules/src/core/ics03_connection/msgs/conn_open_init.rs#L21-L27) - - [MsgConnectionOpenTry](https://github.com/informalsystems/ibc-rs/blob/1448a2bbc817da10b183b8479548a12344ba0e9c/modules/src/core/ics03_connection/msgs/conn_open_try.rs#L29-L38) - - [MsgConnectionOpenAck](https://github.com/informalsystems/ibc-rs/blob/1448a2bbc817da10b183b8479548a12344ba0e9c/modules/src/core/ics03_connection/msgs/conn_open_ack.rs#L20-L27) - - [MsgConnectionOpenConfirm](https://github.com/informalsystems/ibc-rs/blob/1448a2bbc817da10b183b8479548a12344ba0e9c/modules/src/core/ics03_connection/msgs/conn_open_confirm.rs#L19-L23) - -* Channel - - [MsgChannelOpenInit](https://github.com/informalsystems/ibc-rs/blob/1448a2bbc817da10b183b8479548a12344ba0e9c/modules/src/core/ics04_channel/msgs/chan_open_init.rs#L17-L21) - - [MsgChannelOpenTry](https://github.com/informalsystems/ibc-rs/blob/1448a2bbc817da10b183b8479548a12344ba0e9c/modules/src/core/ics04_channel/msgs/chan_open_try.rs#L22-L29) - - [MsgChannelOpenAck](https://github.com/informalsystems/ibc-rs/blob/1448a2bbc817da10b183b8479548a12344ba0e9c/modules/src/core/ics04_channel/msgs/chan_open_ack.rs#L18-L25) - - [MsgChannelOpenConfirm](https://github.com/informalsystems/ibc-rs/blob/1448a2bbc817da10b183b8479548a12344ba0e9c/modules/src/core/ics04_channel/msgs/chan_open_confirm.rs#L18-L23) - - [MsgRecvPacket](https://github.com/informalsystems/ibc-rs/blob/1448a2bbc817da10b183b8479548a12344ba0e9c/modules/src/core/ics04_channel/msgs/recv_packet.rs#L19-L23) - - [MsgAcknowledgement](https://github.com/informalsystems/ibc-rs/blob/1448a2bbc817da10b183b8479548a12344ba0e9c/modules/src/core/ics04_channel/msgs/acknowledgement.rs#L19-L24) - - [MsgChannelCloseInit](https://github.com/informalsystems/ibc-rs/blob/1448a2bbc817da10b183b8479548a12344ba0e9c/modules/src/core/ics04_channel/msgs/chan_close_init.rs#L18-L22) - - [MsgChannelCloseConfirm](https://github.com/informalsystems/ibc-rs/blob/1448a2bbc817da10b183b8479548a12344ba0e9c/modules/src/core/ics04_channel/msgs/chan_close_confirm.rs#L20-L25) - - [MsgTimeout](https://github.com/informalsystems/ibc-rs/blob/1448a2bbc817da10b183b8479548a12344ba0e9c/modules/src/core/ics04_channel/msgs/timeout.rs#L19-L24) - - [MsgTimeoutOnClose](https://github.com/informalsystems/ibc-rs/blob/1448a2bbc817da10b183b8479548a12344ba0e9c/modules/src/core/ics04_channel/msgs/timeout_on_close.rs#L18-L23) - -* ICS20 FungibleTokenTransfer - - [MsgTransfer](https://github.com/informalsystems/ibc-rs/blob/1448a2bbc817da10b183b8479548a12344ba0e9c/modules/src/applications/ics20_fungible_token_transfer/msgs/transfer.rs#L20-L37) From 11cc165120bb7669030f6b683e84a6b707830418 Mon Sep 17 00:00:00 2001 From: yito88 Date: Wed, 14 Jun 2023 22:38:28 +0900 Subject: [PATCH 2/4] fix typo --- packages/specs/pages/base-ledger/fungible-token.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/specs/pages/base-ledger/fungible-token.md b/packages/specs/pages/base-ledger/fungible-token.md index 8445096e..660dbe83 100644 --- a/packages/specs/pages/base-ledger/fungible-token.md +++ b/packages/specs/pages/base-ledger/fungible-token.md @@ -4,8 +4,8 @@ The fungible token validity predicate authorises token balance changes on the ba A token balance is stored with a storage key. The token balance key should be `#Multitoken/{token_addr}/balance/{owner_addr}`. These keys can be made with [token functions](https://github.com/anoma/namada/blob/5da82f093f10c0381865accba99f60c557360c51/core/src/types/token.rs). -We can have multitoken balances for the same owner by `{token_addr}`, e.g. a token balance received over IBC is managed in `#Multitoken/{ibc_token}/balance/{receiver_addr}`. It is distinguished from the receiver's original balance in `#Multitoken/{token_addr}/balance/{receiver_addr}` to know which chain the token was transferred from. +We can have multitoken balances for the same owner by `{token_addr}`, e.g. a token received over IBC is managed in `#Multitoken/{ibc_token}/balance/{receiver_addr}`. It is distinguished from the receiver's original balance in `#Multitoken/{token_addr}/balance/{receiver_addr}` to know which chain the token was transferred from. Transfers between the balances with the same `{token_addr}` are allowed. Specifically, we can transfer a token from `#Multitoken/{token_addr}/balance/{sender_addr}` to `#Multitoken/{token_addr}/balance/{receiver_addr}`. -These balance changes are validated by the multitoken validity prediccate. It also checks the minted or burned token. If a token is minted or burned, i.e. when `#Multitoken/{token_addr}/balance/#Mint` is updated in the transaction, not only the total minted balance is checked but also calling the minter's validity predicate is checked. The minter should be set in a transaction minting the token. For example, when a token is received over IBC, the received token will be minted for the receiver's balance `#Multitoken/{ibc_token}/balance/{receiver_addr}`. The minted balance `#Multitoken/{ibc_token/balance/#Mint` is also increased by the amount of the received token. The minted amount should be checked by the multitoken validity predicate. And, the multitoken validity predicate checks if the minter's validity predicate, the IBC validity predicate in this case, will be called (IBC validity predicate checks the minted amount is correct for the corresponding IBC operation). +These balance changes are validated by the multitoken validity predicate. It also checks the minted or burned token. If a token is minted or burned, i.e. when `#Multitoken/{token_addr}/balance/#Mint` is updated in the transaction, not only the total minted balance is checked but also calling the minter's validity predicate is checked. The minter should be set in a transaction minting the token. For example, when a token is received over IBC, the received token will be minted for the receiver's balance `#Multitoken/{ibc_token}/balance/{receiver_addr}`. The minted balance `#Multitoken/{ibc_token/balance/#Mint` is also increased by the amount of the received token. The minted amount should be checked by the multitoken validity predicate. And, the multitoken validity predicate checks if the minter's validity predicate, the IBC validity predicate in this case, will be called (IBC validity predicate checks the minted amount is correct for the corresponding IBC operation). From 6b4751f89681cc2537c7771cf38eae1abbf2f97c Mon Sep 17 00:00:00 2001 From: yito88 Date: Thu, 15 Jun 2023 14:43:03 +0900 Subject: [PATCH 3/4] fix minted key --- packages/specs/pages/base-ledger/fungible-token.md | 2 +- packages/specs/pages/interoperability/ibc.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/specs/pages/base-ledger/fungible-token.md b/packages/specs/pages/base-ledger/fungible-token.md index 660dbe83..171fe4c3 100644 --- a/packages/specs/pages/base-ledger/fungible-token.md +++ b/packages/specs/pages/base-ledger/fungible-token.md @@ -8,4 +8,4 @@ We can have multitoken balances for the same owner by `{token_addr}`, e.g. a tok Transfers between the balances with the same `{token_addr}` are allowed. Specifically, we can transfer a token from `#Multitoken/{token_addr}/balance/{sender_addr}` to `#Multitoken/{token_addr}/balance/{receiver_addr}`. -These balance changes are validated by the multitoken validity predicate. It also checks the minted or burned token. If a token is minted or burned, i.e. when `#Multitoken/{token_addr}/balance/#Mint` is updated in the transaction, not only the total minted balance is checked but also calling the minter's validity predicate is checked. The minter should be set in a transaction minting the token. For example, when a token is received over IBC, the received token will be minted for the receiver's balance `#Multitoken/{ibc_token}/balance/{receiver_addr}`. The minted balance `#Multitoken/{ibc_token/balance/#Mint` is also increased by the amount of the received token. The minted amount should be checked by the multitoken validity predicate. And, the multitoken validity predicate checks if the minter's validity predicate, the IBC validity predicate in this case, will be called (IBC validity predicate checks the minted amount is correct for the corresponding IBC operation). +These balance changes are validated by the multitoken validity predicate. It also checks the minted or burned token. If a token is minted or burned, i.e. when `#Multitoken/{token_addr}/balance/#Minted` is updated in the transaction, not only the total minted balance is checked but also calling the minter's validity predicate is checked. The minter should be set in a transaction minting the token. For example, when a token is received over IBC, the received token will be minted for the receiver's balance `#Multitoken/{ibc_token}/balance/{receiver_addr}`. The minted balance `#Multitoken/{ibc_token/balance/#Minted` is also increased by the amount of the received token. The minted amount should be checked by the multitoken validity predicate. And, the multitoken validity predicate checks if the minter's validity predicate, the IBC validity predicate in this case, will be called (IBC validity predicate checks the minted amount is correct for the corresponding IBC operation). diff --git a/packages/specs/pages/interoperability/ibc.md b/packages/specs/pages/interoperability/ibc.md index 5d2d41a6..1b9628fb 100644 --- a/packages/specs/pages/interoperability/ibc.md +++ b/packages/specs/pages/interoperability/ibc.md @@ -25,7 +25,7 @@ A Namada instance receives the tokens by a transaction having [MsgRecvPacket](ht The sending and receiving tokens in a transaction are validated by not only IBC validity predicate but also [IBC token validity predicate](https://github.com/anoma/namada/blob/e3c2bd0b463b35d66fcc6d2643fd0e6509e03d99/shared/src/ledger/ibc/vp/token.rs). IBC validity predicate validates if sending and receiving the packet is proper. If the transfer is not valid, e.g. an unexpected amount is minted, the validity predicate makes the transaction fail. -A transaction escrowing/unescrowing a token changes the escrow account's balance of the token. The key is `#Multitoken/{token_addr}/balance/#Ibc`. A transaction burning a token decreases the minted balance of the token. The key is `#Multitoken/{token_addr}/balance/#Mint`. A transaction minting a token increases the minted balance of the token. The key is `#Multitoken/{token_addr}/balance/#Mint`. `#Multitoken`, `#Mint` and `#Ibc` are addresses of [`InternalAddress`](https://github.com/anoma/namada/blob/a5bad396992e5f66351088bde3bec73d83e769ba/core/src/types/address.rs#L473) and actually they are encoded in the storage key. Also, the multitoken validity predicate will be triggered and check the balance changes. +A transaction escrowing/unescrowing a token changes the escrow account's balance of the token. The key is `#Multitoken/{token_addr}/balance/#Ibc`. A transaction burning a token decreases the minted balance of the token. The key is `#Multitoken/{token_addr}/balance/#Minted`. A transaction minting a token increases the minted balance of the token. The key is `#Multitoken/{token_addr}/balance/#Minted`. `#Multitoken`, `#Minted` and `#Ibc` are addresses of [`InternalAddress`](https://github.com/anoma/namada/blob/a5bad396992e5f66351088bde3bec73d83e769ba/core/src/types/address.rs#L473) and actually they are encoded in the storage key. Also, the multitoken validity predicate will be triggered and check the balance changes. The receiver's account is `#Multitoken/{ibc_token}/balance/{receiver_addr}`. `{ibc_token}` is [`IbcToken(hash)`](https://github.com/anoma/namada/blob/a5bad396992e5f66351088bde3bec73d83e769ba/core/src/types/address.rs#L483) which has a hash calculated with the denomination prefixed with the port ID and channel ID. It is NOT the same as the normal account `#Multitoken/{src_token_addr}/balance/{receiver_addr}` of the token address on the source chain. That's because it should be origin-specific for transferring back to the source chain by binding the token address with the port and channel ID. We can transfer back the received token by setting `{ibc_token}` as `denom` in `MsgTransfer`. @@ -47,7 +47,7 @@ For example, we transfer a token `#my_token` from a user `#user_a` on Chain A to }; ``` 2. On Chain A, the specified amount of the token is transferred from the sender's account `#Multitoken/#my_token/balance/#user_a` to the escrow account `#Multitoken/#my_token/balance/#Ibc` -3. On Chain B, `#Multitoken/#my_token/balance/#Mint` is increased by the amount of the token, and `#Multitoken/{ibc_token}/balance/#user_b` +3. On Chain B, `#Multitoken/#my_token/balance/#Minted` is increased by the amount of the token, and `#Multitoken/{ibc_token}/balance/#user_b` - The `{ibc_token}` is made with a hash calculated from a string `transfer/channel_24/#my_token` with SHA256 4. To transfer back, User B makes `MsgTransfer` and submits a transaction from Chain B ```rust @@ -65,7 +65,7 @@ For example, we transfer a token `#my_token` from a user `#user_a` on Chain A to timeout_timestamp_on_b, }; ``` -5. On Chain B, `#Multitoken/{ibc_token}/balance/#user_b` and `#Multitoken/{ibc_token}/balance/#Mint` are decreased by the amount of the token +5. On Chain B, `#Multitoken/{ibc_token}/balance/#user_b` and `#Multitoken/{ibc_token}/balance/#Minted` are decreased by the amount of the token 6. On Chain A, the amount of the token is transferred from `#Multitoken/#my_token/balance/#Ibc` to `#Multitoken/#my_token/balance/#user_a` ## IBC message From a897f26cac22cecb7b29367e68ff1be2b6a6811b Mon Sep 17 00:00:00 2001 From: yito88 Date: Mon, 26 Jun 2023 11:17:10 +0200 Subject: [PATCH 4/4] replace with --- packages/specs/pages/base-ledger/fungible-token.md | 4 ++-- packages/specs/pages/interoperability/ibc.md | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/specs/pages/base-ledger/fungible-token.md b/packages/specs/pages/base-ledger/fungible-token.md index 171fe4c3..4ae110ca 100644 --- a/packages/specs/pages/base-ledger/fungible-token.md +++ b/packages/specs/pages/base-ledger/fungible-token.md @@ -4,8 +4,8 @@ The fungible token validity predicate authorises token balance changes on the ba A token balance is stored with a storage key. The token balance key should be `#Multitoken/{token_addr}/balance/{owner_addr}`. These keys can be made with [token functions](https://github.com/anoma/namada/blob/5da82f093f10c0381865accba99f60c557360c51/core/src/types/token.rs). -We can have multitoken balances for the same owner by `{token_addr}`, e.g. a token received over IBC is managed in `#Multitoken/{ibc_token}/balance/{receiver_addr}`. It is distinguished from the receiver's original balance in `#Multitoken/{token_addr}/balance/{receiver_addr}` to know which chain the token was transferred from. +We can have multitoken balances for the same owner by `{token_addr}`, e.g. a token received over IBC is managed in `#Multitoken/{ibc_token}/balance/{receiver_addr}`. It is distinguished from the receiver's original balance in `#Multitoken/{token_addr}/balance/{receiver_addr}` to know which chain the token was transferred from. The `{ibc_token}` is explained in [IBC](../interoperability/ibc.md). Transfers between the balances with the same `{token_addr}` are allowed. Specifically, we can transfer a token from `#Multitoken/{token_addr}/balance/{sender_addr}` to `#Multitoken/{token_addr}/balance/{receiver_addr}`. -These balance changes are validated by the multitoken validity predicate. It also checks the minted or burned token. If a token is minted or burned, i.e. when `#Multitoken/{token_addr}/balance/#Minted` is updated in the transaction, not only the total minted balance is checked but also calling the minter's validity predicate is checked. The minter should be set in a transaction minting the token. For example, when a token is received over IBC, the received token will be minted for the receiver's balance `#Multitoken/{ibc_token}/balance/{receiver_addr}`. The minted balance `#Multitoken/{ibc_token/balance/#Minted` is also increased by the amount of the received token. The minted amount should be checked by the multitoken validity predicate. And, the multitoken validity predicate checks if the minter's validity predicate, the IBC validity predicate in this case, will be called (IBC validity predicate checks the minted amount is correct for the corresponding IBC operation). +These balance changes are validated by the multitoken validity predicate. It also checks the minted or burned token. If a token is minted or burned, i.e. when `#Multitoken/{token_addr}/balance/minted` is updated in the transaction, not only the total minted balance is checked but also calling the minter's validity predicate is checked. The minter should be set in a transaction minting the token. For example, when a token is received over IBC, the received token will be minted for the receiver's balance `#Multitoken/{ibc_token}/balance/{receiver_addr}`. The minted balance `#Multitoken/{ibc_token/balance/minted` is also increased by the amount of the received token. The minted amount should be checked by the multitoken validity predicate. And, the multitoken validity predicate checks if the minter's validity predicate, the IBC validity predicate in this case, will be called (IBC validity predicate checks the minted amount is correct for the corresponding IBC operation). diff --git a/packages/specs/pages/interoperability/ibc.md b/packages/specs/pages/interoperability/ibc.md index 1b9628fb..4c0b8be0 100644 --- a/packages/specs/pages/interoperability/ibc.md +++ b/packages/specs/pages/interoperability/ibc.md @@ -25,7 +25,7 @@ A Namada instance receives the tokens by a transaction having [MsgRecvPacket](ht The sending and receiving tokens in a transaction are validated by not only IBC validity predicate but also [IBC token validity predicate](https://github.com/anoma/namada/blob/e3c2bd0b463b35d66fcc6d2643fd0e6509e03d99/shared/src/ledger/ibc/vp/token.rs). IBC validity predicate validates if sending and receiving the packet is proper. If the transfer is not valid, e.g. an unexpected amount is minted, the validity predicate makes the transaction fail. -A transaction escrowing/unescrowing a token changes the escrow account's balance of the token. The key is `#Multitoken/{token_addr}/balance/#Ibc`. A transaction burning a token decreases the minted balance of the token. The key is `#Multitoken/{token_addr}/balance/#Minted`. A transaction minting a token increases the minted balance of the token. The key is `#Multitoken/{token_addr}/balance/#Minted`. `#Multitoken`, `#Minted` and `#Ibc` are addresses of [`InternalAddress`](https://github.com/anoma/namada/blob/a5bad396992e5f66351088bde3bec73d83e769ba/core/src/types/address.rs#L473) and actually they are encoded in the storage key. Also, the multitoken validity predicate will be triggered and check the balance changes. +A transaction escrowing/unescrowing a token changes the escrow account's balance of the token. The key is `#Multitoken/{token_addr}/balance/#Ibc`. A transaction burning a token decreases the minted balance of the token. The key is `#Multitoken/{token_addr}/balance/minted`. A transaction minting a token increases the minted balance of the token. The key is `#Multitoken/{token_addr}/balance/minted`. `#Multitoken` and `#Ibc` are addresses of [`InternalAddress`](https://github.com/anoma/namada/blob/a5bad396992e5f66351088bde3bec73d83e769ba/core/src/types/address.rs#L473) and actually they are encoded in the storage key. Also, the multitoken validity predicate will be triggered and check the balance changes. The receiver's account is `#Multitoken/{ibc_token}/balance/{receiver_addr}`. `{ibc_token}` is [`IbcToken(hash)`](https://github.com/anoma/namada/blob/a5bad396992e5f66351088bde3bec73d83e769ba/core/src/types/address.rs#L483) which has a hash calculated with the denomination prefixed with the port ID and channel ID. It is NOT the same as the normal account `#Multitoken/{src_token_addr}/balance/{receiver_addr}` of the token address on the source chain. That's because it should be origin-specific for transferring back to the source chain by binding the token address with the port and channel ID. We can transfer back the received token by setting `{ibc_token}` as `denom` in `MsgTransfer`. @@ -47,7 +47,7 @@ For example, we transfer a token `#my_token` from a user `#user_a` on Chain A to }; ``` 2. On Chain A, the specified amount of the token is transferred from the sender's account `#Multitoken/#my_token/balance/#user_a` to the escrow account `#Multitoken/#my_token/balance/#Ibc` -3. On Chain B, `#Multitoken/#my_token/balance/#Minted` is increased by the amount of the token, and `#Multitoken/{ibc_token}/balance/#user_b` +3. On Chain B, `#Multitoken/#my_token/balance/minted` is increased by the amount of the token, and `#Multitoken/{ibc_token}/balance/#user_b` - The `{ibc_token}` is made with a hash calculated from a string `transfer/channel_24/#my_token` with SHA256 4. To transfer back, User B makes `MsgTransfer` and submits a transaction from Chain B ```rust @@ -65,7 +65,7 @@ For example, we transfer a token `#my_token` from a user `#user_a` on Chain A to timeout_timestamp_on_b, }; ``` -5. On Chain B, `#Multitoken/{ibc_token}/balance/#user_b` and `#Multitoken/{ibc_token}/balance/#Minted` are decreased by the amount of the token +5. On Chain B, `#Multitoken/{ibc_token}/balance/#user_b` and `#Multitoken/{ibc_token}/balance/minted` are decreased by the amount of the token 6. On Chain A, the amount of the token is transferred from `#Multitoken/#my_token/balance/#Ibc` to `#Multitoken/#my_token/balance/#user_a` ## IBC message