# 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