Exchange Integration
Learn how to integrate your exchange with the EVM-Compatible Avalanche C-Chain.
Overview
The objective of this document is to provide a brief overview of how to integrate with the EVM-Compatible Avalanche C-Chain.
For teams that already
support ETH, supporting the C-Chain is as straightforward as spinning up an
Avalanche node (which has the same API as
go-ethereum) and populating
Avalanche's ChainID (43114) when constructing transactions.
Additionally, Ava Labs maintains an implementation of the Rosetta API for the C-Chain called avalanche-rosetta. You can learn more about this standardized integration path on the attached Rosetta API website.
Integration Using EVM Endpoints
Running an Avalanche Node
If you want to build your node form source or include it in a docker image,
reference the AvalancheGo GitHub
repository. To quickly get up and
running, you can use the node installation script that automates installing
and updating AvalancheGo node as a systemd service on Linux, using prebuilt
binaries.
Configuring an Avalanche Node
All configuration options and their default values are described here.
You can supply configuration options on the command line, or use a config file,
which can be easier to work with when supplying many options. You can specify
the config file location with --config-file=config.json, where config.json is
a JSON file whose keys and values are option names and values.
Individual chains, including the C-Chain, have their own configuration options which are separate from the node-level options. These can also be specified in a config file. For more details, see here.
The C-Chain config file should be at
$HOME/.avalanchego/configs/chains/C/config.json. You can also tell AvalancheGo
to look somewhere else for the C-Chain config file with option
--chain-config-dir. An example C-Chain config file:
Warning
If you need Ethereum's Archive
Node
functionality, you need to disable C-Chain pruning, which has been enabled by
default since AvalancheGo v1.4.10. To disable pruning, include
"pruning-enabled": false in the C-Chain config file as shown below. Also set
"state-sync-enabled": false. State sync is on by default, and a node that state
syncs does not have the state of earlier blocks.
{
"local-txs-enabled": true,
"pruning-enabled": false,
"state-sync-enabled": false
}Interacting with the C-Chain
Interacting with the C-Chain is identical to interacting with
go-ethereum. You can find the reference material
for C-Chain API here.
The C-Chain node does not serve the personal_ and admin_ namespaces, eth_accounts or
eth_coinbase. The node holds no keys. Sign transactions in your own system and send them
with eth_sendRawTransaction. By default, the node serves the web3, net, txpool,
price, chain, tx, subscription, avalanche and trace API groups. To change the
groups that the node serves, set apis in the C-Chain config file. Do not use eth-apis, which is deprecated.
Integration Using Rosetta
Rosetta is an open-source specification and set of tools that makes integrating with different blockchain networks easier by presenting the same set of APIs for every network. The Rosetta API is made up of 2 core components, the Data API and the Construction API.
Together, these APIs allow for anyone to read and write to blockchains in a standard format over a standard communication protocol. The specifications for these APIs can be found in the rosetta-specifications repository.
You can find the Rosetta server implementation for Avalanche C-Chain
here, all you need to do is
install and run the server with proper configuration. It comes with a Dockerfile
that packages both the server and the Avalanche client. Detailed instructions
can be found in the linked repository.
Constructing Transactions
Avalanche C-Chain transactions are standard EVM transactions, with these differences:
- Sign them with Avalanche's ChainID (43114).
- Use a legacy, EIP-2930 or EIP-1559 transaction. The C-Chain does not accept blob (EIP-4844) or set-code (EIP-7702) transactions.
- The C-Chain charges each transaction
max(gasUsed, ceil(gasLimit / 2))gas. Do not set a gas limit more than 2 times the expected gas use. A 21,000 gas AVAX transfer with a 21,000 gas limit is not affected. - The mempool rejects a transaction whose gas limit is too small for its size, with the error
insufficient gas limit for tx size. At a block gas limit of 80,000,000, a transaction needs about 51 gas per byte. AvalancheGo v1.15.1 and later include this minimum ineth_estimateGas. - The detailed dynamic gas fee can be found here.
For development purposes, Avalanche supports all the popular tooling for Ethereum, so developers familiar with Ethereum and Solidity can feel right at home. Popular development environments include:
Ingesting On-Chain Data
You can use any standard way of ingesting on-chain data you use for Ethereum network.
Determining Finality
Avalanche consensus gives irreversible finality in about 1 second. A C-Chain transaction is final when consensus accepts its block. Snowman has no re-orgs, so you do not need to wait for more confirmations.
After acceptance, the node executes the block. Receipts, logs and the post-execution state exist only after execution:
latestandeth_blockNumberreturn the last executed block. Read balances, state and logs atlatest.eth_getBlockByNumberwith an explicit number also returns accepted blocks that are not executed yet. A number above the last accepted block returnsnull.- For a transaction in an accepted block,
eth_getTransactionReceiptwaits until the transaction executes. It returnsnullif the transaction is not in an accepted block. safeandfinalizedreturn the last settled block, a few blocks behindlatest. These tags do not mark finality: every accepted block is already final.
(Optional) Custom Golang SDK
If you plan on extracting data from the C-Chain into your own systems using
Golang, we recommend using our custom
ethclient. The
standard go-ethereum Ethereum client does not compute block hashes correctly
(when you call block.Hash()) because it doesn't take into account the added
ExtDataHash
header field in Avalanche C-Chain blocks, which is used move AVAX between chains
(X-Chain and P-Chain). You can read more about our multi-chain abstraction
here (out of scope for a
normal C-Chain integration).
If you plan on reading JSON responses directly or use web3.js (doesn't recompute hash received over the wire) to extract on-chain transaction data/logs/receipts, you shouldn't have any issues!
Support
If you have any problems or questions, reach out either directly to our developers, or on our public Discord server.
Is this guide helpful?