Skip to content

Commit

Permalink
Merge pull request #11 from CosmWasm/ibc-outline
Browse files Browse the repository at this point in the history
IBC Outline and first content
  • Loading branch information
chipshort authored May 21, 2024
2 parents cfdb4c5 + 8e90920 commit f6f6af6
Show file tree
Hide file tree
Showing 10 changed files with 274 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/pages/_meta.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"index": "Welcome",
"core": "CosmWasm Core",
"ibc": "IBC",
"sylvia": "Sylvia",
"cw-multi-test": "MultiTest",
"how-to-doc": "How to doc",
Expand Down
18 changes: 18 additions & 0 deletions src/pages/ibc.mdx
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
6 changes: 6 additions & 0 deletions src/pages/ibc/_meta.json
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"
}
26 changes: 26 additions & 0 deletions src/pages/ibc/basic-concepts.mdx
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
10 changes: 10 additions & 0 deletions src/pages/ibc/diy-protocol.mdx
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.
4 changes: 4 additions & 0 deletions src/pages/ibc/diy-protocol/_meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"channel-lifecycle": "Channel lifecycle",
"packet-lifecycle": "Packet lifecycle"
}
35 changes: 35 additions & 0 deletions src/pages/ibc/diy-protocol/channel-lifecycle.mdx
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
17 changes: 17 additions & 0 deletions src/pages/ibc/diy-protocol/packet-lifecycle.mdx
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
138 changes: 138 additions & 0 deletions src/pages/ibc/existing-protocols.mdx
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
19 changes: 19 additions & 0 deletions src/pages/ibc/getting-started.mdx
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

0 comments on commit f6f6af6

Please sign in to comment.