Skip to main content
Quickstart Tutorials
Deploy your first zEVM contract

Deploy your first zEVM contract


ZetaChain offers two types of contracts: Cross Chain Messaging Contracts (CCM) and zEVM Contracts (Omnichain Smart Contracts).

zEVM contracts run within the ZetaChain network. These contracts can be any standard Solidity contract, but for optimal use of ZetaChain's features, they must align with certain interfaces — namely ZetaChain specific interfaces that can interact with external connected blockchains.

This tutorial specifically looks at how to deploy a cross-chain swap app to zEVM that uses the ZRC-20 feature of omnichain smart contracts.


This tutorial will use the zetachain public repository as a starting point. This repository contains examples and references for development with ZetaChain.

  1. Make sure your machine has git installed:

  2. Install Node.js LTS (previous versions may, but are not guaranteed to work).

  3. Install yarn (make sure NPM has the right permissions to add global packages):

    npm i -g yarn

  4. Clone the zetachain repository to your machine

    git clone
    cd zetachain
  5. Install the dependencies:


  6. From the root folder, compile the contracts:

    yarn compile

    This will compile all the contracts in the repository for you so that you can try deploying them. You can compile these later if you need to edit anything.

  7. You should have an EVM-compatible wallet (not necessarily for this tutorial, but in general). We recommend Metamask as an easy default, but also XDEFI if you’re planning on developing dApps that incorporate Bitcoin.

Deploying an Omnichain Smart Contract on zEVM

zEVM contracts are the contracts that run within ZetaChain. These contracts can be any standard Solidity contracts without any changes — anything that you’d deploy on Ethereum, you could deploy on ZetaChain. However, if you want to get the full potential of ZetaChain, you need to align with certain interfaces that allow you to connect with and orchestrate assets across connected blockchains.

To deploy a zEVM contract, you will need to follow similar steps as deploying a cross chain messaging contract. However, instead of deploying on multiple chains, you will only deploy on ZetaChain.

Here are the steps to deploy a zEVM contract:

  1. Set up the local environment by running yarn install in the root of the project.

  2. Set up the deployer's private key in the .env file located at zetachain/packages/zevm-contracts(if there’s no .envfile then create a new one). There's no need to setup Alchemy API key as you will use the RPC already preconfigured (you can find more details on ZetaChain’s Testnet RPC here, but it is already preconfigured in this project).


    Note: There are several ways to create a new private key, if you are not familiar with that you can refer to ethers documentation This will let you generate a new Wallet with a random private key. You can get the address and private key using the following script:

    • In the examples folder, create a new file called wallet.js
      // wallet.js
      const ethers = require('ethers');
      const newWallet = ethers.Wallet.createRandom()
      console.log(newWallet.privateKey) // when entering this into .env, remove the `0x`
    • After saving this, you can run node wallet.js and it should output something like:
    • Your .env could look like (copy the entire key without the 0x! the ... is just here as an example):
      0x4eC45...505e4d is your public address of the wallet you generated, and you can send assets to this address. Make sure you keep track of both so you have it on hand later! Be aware that this is not a recommendation of a secure way to manage your keys for a Mainnet application; this is solely for development and testing purposes.
  3. Go to the zEVM contracts package (cd packages/zevm-contracts/) and look for the script zeta-swap/deploy.

  4. Use Hardhat to deploy the contract by running a command similar to the one used for cross chain messaging contracts:

    ZETA_NETWORK=athens EXECUTE_PROGRAMMATICALLY=true npx hardhat run scripts/zeta-swap/deploy.ts --network athens

    Note: Make sure to have enough funds in the wallet (public key) specified by the private key used for deploying the contract on ZetaChain. You can read on how to acquire assets for testnets here: The easiest way is to join our Discord and use our discord bot faucet in #zeta-faucet. If you’re having trouble acquiring assets, please contact the ZetaChain team. If you are on a non-unix command line (Wiindows), please add ZETA_NETWORK=athens and EXECUTE_PROGRAMMATICALLY=true to your environment (e. g. set ZETA_NETWORK=athens), and run the command starting with npx hardhat....

    In this example, we will deploy the zeta swap contract. Make sure to specify the ZetaChain network using the --network flag. This deploy script uses the configuration already in the repository to deploy the relevant contracts (ZetaSwap and zetaSwapBtcInbound) to the Athens testnet.

    You should see some output like:

    No need to generate any newer typings.
    Deploying ZetaSwap...
    Getting weth9 address from athens: athens.
    Getting uniswapV2Factory address from athens: athens.
    Getting uniswapV2Router02 address from athens: athens.
    Deployed ZetaSwap. Address: 0x2b186a075202dD065E6BDE6E86f5A9Bbe084Db1e
    Updating zetaSwap address on athens: athens.
    Updated, new address: 0x2b186a075202dD065E6BDE6E86f5A9Bbe084Db1e.
    Deployed zetaSwapBtcInbound. Address: 0x885b840b79De0016cfe2b45d60090DF1aB6FEc1f
    Updating zetaSwapBtcInbound address on athens: athens.
    Updated, new address: 0x885b840b79De0016cfe2b45d60090DF1aB6FEc1f.
  5. Once the contract is deployed, the address will be stored in the addresses file (packages/addresses/src/addresses.athens.json) and can be used for interaction with the contract.

And that’s it! In conclusion, deploying contracts on ZetaChain requires setting up the local environment, specifying the deployer's private key, and using Hardhat to deploy the contract on ZetaChain network. The address of the deployed contract will be stored in the same addresses file as before for later use.

You can read into the Zeta Swap contract in the packages/zevm-contracts/contracts/zeta-swap/ZetaSwap.sol file. If you’re building on top of it, you can edit the code and deploy using similar steps as above! You can also modify the file completely, and still deploy using the same methods.