Non-AVA assets in smart contracts

Does the C-chain support managing assets (e.g. non-fungible tokens) created in the X-chain?

I mean, is there a way to deal with assets apart from AVA in smart contracts? If so, can you point me at some example?

Yes, you can directly move assets from X-chain to C-chain natively. Think of x-chain assets as simplified ERC-20s.

1 Like

Thanks, but I could find only a call to move AVA from X-chain to C-chain: https://docs.avax.network/build/apis/exchange-chain-x-chain-api#avm-importavax - what is the equivalent for other tokens on the X-chain?

AVAX is itself an ANT (Avalanche Native Asset), and it’s not special from other tokens. So moving AVAX is the same as moving other tokens cc @gabriel

I see, then I would expect the call I referenced (https://docs.avax.network/build/apis/exchange-chain-x-chain-api#avm-importavax) to have as a parameter something that would specify the asset (e.g. assetID as can be seen in the “mint” call) but I don’t see anything like that - is it perhaps a different call or some optional parameter not mentioned in the docs?

Hi, there’s actually a few new API calls which aren’t yet documented that you can use to swap non-AVAX assets from the X-Chain to the C-Chain and back.

Let’s say you have a fixed cap asset which you issued on the X-Chain called 2YmsQfMaCczE4mLG1DPYUnRURNGfhjj4qrqnLRR3LmZ3GxDWPt and you want to swap it to the C-Chain and back. Here are the steps.

First call avm.export. This is different than avm.exportAVAX in that it accepts an assetID. Make sure to use the bech 32 encoded C-Chain address.

curl --location --request POST 'http://localhost:9650/ext/bc/X' \
--header 'Content-Type: application/json' \
--data-raw '{
    "jsonrpc":"2.0",
    "id"     :1,
    "method" :"avm.export",
    "params" :{
        "to":"C-local18jma8ppw3nhx5r4ap8clazz0dps7rv5u00z96u",
        "amount": 50,
        "assetID": "2YmsQfMaCczE4mLG1DPYUnRURNGfhjj4qrqnLRR3LmZ3GxDWPt",
        "username":"",
        "password":"" 
    }
}'

{
    "jsonrpc": "2.0",
    "result": {
        "txID": "2s4duEBMvc3mrgy1pcUkfBHFpaUbWXe6zpnuG3xAMMkB6iKCgm",
        "changeAddr": "X-local18jma8ppw3nhx5r4ap8clazz0dps7rv5u00z96u"
    },
    "id": 1
}

Next on the C-Chain you need to call avax.import. Note this is different than avax.importAVAX in that it looks for non-AVAX assets as well as AVAX. Note here you use the hex version of your C-Chain address

curl --location --request POST 'http://localhost:9650/ext/bc/C/avax' \
--header 'Content-Type: application/json' \
--data-raw '{
    "method": "avax.import",
    "params": {
        "username":"",
        "password":"",
        "sourceChain": "X",
        "to":"0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC"
    },
    "jsonrpc": "2.0",
    "id": 1
}'

{
    "jsonrpc": "2.0",
    "result": {
        "txID": "12UzqozKUQJZ3popRhLk2vdSF7sBgygMjFZHM3tG9GPo4uxfM"
    },
    "id": 1
}

Now you can confirm it worked by checking the balance w/ the new eth_getAssetBalance rpc. You pass in the assetID as the last arg.

curl --location --request POST 'http://localhost:9650/ext/bc/C/rpc' \
--header 'Content-Type: application/json' \
--data-raw '{
    "jsonrpc": "2.0",
    "method": "eth_getAssetBalance",
    "params": [
        "0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC",
        "latest",
        "2YmsQfMaCczE4mLG1DPYUnRURNGfhjj4qrqnLRR3LmZ3GxDWPt"
    ],
    "id": 1
}'

{
    "jsonrpc": "2.0",
    "id": 1,
    "result": "0x32"
}

When you want to swap the asset back from the C-Chain to the X-Chain you call the same commands in reverse order.

First avax.export

curl --location --request POST 'http://localhost:9650/ext/bc/C/avax' \
--header 'Content-Type: application/json' \
--data-raw '{
    "method" :"avax.export",
    "params" :{
        "from": ["0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC"],
        "to":"X-local18jma8ppw3nhx5r4ap8clazz0dps7rv5u00z96u",
        "amount": 25,
        "destinationChain": "X",
        "changeAddr": "0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC",
        "assetID": "2YmsQfMaCczE4mLG1DPYUnRURNGfhjj4qrqnLRR3LmZ3GxDWPt",
        "username":"",
        "password":""
    },
    "jsonrpc":"2.0",
    "id"     :1
}'

{
    "jsonrpc": "2.0",
    "result": {
        "txID": "2mSUbiGK1z2WLgkXqDDBXCfUtU42bjtX1vLMPSr4xiN5JBq3SG"
    },
    "id": 1
}

Then avm.import. Make sure to set the sourceChain as C.

curl --location --request POST 'http://localhost:9650/ext/bc/X' \
--header 'Content-Type: application/json' \
--data-raw '{
    "jsonrpc":"2.0",
    "id"     :1,
    "method" :"avm.import",
    "params" :{
        "username":"",
        "password":"",
        "sourceChain": "C",
        "to":"X-local18jma8ppw3nhx5r4ap8clazz0dps7rv5u00z96u"
    }
}'

I need to update the docs to have avm.import, avm.export, avax.import, avax.export, and eth_getAssetBalance

8 Likes

Awesome! Once the asset is imported into the C-chain, how would I interact with those assets in Solidity? Do they offer some ERC-20-like interface? If so, where is it documented?

There is currently no existing way to both transfer and call a smart contract in one step for multi coin assets. There is a call we added to coreth/EVM called callex. It currently only moves multicoin funds, so we’ve expanded it to also invoke smart contracts in the same step. This will be live in our upcoming hardfork.

1 Like

Also we have this Multicoin contract and this go script to show how to move send Multicoins on the C-Chain.

1 Like