How to Migrate from Solana to the XDC Network using Solang

Table of content

Overview

Install and setup Dev Environment

npm install -g truffle

To verify that Truffle is installed properly, type truffle version on a terminal. You should see something like:

Truffle v5.5.27 (core: 5.5.27)
Ganache v7.4.0
Solidity v0.5.16 (solc-js)
Node v16.16.0
Web3.js v1.7.4

If you see an error instead, make sure that your npm modules are added to your path.

For Windows

We need to install:

Solana Tool Suite

curl https://release.solana.com/v1.14.3/solana-install-init-x86_64-pc-windows-msvc.exe --output C:\solana-install-tmp\solana-install-init.exe --create-dirs

And Prebuilt Binaries

Download the binaries by navigating to https://github.com/solana-labs/solana/releases/latest, download solana-release-x86_64-pc-windows-msvc.tar.bz2, then extract the archive using WinZip or similar. Open a Command Prompt and run:

cd solana-release/
set PATH=%cd%/bin;%PATH%
solana --version

Create a project

mkdir solana-migration-xdc && cd solana-migration-xdc
Starting init...
================
> Copying project files to /home/your/path/to/solana-migration-xdc
Init successful, sweet!
Try our scaffold commands to get started:
  $ truffle create contract YourContractName # scaffold a contract
  $ truffle create test YourTestName         # scaffold a test
http://trufflesuite.com/docs
yarn add @solana/solidity @solana/web3.js dotenv @truffle/hdwallet-provider

Create an XDC Network Wallet

  • Easy way to create a wallet is installing the XDC Pay wallet extension download it from here

  • Receive 1000 free testnet XDC tokens using Faucet

Write a smart contract

  • a constructor that initializes the int32 value to the given init_value,

  • a inc method to increment the state value,

  • a get method to know what is the state value

Note: Solang aims to be compatible with Solidity 0.7

Write the following code to incrementer.sol:

pragma solidity ^0.7.0;

contract incrementer {
	uint32 private value;

	/// Constructor that initializes the `int32` value to the given `init_value`.
	constructor(uint32 initvalue) {
		value = initvalue;
	}

	/// This increments the value by `by`. 
	function inc(uint32 by) public {
		value += by;
	}

	/// Simply returns the current value of our `uint32`.
	function get() public view returns (uint32) {
		return value;
	}
}

The Solang extension should compile the code automatically and a folder Build with 2 files: bundle.so and incrementer.abi.

Compile and migrate the smart contract from Solana to the XDC Network

If the extension doesn't work and you cannot see a build folder, try running this command:

solang.exe compile contracts/incrementer.sol --target solana --output build
const { Connection, LAMPORTS_PER_SOL, Keypair } = require('@solana/web3.js');
const { Contract, Program } = require('@solana/solidity');
const { readFileSync } = require('fs');

const INCREMENTER_ABI = JSON.parse(readFileSync('./build/incrementer.abi', 'utf8'));
const PROGRAM_SO = readFileSync('./build/bundle.so');

(async function () {
    console.log('Connecting to your local Solana node ...');
    const connection = new Connection(
        //'https://api.mainnet-beta.solana.com',
        'https://api.devnet.solana.com',
        //'http://localhost:8899',
         'confirmed');

    const payer = Keypair.generate();

    console.log('Airdropping SOL to a new wallet ...');
    const signature = await connection.requestAirdrop(payer.publicKey, LAMPORTS_PER_SOL);
    await connection.confirmTransaction(signature, 'confirmed');

    const program = Keypair.generate();
    const storage = Keypair.generate();

    const contract = new Contract(connection, program.publicKey, storage.publicKey, INCREMENTER_ABI, payer);

    await contract.load(program, PROGRAM_SO);

    console.log('Program deployment finished, deploying the incrementer contract ...');

    await contract.deploy('incrementer', [1], storage, 1000);

    const res = await contract.functions.inc(2);
    console.log('Adding number 2 to the value', res)

    const res2 = await contract.functions.get();
    console.log('state: ' + res2.result);
})();

Run this command to config the devnet url for solana:

solana config set --url devnet

Run the command:

node deployContract.js

Migrate to XDC

Go to your truffle-config.js and paste this code:

require("dotenv").config();
const { MNEMONIC } = process.env;
const HDWalletProvider = require("@truffle/hdwallet-provider");

module.exports = {
  networks: {
    xinfin: {
      provider: () =>
        new HDWalletProvider(MNEMONIC, "https://erpc.xinfin.network"),
      network_id: 50,
      gasLimit: 6721975,
      confirmation: 2,
      networkCheckTimeout: 1000000,
      timeoutBlocks: 2000,
    },

    apothem: {
      provider: () =>
        new HDWalletProvider(MNEMONIC, "https://erpc.apothem.network"),
      network_id: 51,
      gasLimit: 6721975,
      confirmation: 2,
      networkCheckTimeout: 1000000,
      timeoutBlocks: 2000,
    },
  },
  mocha: {},
  compilers: {
    solc: {
      version: "0.7.0",
    },
  },
};
const incrementer = artifacts.require("incrementer");

const VALUE = 1

module.exports = function(deployer) {
  deployer.deploy(incrementer, [VALUE]);
};
truffle migrate --network apothem
or 
truffle migrate --network xinfin

Copy the transaction hash to check it in the block explorer

Congrats! you have migrated a solana contract compiled with Solang to the XDC network

Last updated