Skip to main content

How To Perform Cross-Chain Asset Transfers

This document provides an overview of the cross-chain transfer options available for the ERC standards supported on Supernets.

Breaking changes

Supernets are rapidly evolving towards their production-ready state, and, as a result, instructions and concepts in these documents are subject to change.

Test releases include breaking changes and are not backward compatibility. Use the current test releases for testing and familiarization only.

It is highly recommended that reach out to the Supernets team for support.

Prerequisites

You'll need to have a a successful bridge deployment to make any cross-chain transactions. If you haven't done so already, check out the local deployment guide here.

Key management and secure values

When passing values to run transactions, it is important to keep sensitive values like private keys and API keys secure.

The sample commands provided in this guide use sample private keys for demonstration purposes only, in order to show the format and expected value of the parameter. It is important to note that hardcoding or directly passing private keys should never be done in a development or production environment.
Here are some options for securely storing and retrieving private keys ↓
  • Environment Variables: You can store the private key as an environment variable and access it in your code. For example, in Linux, you can set an environment variable like this: export PRIVATE_KEY="my_private_key". Then, in your code, you can retrieve the value of the environment variable using os.Getenv("PRIVATE_KEY").

  • Configuration Files: You can store the private key in a configuration file and read it in your session. Be sure to keep the configuration file in a secure location and restrict access to it.

  • Vaults and Key Management Systems: If you are working with sensitive data, you might consider using a vault or key management system like a keystore to store your private keys. These systems provide additional layers of security and can help ensure that your private keys are kept safe.

Regardless of how a private key is stored and retrieved, it's important to keep it secure and not expose it unnecessarily.

Deposit

This command deposits ERC-20 tokens from a rootchain to a Supernet.

  • Replace hex_encoded_depositor_private_key with the private key of the account that will be depositing the tokens.
  • Replace receivers_addresses with a comma-separated list of Ethereum addresses that will receive the tokens.
  • Replace amounts with a comma-separated list of token amounts to be deposited for each receiver.
  • Replace root_erc20_token_address with the address of the ERC-20 token contract on the rootchain.
  • Replace root_erc20_predicate_address with the address of the ERC-20 predicate contract on the rootchain.
  • Replace root_chain_json_rpc_endpoint with the JSON-RPC endpoint of the rootchain.
./polygon-edge bridge deposit-erc20 \
--sender-key <hex_encoded_depositor_private_key> \
--receivers <receivers_addresses> \
--amounts <amounts> \
--root-token <root_erc20_token_address> \
--root-predicate <root_erc20_predicate_address> \
--json-rpc <root_chain_json_rpc_endpoint>
Example ↓

In this example, we're depositing ERC-20 tokens to a test Supernet instance:

  • We're using a private key of 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef.
  • We're depositing tokens to two receiver addresses: 0x1111111111111111111111111111111111111111 and 0x2222222222222222222222222222222222222222.
  • We're depositing 100 tokens to the first receiver and 200 tokens to the second receiver.
  • The address of the ERC-20 token contract on the rootchain is 0x123456789abcdef0123456789abcdef01234567.
  • The address of the ERC-20 predicate contract on the rootchain is 0x23456789abcdef0123456789abcdef012345678.
  • The JSON-RPC endpoint for the rootchain is http://root-chain-json-rpc-endpoint.com:8545.
./polygon-edge bridge deposit-erc20 \
--sender-key 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \
--receivers 0x1111111111111111111111111111111111111111,0x2222222222222222222222222222222222222222 \
--amounts 100,200 \
--root-token 0x123456789abcdef0123456789abcdef01234567 \
--root-predicate 0x23456789abcdef0123456789abcdef012345678 \
--json-rpc http://root-chain-json-rpc-endpoint.com:8545

Withdraw

This command withdraws ERC-20 tokens from a Supernet to a rootchain.

  • Replace hex_encoded_txn_sender_private_key with the private key of the account that will be sending the transaction.
  • Replace receivers_addresses with a comma-separated list of Ethereum addresses that will receive the tokens.
  • Replace amounts with a comma-separated list of token amounts to be withdrawn for each receiver.
  • Replace child_erc20_predicate_address with the address of the ERC-20 predicate contract on the Supernet.
  • Replace child_erc20_token_address with the address of the ERC-20 token contract on the Supernet (optional, only required if the token is not a default ERC-20 token).
  • Replace child_chain_json_rpc_endpoint with the JSON-RPC endpoint of the Supernet.
 ./polygon-edge bridge withdraw-erc20 \
--sender-key <hex_encoded_txn_sender_private_key> \
--receivers <receivers_addresses> \
--amounts <amounts> \
--child-predicate <rchild_erc20_predicate_address> \
--child-token <child_erc20_token_address> \
--json-rpc <child_chain_json_rpc_endpoint>
Example ↓
  • We're using a private key of 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef.
  • We're withdrawing tokens from two receiver addresses: 0x1111111111111111111111111111111111111111 and 0x2222222222222222222222222222222222222222.
  • We're withdrawing 100 tokens from the first receiver and 200 tokens from the second receiver.
  • The address of the ERC-20 predicate contract on the Supernet is 0x3456789abcdef0123456789abcdef0123456789.
  • The address of the ERC-20 token contract on the Supernet is 0x456789abcdef0123456789abcdef0123456789.
  • The JSON-RPC endpoint for the Supernet is http://json-rpc-endpoint.com:8545.
./polygon-edge bridge withdraw-erc20 \
--sender-key 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \
--receivers 0x1111111111111111111111111111111111111111,0x2222222222222222222222222222222222222222 \
--amounts 100,200 \
--child-predicate 0x3456789abcdef0123456789abcdef0123456789 \
--child-token 0x456789abcdef0123456789abcdef0123456789 \
--json-rpc http://json-rpc-endpoint.com:8545

Exit

This command sends an exit transaction to the ExitHelper contract on the rootchain for a token that was deposited on the Supernet. It basically finalizes a withdrawal (initiated on the Supernets) and transfers assets to receiving address on a rootchain.

  • Replace hex_encoded_txn_sender_private_key with the private key of the account that will send the exit transaction.
  • Replace exit_helper_address with the address of the ExitHelper contract on the rootchain.
  • Replace exit_id with the ID of the exit event.
  • Replace root_chain_json_rpc_endpoint with the JSON-RPC endpoint of the rootchain.
  • Replace child_chain_json_rpc_endpoint with the JSON-RPC endpoint of the Supernet.
./polygon-edge bridge exit \
--sender-key <hex_encoded_txn_sender_private_key> \
--exit-helper <exit_helper_address> \
--exit-id <exit_event_id> \
--root-json-rpc <root_chain_json_rpc_endpoint> \
--child-json-rpc <child_chain_json_rpc_endpoint>
Example ↓

In this example, we're sending an exit transaction on a test Supernet instance:

  • We're using a private key of 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef.
  • The address of the ExitHelper contract on the rootchain is 0x123456789abcdef0123456789abcdef01234567.
  • The ID of the exit event is 42.
  • The JSON-RPC endpoint for the rootchain is http://root-chain-json-rpc-endpoint.com:8545, and the JSON-RPC endpoint for the Supernet is http://json-rpc-endpoint.com:8545.
./polygon-edge bridge exit \
--sender-key 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \
--exit-helper 0x123456789abcdef0123456789abcdef01234567 \
--exit-id 42 \
--root-json-rpc http://root-chain-json-rpc-endpoint.com:8545 \
--child-json-rpc http://json-rpc-endpoint.com:8545