-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #11 from CosmWasm/ibc-outline
IBC Outline and first content
- Loading branch information
Showing
10 changed files
with
274 additions
and
0 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,18 @@ | ||
--- | ||
tags: ["ibc"] | ||
--- | ||
|
||
# Introduction | ||
|
||
IBC is a protocol that allows different blockchains to communicate with each | ||
other. It is a standard that defines how blockchains can send and receive | ||
messages to each other. This allows for the creation of a network of blockchains | ||
that can interact with each other. | ||
|
||
You can use the IBC protocol as a building block to create your own custom | ||
protocols on top of it, but you can also use existing protocols like the [ICS-20 | ||
token transfer protocol]. In the following sections, we will explain how both of | ||
these work. | ||
|
||
[ICS-20 token transfer protocol]: | ||
https://github.com/cosmos/ibc/blob/main/spec/app/ics-020-fungible-token-transfer/README.md |
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,6 @@ | ||
{ | ||
"getting-started": "Getting started", | ||
"basic-concepts": "Basic concepts", | ||
"existing-protocols": "Using existing protocols", | ||
"diy-protocol": "Build your own protocol" | ||
} |
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,26 @@ | ||
--- | ||
tags: ["ibc"] | ||
--- | ||
|
||
## Basic Concepts | ||
|
||
In order to understand how IBC works, it is important to understand some basic | ||
concepts: | ||
|
||
- **Port**: An identifier that corresponds to a single module on a chain. One | ||
module can have multiple ports. Each contract has its own unique port. | ||
- **Channel**: A connection between two ports on different blockchains that | ||
allows them to send packets to each other. Each port can have multiple | ||
channels. | ||
- **Relayer**: A service that is responsible for relaying packets between | ||
blockchains. Anyone can run a relayer. | ||
- **Packet**: A piece of binary data that is sent through a channel. It can time | ||
out if it is not delivered within a certain time frame. | ||
|
||
We will go into more detail on how these concepts are related to CosmWasm in the | ||
later sections, but this should give you some basic terminology to start with. | ||
If you want to learn more about IBC, you can read the [IBC specification] or | ||
check out the [IBC documentation]. | ||
|
||
[IBC specification]: https://github.com/cosmos/ibc | ||
[IBC documentation]: https://ibc.cosmos.network/main |
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,10 @@ | ||
--- | ||
tags: ["ibc"] | ||
--- | ||
|
||
# Build your own protocol | ||
|
||
In the following sections, we will guide you through the process of building | ||
your own IBC protocol. We will cover how to establish a channel between two | ||
chains, send and receive packets and how to handle timeouts and | ||
acknowledgements. |
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,4 @@ | ||
{ | ||
"channel-lifecycle": "Channel lifecycle", | ||
"packet-lifecycle": "Packet lifecycle" | ||
} |
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,35 @@ | ||
--- | ||
tags: ["ibc"] | ||
--- | ||
|
||
# Channel lifecycle | ||
|
||
A channel is a connection between two IBC ports that allows them to send packets | ||
to each other. In this section, we will cover how to establish a channel and how | ||
to close it. Since a channel is a connection between two ports, it can connect | ||
two chain modules, two contracts, or a module and a contract. | ||
|
||
## Establishing a channel | ||
|
||
In order to send packets between two chains, you need to establish a channel | ||
between them. This process involves two calls per chain. They are described | ||
below. Once the channel is established, you can start sending packets through | ||
it, which we will cover in the next section. | ||
|
||
### Channel open | ||
|
||
{/* `ibc_channel_open` called on both chains, explain differences */} | ||
|
||
### Channel connect | ||
|
||
{/* `ibc_channel_connect` called on both chains, explain differences */} | ||
|
||
## Closing a channel | ||
|
||
--- | ||
|
||
Notes: | ||
|
||
- reference basic concepts | ||
- relayer initiates this | ||
- explain ibc_channel_open & ibc_channel_connect |
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,17 @@ | ||
--- | ||
tags: ["ibc"] | ||
--- | ||
|
||
# Packet lifecycle | ||
|
||
## Sending a packet | ||
|
||
## Receiving a packet | ||
|
||
### Async acknowledgement | ||
|
||
if implemented until then | ||
|
||
## Receiving a packet acknowledgement | ||
|
||
## Receiving a packet timeout |
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,138 @@ | ||
--- | ||
tags: ["ibc", "ics20"] | ||
--- | ||
|
||
import { Callout } from "nextra/components"; | ||
|
||
# Using existing protocols | ||
|
||
The easiest way to use IBC is to use an already existing protocol. These | ||
protocols can either be implemented by the chain itself or by another contract. | ||
|
||
One example for the former is the `IbcMsg::Transfer` message, which causes an | ||
ICS20 transfer. This message is included in the CosmWasm standard library and | ||
causes the chain's IBC transfer module to send tokens to another chain. | ||
|
||
An example for the latter is the Nois protocol. It provides a proxy contract | ||
that handles all the IBC logic for you. For more information on Nois, check the | ||
[Nois documentation](https://docs.nois.network/dapp_devs/use_nois_randomness.html). | ||
We will later cover how to implement your own IBC protocol. | ||
|
||
## Example: `IbcMsg::Transfer` | ||
|
||
To initiate an ICS20 transfer, you need to attach an `IbcMsg::Transfer` message | ||
to your contract response like this: | ||
|
||
```rust template="execute" | ||
// construct the transfer message | ||
let msg = IbcMsg::Transfer { | ||
channel_id: "channel-0".to_string(), | ||
to_address: "cosmos1exampleaddress".to_string(), | ||
amount: Coin::new(123u128, "ucoin"), | ||
timeout: env.block.time.plus_seconds(60).into(), | ||
memo: None, | ||
}; | ||
|
||
// attach the message and return the response | ||
Ok(Response::new().add_message(msg)) | ||
``` | ||
|
||
The `channel_id` is the identifier of the channel you want to use for the | ||
transfer. Which channel that should be depends on the source and destination | ||
chain. You can find out the correct channel ID using a | ||
[block explorer](https://www.mintscan.io/cosmos/relayers). | ||
|
||
The `to_address` is the address on the _destination chain_ that should receive | ||
the tokens. | ||
|
||
The `amount` is the number and denomination of tokens to send. On the | ||
destination chain, the same amount will be received, but the denomination will | ||
be of the form `ibc/HASH`, where `HASH` is a SHA256 hash uniquely identifying | ||
the channel and the source chain denomination. To learn more about this, take a | ||
look at the [Cosmos Developer Portal]. | ||
|
||
The `timeout` can either be a timestamp or a block height, as measured on the | ||
destination chain. It is used to prevent the transfer from being stuck in limbo | ||
if the destination chain does not receive the packet. | ||
|
||
The `memo` is an optional field that can be used to attach a message to the | ||
transfer. It is often used for additional functionality like | ||
[packet-forward-middleware] or IBC Callbacks. | ||
|
||
[packet-forward-middleware]: | ||
https://github.com/cosmos/ibc-apps/tree/main/middleware/packet-forward-middleware | ||
[Cosmos Developer Portal]: | ||
https://tutorials.cosmos.network/tutorials/6-ibc-dev/#understand-ibc-denoms | ||
|
||
## ADR-8: IBC Callbacks | ||
|
||
When you send an ICS20 transfer as described above, you do not get any feedback | ||
on whether the transfer was successful or not and the destination does not get | ||
informed of its newfound wealth. To solve this problem, the ADR-8 specification | ||
was created. On the source chain, it provides callbacks when an IBC packet was | ||
acknowledged or timed out. On the destination chain, it triggers callbacks when | ||
a packet is received. | ||
|
||
<Callout> | ||
To receive callbacks, the chain needs to support IBC Callbacks for the message | ||
type. | ||
</Callout> | ||
|
||
### Enabling IBC Callbacks for a message | ||
|
||
You need to explicitly opt-in to IBC Callbacks for each message. In order to do | ||
this, you need to add some metadata to the message, including who should receive | ||
the callbacks. | ||
|
||
<Callout> | ||
The exact data format and how to add it to the message can vary, but for the | ||
`IbcMsg::Transfer` message, this data is in JSON format and needs to be added | ||
to the `memo` field. | ||
</Callout> | ||
|
||
To make this as easy as possible, we provide a helper type `IbcCallbackRequest` | ||
that you can use to generate the JSON: | ||
|
||
{/* TODO: add `template="execute"` once IBC Callbacks are merged */} | ||
|
||
```rust | ||
let _ = IbcMsg::Transfer { | ||
to_address: "cosmos1exampleaddress".to_string(), | ||
channel_id: "channel-0".to_string(), | ||
amount: Coin::new(10u32, "ucoin"), | ||
timeout: Timestamp::from_seconds(12345).into(), | ||
memo: Some(to_json_string(&IbcCallbackRequest::both(IbcSrcCallback { | ||
address: env.contract.address, | ||
gas_limit: None, | ||
}, IbcDstCallback { | ||
address: to_address.clone(), | ||
gas_limit: None, | ||
})).unwrap()), | ||
}; | ||
``` | ||
|
||
As you can see, you can request callbacks for both the source and destination | ||
chain. However, you can also request callbacks for only one of them. For this, | ||
you need to provide the address that should receive the callback and you can | ||
optionally set a gas limit for the callback execution. Please take a look at the | ||
`IbcCallbackRequest` docs for more information. | ||
|
||
<Callout> | ||
The `address` of the source callback always needs to be the contract address | ||
that sends the message (`env.contract.address`). Otherwise, the callback will | ||
error and the contract will not be called. | ||
</Callout> | ||
|
||
### Entrypoints | ||
|
||
TODO | ||
|
||
- two new entrypoints | ||
- `ibc_source_chain_callback` | ||
- `ibc_destination_chain_callback` | ||
|
||
--- | ||
|
||
Notes: | ||
|
||
- add link to IbcCallbackRequest docs when merged and deployed |
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,19 @@ | ||
--- | ||
tags: ["ibc"] | ||
--- | ||
|
||
# Getting started | ||
|
||
To get started, you need to enable the `stargate` feature of the `cosmwasm-std` | ||
crate. This will enable additional functionality that is not available on all | ||
chains, including IBC support. | ||
|
||
```toml | ||
cosmwasm-std = { version = "...", features = ["stargate"] } | ||
``` | ||
|
||
--- | ||
|
||
Notes: | ||
|
||
- add reference to core capabilities section |