diff --git a/src/pages/_meta.json b/src/pages/_meta.json index f04ea4b2..7095d526 100644 --- a/src/pages/_meta.json +++ b/src/pages/_meta.json @@ -1,6 +1,7 @@ { "index": "Welcome", "core": "CosmWasm Core", + "ibc": "IBC", "sylvia": "Sylvia", "cw-multi-test": "MultiTest", "how-to-doc": "How to doc", diff --git a/src/pages/ibc.mdx b/src/pages/ibc.mdx new file mode 100644 index 00000000..3c911e85 --- /dev/null +++ b/src/pages/ibc.mdx @@ -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 diff --git a/src/pages/ibc/_meta.json b/src/pages/ibc/_meta.json new file mode 100644 index 00000000..7135e07f --- /dev/null +++ b/src/pages/ibc/_meta.json @@ -0,0 +1,6 @@ +{ + "getting-started": "Getting started", + "basic-concepts": "Basic concepts", + "existing-protocols": "Using existing protocols", + "diy-protocol": "Build your own protocol" +} diff --git a/src/pages/ibc/basic-concepts.mdx b/src/pages/ibc/basic-concepts.mdx new file mode 100644 index 00000000..2a41857d --- /dev/null +++ b/src/pages/ibc/basic-concepts.mdx @@ -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 diff --git a/src/pages/ibc/diy-protocol.mdx b/src/pages/ibc/diy-protocol.mdx new file mode 100644 index 00000000..7252f9e9 --- /dev/null +++ b/src/pages/ibc/diy-protocol.mdx @@ -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. diff --git a/src/pages/ibc/diy-protocol/_meta.json b/src/pages/ibc/diy-protocol/_meta.json new file mode 100644 index 00000000..80959cc4 --- /dev/null +++ b/src/pages/ibc/diy-protocol/_meta.json @@ -0,0 +1,4 @@ +{ + "channel-lifecycle": "Channel lifecycle", + "packet-lifecycle": "Packet lifecycle" +} diff --git a/src/pages/ibc/diy-protocol/channel-lifecycle.mdx b/src/pages/ibc/diy-protocol/channel-lifecycle.mdx new file mode 100644 index 00000000..5a36b2e9 --- /dev/null +++ b/src/pages/ibc/diy-protocol/channel-lifecycle.mdx @@ -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 diff --git a/src/pages/ibc/diy-protocol/packet-lifecycle.mdx b/src/pages/ibc/diy-protocol/packet-lifecycle.mdx new file mode 100644 index 00000000..b728278e --- /dev/null +++ b/src/pages/ibc/diy-protocol/packet-lifecycle.mdx @@ -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 diff --git a/src/pages/ibc/existing-protocols.mdx b/src/pages/ibc/existing-protocols.mdx new file mode 100644 index 00000000..fb18893e --- /dev/null +++ b/src/pages/ibc/existing-protocols.mdx @@ -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. + + + To receive callbacks, the chain needs to support IBC Callbacks for the message + type. + + +### 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. + + + 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. + + +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. + + + 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. + + +### Entrypoints + +TODO + +- two new entrypoints + - `ibc_source_chain_callback` + - `ibc_destination_chain_callback` + +--- + +Notes: + +- add link to IbcCallbackRequest docs when merged and deployed diff --git a/src/pages/ibc/getting-started.mdx b/src/pages/ibc/getting-started.mdx new file mode 100644 index 00000000..7b16b620 --- /dev/null +++ b/src/pages/ibc/getting-started.mdx @@ -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