Our Experience in Migration from Ethermint to Evmos

By

  • Published
  • Updated
  • 5 min read
Our Experience in Migration from Ethermint to Evmos

Our recent project faced challenges due to an outdated EVM-based blockchain Ethermint. To address these issues, we decided to transition to a new blockchain solution based on Evmos. This article outlines our journey, from identifying the initial problems to achieving a smooth transition.

Key takeaways

  • The Ethermint-based blockchain behind our project shut down unexpectedly about every 2-3 months and needed manual node restarts, and the Ethermint team had gone quiet, which is why we moved to Evmos.
  • The nonce values on the new Evmos chain cannot match those of the old Ethermint chain, so we decoupled the database from the nonce and bound it to block numbers.
  • A script saved the state of all issued tokens, user balances and smart contracts, and we then simulated the 2,253 transactions we had to complete in separate blocks of the new chain.
  • Since the move to Evmos the project has had 100% uptime, a clear improvement on the frequent shutdowns of the old Ethermint chain.
  • As of October 2026, the Ethermint repository on GitHub has been archived and read-only since 4 April 2024, and its notice says the team behind it moved its focus to Evmos.

We moved our project's EVM blockchain from Ethermint to Evmos after the old chain kept shutting down about every 2-3 months. One of the most significant challenges was the nonce: its values on Evmos cannot match those on Ethermint, so we bound the database to block numbers instead and simulated the 2,253 transactions we had to complete in separate blocks.

In the ever-evolving world of blockchain technology, staying up-to-date with the latest advancements is crucial for maintaining efficiency and reliability. Our recent project faced significant challenges due to an outdated EVM-based blockchain Ethermint. To address these issues, we decided to transition to a new blockchain solution based on Evmos. This article outlines our journey, from identifying the initial problems to achieving a smooth transition with 100% uptime.

Problem with Ethermint

Our project initially relied on an Ethermint-based blockchain, which, while functional, proved to be increasingly unreliable. Approximately every 2-3 months, the blockchain would shut down unexpectedly, necessitating manual restarts of the nodes. This issue disrupted our operations and posed a significant risk to user satisfaction and trust.

Given the complete lack of activity from the Ethermint team and the availability of alternatives, it became evident that continuing with the existing Ethermint-based blockchain was unsustainable in the long term.

Decision to Switch to Evmos

After thorough research and consideration, we decided to switch to a blockchain solution based on the next version of Ethermint, Evmos. Evmos aims for compatibility with EVM / smart contracts. So if you already have an EVM application running on an Ethereum or EVM-compatible chain you can easily migrate to Evmos and offer your app to the Cosmos ecosystem.

The decision was driven by several factors, including Evmos's improved architecture and compatibility with our existing systems. We anticipated a smoother operation and fewer disruptions, which were critical for maintaining user trust and operational efficiency. The planning phase involved detailed evaluations and risk assessments to ensure a well-informed transition.

As of October 2026, the Ethermint repository on GitHub was archived by its owner on 4 April 2024 and is read-only. Its notice says the team behind it has fully shifted its focus to Evmos and that the repository is no longer maintained. Teams that want EVM compatibility in a Cosmos SDK chain today can also look at Cosmos EVM, which describes itself as a fork of evmOS.

Handling the Nonce Issue

A nonce refers to a number or value that can only be used once. Nonces are often used on authentication protocols and cryptographic hash functions. In the context of blockchain technology, a nonce refers to a pseudo-random number that is utilized as a counter during the process of mining.

One of the most significant challenges we faced during the transition was the issue with Nonce values. The Nonce values in the new Evmos blockchain can’t match those in the old Ethermint blockchain. This discrepancy posed a major hurdle since some of the client data and functions on the backend relied on this value.

The solution to this problem is to completely decouple the database from this value and bind it to the block numbers (which in truth should have been done initially).

Transition Phase: Migrating Tokens, Balances and Contracts

We executed a script that saved the state of all issued tokens, user balances, and the state of smart contracts.

JavaScript
const pullAccounts = async (db: DB) => {
  console.log('Pulling accounts...')
  const accounts = await db.select().from(wallet_account);
  const addresses = accounts.map(a => a.address);
  const dataDir = path.join(__dirname, '../data', ENV, 'accounts.json');
  await fs.writeFile(dataDir, JSON.stringify(addresses, null, 2));
  console.log(`Pulled ${addresses.length} accounts`);
}

const pullProjects = async (db: DB) => {
  console.log('Pulling projects...');
  const projects = await db.select().from(project);
  const ids = projects.map(p => p.nft_contract_id);
  const txs = await db.select().from(transaction).where(inArray(transaction.id, ids));
  const dataDir = path.join(__dirname, '../data', ENV, 'projects.json');
  await fs.writeFile(dataDir, JSON.stringify(txs, null, 2));
  console.log(`Pulled ${txs.length} projects`);
}

const pullTokens = async (db: DB) => {
  console.log('Pulling tokens...');
  const tokens = await db.select().from(token);
  const ids = tokens.map(t => t.blockchain_reference);
  const txs = await db.select().from(transaction).where(inArray(transaction.id, ids.map(Number)));
  const dataDir = path.join(__dirname, '../data', ENV, 'tokens.json');
  await fs.writeFile(dataDir, JSON.stringify(txs, null, 2));
  console.log(`Pulled ${txs.length} tokens`);
}

const main = async () => {
  console.log(`Pulling ${ENV} data...`);
  const {db, close} = await getDb();
  await pullAccounts(db);
  await pullProjects(db);
  await pullTokens(db);
  console.log('Done');
  close();
};

At this point, the new Nodes were already ready to launch.

The next part was the production of the genesis block in the new blockchain. We wanted to immediately launch a new blockchain from the moment where the old one left off, but the problem of linking the backend to the blocks still remained.

The way out of this situation was to simulate the minimum number of transactions in separate blocks. Luckily we only had 2,253 transactions to complete.

An example of a script that deploys contracts and transfers tokens in batch

JavaScript
const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
const admin = new ethers.Wallet(process.env.ADMIN_PRIVATE_KEY, provider);

const batchTransfer = async () => {
  const addresses = await fs.readFile(path.join(__dirname, `../data/${ENV}/accounts.json`), 'utf-8');
  const batchTransfer = new ethers.Contract(batchTransferAddress, BatchTransferABI, admin);
  await batchTransfer.batchTransfer(JSON.parse(addresses), { gasPrice: 0, value: addresses.length });
  console.log('Addresses topped up');
}

const deployProjects = async () => {
  const projects = JSON.parse(await fs.readFile(path.join(__dirname, `../data/${ENV}/projects.json`), 'utf-8'));

  const p = projects[1];

  const data = p.payload.replace('02f93ff48205398205038080832e97488080b93f9f', '')

  const tx = await admin.sendTransaction({
    value: 0,
    data,
    gasLimit: 15000000,
    gasPrice: 0,
  })

  await tx.wait();

  const receipt = await provider.getTransactionReceipt(tx.hash);
  const newContractAddress = receipt.contractAddress;

  console.log(newContractAddress);
  p.newContractAddress = newContractAddress;

  await fs.writeFile(path.join(__dirname, `../data/${ENV}/projects.json`), JSON.stringify(projects, null, 2));
}

const deployTokens = async () => {
  const tokens = JSON.parse(await fs.readFile(path.join(__dirname, `../data/${ENV}/tokens.json`), 'utf-8'));

  for (const t of tokens) {
    const data = '0x' + t.payload.slice(44);
    const tx = await admin.sendTransaction({
      value: 0,
      data,
      gasLimit: 15000000,
      gasPrice: 0,
    })
    await tx.wait();

    const receipt = await provider.getTransactionReceipt(tx.hash);
    const newContractAddress = receipt.contractAddress;

    console.log(newContractAddress);
    t.newContractAddress = newContractAddress;
    await fs.writeFile(path.join(__dirname, `../data/${ENV}/tokens.json`), JSON.stringify(tokens, null, 2));
  }
}
const main = async () => {
  await batchTransfer();
  await deployProjects();
  await deployTokens();
}
main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error);
    process.exit(1);
  });

Setting up the new blockchain was straightforward, and early tests indicated that everything was functioning as expected. Considering that, Evmos was created with the expectation of easy transfer from any other EVM-based blockchain.

However, as we dug deeper into the integration process, we encountered several specific challenges unique to our project's requirements.

Ensuring a Smooth User Experience

A primary goal of our transition was to make it invisible to users, ensuring that they experienced no disruptions or changes in functionality. Achieving this required meticulous planning and execution. We employed several strategies to ensure a smooth user experience, including extensive testing, phased rollouts, and continuous monitoring.

Our approach focused on maintaining the integrity of user data and interactions throughout the transition. By simulating real-world scenarios and conducting rigorous testing, we were able to identify and address potential issues before they impacted users. This proactive approach was crucial in achieving a smooth transition and maintaining user confidence.

Achieving 100% Uptime

When all challenges were addressed, we successfully replaced the old blockchain with the new Evmos-based solution. Since the transition, we have achieved 100% uptime, a significant improvement from the frequent shutdowns experienced with the old system.

To maintain this high level of reliability, we implemented strong monitoring and maintenance practices. Continuous performance monitoring allows us to detect and address potential issues proactively, ensuring uninterrupted service for our users. The success of this transition has reinforced the importance of selecting the right blockchain solution and the value of thorough planning and testing.

Next step

About the author

Category:Software DevelopmentBlockchain

Back to Blog
  • Case study

    Cryptominer World

    Blockchain collectible and idle game with loot drops, NFT auctions and lotteries

  • Case study

    BloXmove

    Smart contract that cuts gas fees and boosts user earnings from liquidity pools