Skip to content

Commit

Permalink
feat: improve cosmos gmp integration instructions and styles (#518)
Browse files Browse the repository at this point in the history

Co-authored-by: ffe9f8 <149421156+ffe9f8@users.noreply.github.com>
  • Loading branch information
StephenFluin and ffe9f8 authored Jan 4, 2024
1 parent d24348d commit 5bb839b
Show file tree
Hide file tree
Showing 3 changed files with 253 additions and 23 deletions.
201 changes: 198 additions & 3 deletions public/styles/prism.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,199 @@
/* PrismJS 1.29.0
https://prismjs.com/download.html#themes=prism-twilight&languages=markup+css+clike+javascript+bash+json+json5+solidity+typescript&plugins=show-language+toolbar+copy-to-clipboard */
code[class*=language-],pre[class*=language-]{color:#fff;background:0 0;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;text-shadow:0 -.1em .2em #000;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}:not(pre)>code[class*=language-],pre[class*=language-]{background:#141414}pre[class*=language-]{border-radius:.5em;border:.3em solid #545454;box-shadow:1px 1px .5em #000 inset;margin:.5em 0;overflow:auto;padding:1em}pre[class*=language-]::-moz-selection{background:#27292a}pre[class*=language-]::selection{background:#27292a}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{text-shadow:none;background:hsla(0,0%,93%,.15)}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:hsla(0,0%,93%,.15)}:not(pre)>code[class*=language-]{border-radius:.3em;border:.13em solid #545454;box-shadow:1px 1px .3em -.1em #000 inset;padding:.15em .2em .05em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#777}.token.punctuation{opacity:.7}.token.namespace{opacity:.7}.token.boolean,.token.deleted,.token.number,.token.tag{color:#ce6849}.token.builtin,.token.constant,.token.keyword,.token.property,.token.selector,.token.symbol{color:#f9ed99}.language-css .token.string,.style .token.string,.token.attr-name,.token.attr-value,.token.char,.token.entity,.token.inserted,.token.operator,.token.string,.token.url,.token.variable{color:#909e6a}.token.atrule{color:#7385a5}.token.important,.token.regex{color:#e8c062}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.language-markup .token.attr-name,.language-markup .token.punctuation,.language-markup .token.tag{color:#ac885c}.token{position:relative;z-index:1}.line-highlight.line-highlight{background:hsla(0,0%,33%,.25);background:linear-gradient(to right,hsla(0,0%,33%,.1) 70%,hsla(0,0%,33%,0));border-bottom:1px dashed #545454;border-top:1px dashed #545454;margin-top:.75em;z-index:0}.line-highlight.line-highlight:before,.line-highlight.line-highlight[data-end]:after{background-color:#8693a6;color:#f4f1ef}
div.code-toolbar{position:relative}div.code-toolbar>.toolbar{position:absolute;z-index:10;top:.3em;right:.2em;transition:opacity .3s ease-in-out;opacity:0}div.code-toolbar:hover>.toolbar{opacity:1}div.code-toolbar:focus-within>.toolbar{opacity:1}div.code-toolbar>.toolbar>.toolbar-item{display:inline-block}div.code-toolbar>.toolbar>.toolbar-item>a{cursor:pointer}div.code-toolbar>.toolbar>.toolbar-item>button{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;padding:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}div.code-toolbar>.toolbar>.toolbar-item>a,div.code-toolbar>.toolbar>.toolbar-item>button,div.code-toolbar>.toolbar>.toolbar-item>span{color:#bbb;font-size:.8em;padding:0 .5em;background:#f5f2f0;background:rgba(224,224,224,.2);box-shadow:0 2px 0 0 rgba(0,0,0,.2);border-radius:.5em}div.code-toolbar>.toolbar>.toolbar-item>a:focus,div.code-toolbar>.toolbar>.toolbar-item>a:hover,div.code-toolbar>.toolbar>.toolbar-item>button:focus,div.code-toolbar>.toolbar>.toolbar-item>button:hover,div.code-toolbar>.toolbar>.toolbar-item>span:focus,div.code-toolbar>.toolbar>.toolbar-item>span:hover{color:inherit;text-decoration:none}
https://prismjs.com/download.html#themes=prism-twilight&languages=markup+css+clike+javascript+bash+go+rust+solidity+typescript&plugins=show-language+toolbar+copy-to-clipboard */
code[class*="language-"],
pre[class*="language-"] {
color: #fff;
background: 0 0;
font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
font-size: 1em;
text-align: left;
text-shadow: 0 -0.1em 0.2em #000;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background: #141414;
}
pre[class*="language-"] {
border-radius: 0.5em;
border: 0.3em solid #545454;
box-shadow: 1px 1px 0.5em #000 inset;
margin: 0.5em 0;
overflow: auto;
padding: 1em;
}
pre[class*="language-"]::-moz-selection {
background: #27292a;
}
pre[class*="language-"]::selection {
background: #27292a;
}
code[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection,
pre[class*="language-"] ::-moz-selection,
pre[class*="language-"]::-moz-selection {
text-shadow: none;
background: hsla(0, 0%, 93%, 0.15);
}
code[class*="language-"] ::selection,
code[class*="language-"]::selection,
pre[class*="language-"] ::selection,
pre[class*="language-"]::selection {
text-shadow: none;
background: hsla(0, 0%, 93%, 0.15);
}
:not(pre) > code[class*="language-"] {
border-radius: 0.3em;
border: 0.13em solid #545454;
box-shadow: 1px 1px 0.3em -0.1em #000 inset;
padding: 0.15em 0.2em 0.05em;
white-space: normal;
}
.token.cdata,
.token.comment,
.token.doctype,
.token.prolog {
color: #777;
}
.token.punctuation {
opacity: 0.7;
}
.token.namespace {
opacity: 0.7;
}
.token.boolean,
.token.deleted,
.token.number,
.token.tag {
color: #ce6849;
}
.token.builtin,
.token.constant,
.token.keyword,
.token.property,
.token.selector,
.token.symbol {
color: #f9ed99;
}
.language-css .token.string,
.style .token.string,
.token.attr-name,
.token.attr-value,
.token.char,
.token.entity,
.token.inserted,
.token.operator,
.token.string,
.token.url,
.token.variable {
color: #909e6a;
}
.token.atrule {
color: #7385a5;
}
.token.important,
.token.regex {
color: #e8c062;
}
.token.bold,
.token.important {
font-weight: 700;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}
.language-markup .token.attr-name,
.language-markup .token.punctuation,
.language-markup .token.tag {
color: #ac885c;
}
.token {
position: relative;
z-index: 1;
}
.line-highlight.line-highlight {
background: hsla(0, 0%, 33%, 0.25);
background: linear-gradient(
to right,
hsla(0, 0%, 33%, 0.1) 70%,
hsla(0, 0%, 33%, 0)
);
border-bottom: 1px dashed #545454;
border-top: 1px dashed #545454;
margin-top: 0.75em;
z-index: 0;
}
.line-highlight.line-highlight:before,
.line-highlight.line-highlight[data-end]:after {
background-color: #8693a6;
color: #f4f1ef;
}
div.code-toolbar {
position: relative;
}
div.code-toolbar > .toolbar {
position: absolute;
z-index: 10;
top: 0.3em;
right: 0.2em;
transition: opacity 0.3s ease-in-out;
opacity: 0;
}
div.code-toolbar:hover > .toolbar {
opacity: 1;
}
div.code-toolbar:focus-within > .toolbar {
opacity: 1;
}
div.code-toolbar > .toolbar > .toolbar-item {
display: inline-block;
}
div.code-toolbar > .toolbar > .toolbar-item > a {
cursor: pointer;
}
div.code-toolbar > .toolbar > .toolbar-item > button {
background: 0 0;
border: 0;
color: inherit;
font: inherit;
line-height: normal;
overflow: visible;
padding: 0;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
}
div.code-toolbar > .toolbar > .toolbar-item > a,
div.code-toolbar > .toolbar > .toolbar-item > button,
div.code-toolbar > .toolbar > .toolbar-item > span {
color: #bbb;
font-size: 0.8em;
padding: 0 0.5em;
background: #f5f2f0;
background: rgba(224, 224, 224, 0.2);
box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.2);
border-radius: 0.5em;
}
div.code-toolbar > .toolbar > .toolbar-item > a:focus,
div.code-toolbar > .toolbar > .toolbar-item > a:hover,
div.code-toolbar > .toolbar > .toolbar-item > button:focus,
div.code-toolbar > .toolbar > .toolbar-item > button:hover,
div.code-toolbar > .toolbar > .toolbar-item > span:focus,
div.code-toolbar > .toolbar > .toolbar-item > span:hover {
color: inherit;
text-decoration: none;
}
67 changes: 51 additions & 16 deletions src/pages/dev/general-message-passing/cosmos-gmp.mdx
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
---
templateEngineOverride: md
---
import { Callout } from "/src/components/callout"
import { Callout } from "/src/components/callout";

# Cosmos General Message Passing

Axelar has expanded General Message Passing (GMP) to support Cosmos blockchains. With Axelar, you can now send and receive messages on EVM chains and Cosmos chains. Messages sent to Cosmos chains can be received by [CosmWasm smart contracts](https://github.com/axelarnetwork/evm-cosmos-gmp-sample/tree/main/cosmwasm-integration/) (on blockchains with CosmWasm support), or those messages can be received [natively at the consensus layer as part Go code](https://github.com/axelarnetwork/evm-cosmos-gmp-sample/tree/main/native-integration).

Cosmos GMP works by sending and receiving through [IBC's memo field](https://medium.com/the-interchain-foundation/moving-beyond-simple-token-transfers-d42b2b1dc29b). Cosmos chains looking to support GMP should [integrate the appropriate middleware](#chain-support) and [verify message source](#establishing-a-path-of-trust).

<Callout emoji="💡">
To see full examples of sending and receiving messages in all cases, check out our full [Cosmos GMP Example Project](https://github.com/axelarnetwork/evm-cosmos-gmp-sample/).
To see full examples of sending and receiving messages in all cases, check out
our full [Cosmos GMP Example
Project](https://github.com/axelarnetwork/evm-cosmos-gmp-sample/).
</Callout>

## Messages from EVM to CosmWasm
To send a message from an EVM chain to a Cosmos CosmWasm contract, the payload must be encoded before calling the [standard](./gmp-messages) `payNativeGasForContractCall` and `callContract` methods (or [token-including equivalents](./gmp-tokens-with-messages)). You must also specify the destination method you are calling.

To send a message from an EVM chain to a Cosmos CosmWasm contract, the payload must be encoded before calling the [standard](./gmp-messages) `payNativeGasForContractCall` and `callContract` methods (or [token-including equivalents](./gmp-tokens-with-messages)). You must also specify the destination method you are calling.

The payload must specify:

1. **string** - The method name of the CosmWasm contract to call
1. **string[]** - The names of all arguments
1. **string[]** - the types of all arguments
1. **bytes** - the values of all arguments
1. `string` - The method name of the CosmWasm contract to call
1. `string[]` - The names of all arguments
1. `string[]` - the types of all arguments
1. `bytes` - the values of all arguments

### Multi-send Example encoding

### MultiSend Example encoding
This example encodes a string array of recipients, as you can see in our [example of sending tokens and recipients](https://github.com/axelarnetwork/axelar-examples/blob/main/examples/evm/call-contract-with-token/DistributionExecutable.sol).

```solidity
Expand All @@ -41,6 +42,7 @@ bytes memory payloadToCW = abi.encodePacked(
```

## Messages from EVM to Native Cosmos

When sending a message to a Cosmos chain with native (consensus layer) support for GMP, you must encode a version number with the intended payload. This allows the consensus layer to know what to do with the payload.

```solidity
Expand All @@ -50,13 +52,11 @@ bytes memory payload = abi.encodePacked(
);
```


## Messages from Native Cosmos
To send a message from Naive Cosmos Go code, you must send a message to the Axelar GMP Account (`axelar1dv4u5k73pzqrxlzujxg3qp8kvc3pje7jtdvu72npnt5zhq05ejcsn5qme5s`) via IBC.


To send a message from Native Cosmos Go code, you must send a message to the Axelar GMP Account (`axelar1dv4u5k73pzqrxlzujxg3qp8kvc3pje7jtdvu72npnt5zhq05ejcsn5qme5s`) via IBC.

When sending messages from Cosmos, you should perform standard GMP ABI encoding via the `github.com/ethereum/go-ethereum/accounts/abi` package.
When sending messages from Cosmos, you should perform standard GMP ABI encoding via the [`github.com/ethereum/go-ethereum/accounts/abi`](https://github.com/ethereum/go-ethereum/tree/master/accounts/abi) package.

```go
// build payload that can be decoded by solidity
Expand Down Expand Up @@ -105,6 +105,7 @@ if err != nil {
```

## Messages from CosmWasm

To send a message from CosmWasm Rust code, you must send a message to the Axelar Gateway (`axelar1dv4u5k73pzqrxlzujxg3qp8kvc3pje7jtdvu72npnt5zhq05ejcsn5qme5s`) via IBC.

You should encode your payload using [ethabi](https://github.com/rust-ethereum/ethabi).
Expand Down Expand Up @@ -162,6 +163,40 @@ pub fn multi_send_to_evm(
```

## Chain Support

For a Cosmos blockchain to support receiving GMP messages (naively or via CosmWasm), it should implement the appropriate middleware in Go as part of the consensus layer.

See our [Sample GMP Middleware](https://github.com/axelarnetwork/evm-cosmos-gmp-sample/tree/main/native-integration/sample-middleware).
If you have CosmWasm on your Cosmos chain and want to be able to receieve and deliver messages, install [Osmosis IBC-hooks](https://github.com/osmosis-labs/osmosis/tree/main/x/ibc-hooks).

If you don’t support CosmWasm on your Cosmos chain, you'll need to implement and install your own Axelar GMP module to receive and execute messages. See our [sample reference implementation](https://github.com/axelarnetwork/evm-cosmos-gmp-sample/tree/main/native-integration/sample-middleware).

## Establishing a Path of Trust

Because IBC messages are permissionless, you'll want to ensure you verify the source of all messages.

When you receive a packet on Cosmos chain, you'll need to verify:

1. That the packet came from Axelar (verify IBC channel; Axelar GMP sender account).

Specify the Axelar IBC channel by allowlisting the channel hash.

- **[CosmWasm](https://github.com/osmosis-labs/osmosis/blob/main/x/ibc-hooks/README.md#cosmwasm-contract-execution-format)**

For example, in your CosmWasm code, you can combine the IBC hook, the channel ID, and the Axelar GMP account to verify the channel matches the expected channel.

```rust

`Bech32(Hash("ibc-wasm-hook-intermediary" || channelID to Axelar || Axelar GMP account))` assuming the channel is fixed, which is usually true for mainnet

```

- **For Consensus**

Verify (channel & sender == address of our GMP account = `axelar1dv4u5k73pzqrxlzujxg3qp8kvc3pje7jtdvu72npnt5zhq05ejcsn5qme5`.
https://github.com/axelarnetwork/evm-cosmos-gmp-sample/blob/main/native-integration/sample-middleware/gmp_middleware.go#L114

1. The EVM source chain and address.

When a message has an EVM source, the chain and address are passed in differently for CosmWasm and Native GMP.
- **CosmWasm**: When you build your CosmWasm contract, you can define `source_chain` and/or `source_address` as arguments for their `wasm` method. And pass in the correct `source_chain` and/or `source_address` as an argument from the EVM contract. The Axelar network will validate that these values are accurate and not being spoofed by the sender.
- **Native GMP**: The GMP call will be sent by the Axelar GMP account to the cosmos chain. Make sure that it is [formatted correctly](https://github.com/axelarnetwork/axelar-core/blob/main/x/axelarnet/types/evm_translator.go#L55) in the IBC memo that contains validated source chain/address values.
Loading

1 comment on commit 5bb839b

@vercel
Copy link

@vercel vercel bot commented on 5bb839b Jan 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.