# IBC with CW20 and ICS20_CW20 contract
## Video source
https://www.youtube.com/watch?v=Yix0BThxTIU
## Steps
**Note**: you don't need reproduce step 1,2 and 4.
You can concentrate on step 3 and step 5
- `Step 3`: It's important to understand that every cw20 contract need allowed in the cw20_ics20 to perform ibc transfer. It is not necessary create multiple cw20_ics20 contract. It is better to create only one contract for the chain
- `Step 5`: Contains the istructions to build the message to execute on cw20 contract
### 1 Create cw20 contract
Load contract code cw20 into chain. After store transaction you can get contract id
```bash=
WALLET_MINTER="did:com:16shau48zk7mkeszuww494hvvu34mxgpfw39upa"
WALLET_ADMIN="did:com:1zjdky9s0n6rgck6mxfgvjf68qvda9akad36m67"
WALLET_FOUNDER="did:com:1829s409tjju2luhudq5dfeus6je3vfdnjv9tpn"
WALLET_DESTINATION="did:com:1qlru3vdq7lajx4tpj0gdlm6lx5mgk09u7kpzxg"
WALLET_BUYER="did:com:1xdjmpk8r0nzfuhgfvg6s2gxmtfxslqmn9newuv"
WALLET_REWARDS="osmo18qrv57zec56cgfr9prf4mh4zy0yayv7cjkcwfp"
WALLET_GOV="did:com:19fe4e45jakkwcf7ysajf3zqekd982a66zl4a6u"
CHAIN_FEES="1000000ucommercio"
CHAIN_FEES_FOR_STORE="100000000ucommercio"
CHAIN_GAS="5000000"
CHAIN_GAS_FOR_STORE="50000000"
cw20_contract="cw20_base.wasm"
commercionetworkd tx wasm store "$cw20_contract" \
--from $WALLET_GOV \
--chain-id commercio-devnet09 --keyring-backend file \
--gas $CHAIN_GAS_FOR_STORE \
--fees $CHAIN_FEES_FOR_STORE \
--gas-adjustment 1.5 \
--broadcast-mode block \
-o json -y > store_cw20.json
```
From this transaction you can get contract id. Read from explorer the transaction anche get datails or parse the output of transaction to get it
```bash
CW20_CONTRACT_ID=$(jq -r '.logs[0].events[-1].attributes[1].value' store_cw20.json)
```
Instatiate and mint a new cw20 token
```bash=
CAP_RIV="9900000000000000"
INIT_CW20='{"name":"rivera dev 51","symbol":"RIV-DEVNEW","decimals": 5,"initial_balances":[{"address":"'$WALLET_MINTER'","amount":"'$CAP_RIV'"}],"mint":{"minter":"'$WALLET_MINTER'","cap":"'$CAP_RIV'"}}'
commercionetworkd tx wasm instantiate "$CW20_CONTRACT_ID" "$INIT_CW20" \
--label "RIV TOKEN 51" \
--admin $WALLET_MINTER \
--from $WALLET_MINTER \
--chain-id commercio-devnet09 --keyring-backend file \
--gas $CHAIN_GAS \
--fees $CHAIN_FEES \
--gas-adjustment 1.5 \
--broadcast-mode block \
-o json -y > cw20_istantiate.json
```
Get contract address
```bash
CW20_CONTRACT_ADDRESS=$(jq -r '.logs[0].events[0].attributes[0].value' cw20_istantiate.json)
```
### 2 Create cw20_ics20 contract
Store contract code
```bash=
cw20_ics20_contract="cw20_ics20.wasm"
commercionetworkd tx wasm store "$cw20_ics20_contract" \
--from $WALLET_GOV \
--chain-id commercio-devnet09 --keyring-backend file \
--gas $CHAIN_GAS_FOR_STORE \
--fees $CHAIN_FEES_FOR_STORE \
--gas-adjustment 1.5 \
--broadcast-mode block \
-o json -y > store_cw20_ics20.json
```
From this transaction you can get contract id. Read from explorer the transaction to get datails or parse the output of transaction
```bash
CW20_ICS20_CONTRACT_ID=$(jq -r '.logs[0].events[-1].attributes[1].value' store_cw20_ics20.json)
```
Instatiate the cw20_ics20 contract
```bash=
INIT_CW20_ICS20='{"default_timeout":1000,"gov_contract":"'$WALLET_GOV'","default_gas_limit": 10000000,"allowlist":[]}'
commercionetworkd tx wasm instantiate \
"$CW20_ICS20_CONTRACT_ID" \
"$INIT_CW20_ICS20" \
--label "ICS CONTRACT" \
--admin $WALLET_GOV \
--from $WALLET_GOV \
--chain-id commercio-devnet09 --keyring-backend file \
--gas $CHAIN_GAS \
--fees $CHAIN_FEES \
--gas-adjustment 1.5 \
--broadcast-mode block \
-o json -y > cw20_ics20_istantiate.json
```
Get contract address
```bash
CW20_ICS20_ADDRESS=$(jq -r '.logs[0].events[0].attributes[0].value' cw20_ics20_istantiate.json)
```
### 3 Allow cw20 to ics20 cw20
To allow the cw20 contract to use the cw20_ics20 contract, an allowance transaction must be performed
```bash=
ALLOW_CW20_ICS20='{"allow":{"contract":"'$CW20_CONTRACT_ADDRESS'"}}'
commercionetworkd tx wasm execute \
$CW20_ICS20_ADDRESS \
"$ALLOW_CW20_ICS20" \
--from $WALLET_GOV \
--chain-id commercio-devnet09 --keyring-backend file \
--gas $CHAIN_GAS \
--fees $CHAIN_FEES \
--gas-adjustment 1.5 \
--broadcast-mode block \
-o json -y
```
If you want to create a new cw20 and use it in sending through ibc you must request to perform this transaction.
**If you create a new cw20_ics20 contract a new port must be created and a new channel must be created between the chains**
### 4 Create ibc channel
To create the channel we use hermes relayer. Relayer perform these
- Execute the transactions to transport the assets between the chains
- Keeps clients active in configured chains
Create a connection. Cliente will be created automatically
```bash=
OSMOSIS_CHAIN_ID="osmo-test-5"
COMMERCIO_CHAIN_ID="commercio-devnet09"
hermes create connection --a-chain $COMMERCIO_CHAIN_ID --b-chain $OSMOSIS_CHAIN_ID
```
Get port id
```bash=
CW20_ICS20_QUERY='{"port":{}}'
CW20_ICS20_PORT=$(commercionetworkd q wasm \
contract-state smart \
$CW20_ICS20_ADDRESS "$CW20_ICS20_QUERY" \
-o json | jq -r '.data.port_id')
```
In our case the port is
`wasm.a4e1bbdf5d9534c7f08de7c6b5ef47ebd1bd7925889edb5098d83efa15122ac4`
```bash=
hermes create channel --order unordered \
--a-chain $COMMERCIO_CHAIN_ID \
--a-connection connection-2 \
--a-port $CW20_ICS20_PORT \
--b-port transfer \
--channel-version ics20-1
```
We get this response
```
SUCCESS Channel {
ordering: Unordered,
a_side: ChannelSide {
chain: BaseChainHandle {
chain_id: ChainId {
id: "commercio-devnet09",
version: 0,
},
runtime_sender: Sender { .. },
},
client_id: ClientId(
"07-tendermint-4",
),
connection_id: ConnectionId(
"connection-2",
),
port_id: PortId(
"wasm.a4e1bbdf5d9534c7f08de7c6b5ef47ebd1bd7925889edb5098d83efa15122ac4",
),
channel_id: Some(
ChannelId(
"channel-3",
),
),
version: Some(
Version(
"ics20-1",
),
),
},
b_side: ChannelSide {
chain: BaseChainHandle {
chain_id: ChainId {
id: "osmo-test-5",
version: 5,
},
runtime_sender: Sender { .. },
},
client_id: ClientId(
"07-tendermint-1609",
),
connection_id: ConnectionId(
"connection-1499",
),
port_id: PortId(
"transfer",
),
channel_id: Some(
ChannelId(
"channel-4566",
),
),
version: Some(
Version(
"ics20-1",
),
),
},
connection_delay: 0ns,
}
```
We obtain
- Channel on the commercionetwork devnet : `channel-3`
- Channel on the osmosis testnet-5: `channel-4566`
### 5 Send cw20 token to osmosis
You need to create a msg and encode it in base64
Message:
```json
{
"channel":"channel-3",
"remote_address":"$WALLET_OSMOSIS"
}
```
```bash=
MSG_CHANNEL='{"channel":"channel-3","remote_address":"'$WALLET_OSMOSIS'"}'
MSG_CHANNEL_BASE64=$(printf $MSG_CHANNEL | base64 --wrap=0)
```
Execute transaction to send on CW20 contract
Message:
```json
{
"send":
{
"contract":"$CW20_ICS20_ADDRESS",
"amount":"10000",
"msg":"MSG_CHANNEL_BASE64"
}
}
```
- `contract`: Contract address cw20_ics20
- `amount`: the amount of cw20 you want send
- `msg`: base64 encoded message with channel and target wallet in osmosis chain
```bash=
EXEC_TRANSFER='{"send":{"contract":"'$CW20_ICS_CONTRACT_ADDRESS'","amount":"1000000","msg":"'$MSG_CHANNEL_BASE64'"}}'
commercionetworkd tx wasm execute \
$CW20_CONTRACT_ADDRESS \
"$EXEC_TRANSFER" \
--from $WALLET_SENDER \
--chain-id commercio-devnet09 \
--keyring-backend file \
--gas $CHAIN_GAS \
--fees $CHAIN_FEES \
--gas-adjustment 1.5 \
--broadcast-mode block \
-o json -y
```
## Warning
The transfer may take a long time to complete. Right now the relayer is on a single-node test system and therefore may not be performing very well
To perform a transaction from osmosis testnet to devnet commercio, simply execute an ibc transaction as if they were native tokens through the channel `channel-4566`.
I performed a transfer using simply keplr