Ethereum is the world computer that enforces smart contracts on it to work as expected so that no one can revert or interrupt the execution of those predefined sets of rules. With the power of smart contracts, Ethereum grew vastly in the last 4 years and thus it is the best blockchain platform so far.

The biggest innovation that Ethereum has brought to us is, the power of creating a currency isn't limited to governments anymore. Anyone who can program smart contracts using Solidity or Vyper can deploy their own ERC-20 (or ERC-721) asset. When their asset is listed on exchanges, it has value and can be traded by traders. Before the rise of Ethereum and blockchains, it was not possible for an individual to put its own currency into circulation. But now, developers with the knowledge of smart contracts can easily make their own assets. How cool is it?

User Experience of Ethereum

Even though many developers prefer to choose Ethereum when designing a decentralized application(apps on blockchain backed by smart contracts), it has a critical downside when it comes to user experience. That is, users need to wait for at least 15 seconds for their transaction to be recorded on the blockchain.

A transaction is the atomic operational unit for every action users take. Let's take an example. If you're playing a chess application on Ethereum and you want to move your pawn, you need to wait for 15+ seconds for one move. This is why Ethereum isn't suited for real time gaming or social networks. But isn't there any solution for this? Luckly there is :) That project is called Loom Network.

What is Loom Network?

Loom Network is a universal multi-chain hub, which is interoperable with many blockchains such as Ethereum, Binanace Chain, Tron (and soon EOS, Cosmos, BTC). Easily speaking, we can call those different chains "intranet" while Loom Network is the "Internet" that connects those ones so that assets on each chain can be transferred from and to other blockchains.

Like mentioned above, major use cases of Ethereum blockchain are ERC-20 and ERC-721 assets so let's explain it in terms of these standards. Like all the other operations on Ethereum, a transfer of ERC-20 and ERC-721 assets needs to be packed in a transaction. It means, if you want to transfer one, you need to wait for at least 15 seconds for every action. On Loom Network, a transaction is confirmed in 1-3 seconds which is much shorter than on Ethereum.

How is it possible? The key difference between Ethereum and Loom Network is in its consensus algorithm. Ethereum has taken Proof-of-Work consensus which requires miners to take the job of deciding which transactions to be included and which nonce to be used for the block. This nonce finding takes a certain amount of time and in the case of Ethereum, it is 15 seconds in average. On Loom Network, they have delegated validators, whose job is somewhat similar to miners of Ethereum. These validators don't need to find nonces but they vote to the suggested candidates of blocks so it requires significantly small amount of time compared to Ethereum. This consensus algorithm is called DPoS(Delegated Proof of Stake).

Now you'll get the answer to the question above. Loom Network, a universal multichain hub, has big advantages on its performance when you want to transfer ERC-20 and ERC-721 assets. And those transactions don't have to be recorded on Ethereum. Your assets are transferred on Loom Network so that it reduces the actual amount of operations that take place on it.

Utilizing Assets to Loom Network

Loom Network is the best side-chain for Ethereum that's fully compatible with it. Any Solidity and Vyper contracts can be deployed on the chain just like on Ethereum because it's shipped with EVM(Ethereum Virtual Machine). In this tutorial, we'll go through the steps on how to make your own ERC-20 assets work on Ethereum and Loom Network using Solidity and truffle.

Installing Node.js

If you didn't install node.js yet, you need to do it HERE.

Initializing Your Project

Let's create your project called web3token and initialize it using truffle.

$ mkdir web3token
$ cd web3token
$ npm install -g truffle
$ truffle init

Now, let's install required dependencies for the project.

$ npm init -y
$ npm install @openzeppelin/contracts @web3-guru/loom-x truffle-hdwallet-provider loom-truffle-provider dotenv

What is LoomX?

You'll see that you installed @web3-guru/loom-x above. Loom Network team provides the official JavaScript library, loom-js, that you can use to interact with Loom Network and its features range from signing with private keys from interoperable chains, reading and writing contracts, caching transactions and so on.
Even though it offers a complete set of tools when you want to build cool stuffs on Loom Network, it wouldn't be easy for beginners to start with it.
LoomX was born to make your life easier. It provides a straightforward apis that you can learn quickly. With LoomX, you don't have to struggle with severe issues. We'll use LoomX in this tutorial.

Type ls -al and you'll get just like below:

total 32
drwxr-xr-x   9 yoonjae  staff   288  1  1 22:44 .
drwxr-xr-x  55 yoonjae  staff  1760  1  1 22:44 ..
drwxr-xr-x   3 yoonjae  staff    96  1  1 22:44 contracts
drwxr-xr-x   3 yoonjae  staff    96  1  1 22:44 migrations
drwxr-xr-x   3 yoonjae  staff    96  1  1 22:44 node_modules
-rw-r--r--   1 yoonjae  staff   393  1  1 22:44 package-lock.json
-rw-r--r--   1 yoonjae  staff   340  1  1 22:44 package.json
drwxr-xr-x   2 yoonjae  staff    64  1  1 22:44 test
-rw-r--r--   1 yoonjae  staff  4233  1  1 22:44 truffle-config.js

Setting Up Network Configuration

Open truffle-config.js and edit like below:

const HDWalletProvider = require('truffle-hdwallet-provider');
const LoomTruffleProvider = require("loom-truffle-provider");
const { loomPrivateKeyFromMnemonic } = require("@web3-guru/loom-x/dist/utils/crypto-utils");
const infuraKey = "fj4jll3k.....";


module.exports = {
    networks: {
        mainnet: {
            provider: () => new HDWalletProvider(process.env.MNEMONIC, `` + infuraKey),
            network_id: 4
        loom: {
            provider: () => {
                const provider = new LoomTruffleProvider(
                const engine = provider.getProviderEngine();
                engine.addCustomMethod("web3_clientVersion", () => "");
                return provider;
            network_id: "*"


    compilers: {
        solc: {
            version: "0.5.15",
            settings: {
                optimizer: {
                    enabled: false,
                    runs: 200
                evmVersion: "istanbul"

You can get your own infuraKey by signing up HERE. Also, your .env file should look like this:

MNEMONIC=abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about

MNEMONIC is a 12-word seed phrase for Ethereum and Loom Network. We use the same mnemonic for both chains.

Deploying ERC-20 to Ethereum

Let's write an ERC-20 contract named Web3Token.sol under contracts directory to be deployed on Ethereum.

pragma solidity >=0.4.21 <0.7.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract Web3Token is ERC20 {
    uint256 public constant INITIAL_SUPPLY = 21000000; // 21,000,000 WEB3

    string public constant name = "Web3 Token";
    string public constant symbol = "WEB3";
    uint8 public constant decimals = 18;

    constructor() public {
        // Set initial supply to 21,000,000 WEB3
        _mint(msg.sender, 21000000 * (10 ** uint256(decimals)));

Compile it:

$ truffle compile

Then you need to write a script named 2_deploy_web3token.js under migrations directory to deploy the contract.

const Web3Token = artifacts.require("Web3Token");

module.exports = async function(deployer) {
  if (network === "mainnet") {
    await deployer.deploy(Web3Token);

Deploy it on Ethereum mainnet.

$ truffle migrate --network mainnet

Deploying ERC-20 to Loom Network

It's time to create a ERC-20 contract named LoomWeb3Token.sol under contracts directory to be deployed on Loom Network. What's important here is that LoomWeb3Token.sol MUST set gateway in the constructor and have mintToGateway function that's called when users want to withdraw their assets.

pragma solidity >=0.4.21 <0.7.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract LoomWeb3Token is ERC20 {
    address public gateway;

    string public constant name = "Web3 Token";
    string public constant symbol = "WEB3";
    uint8 public constant decimals = 18;

    constructor(address gatewayAddress) public {
        gateway = gatewayAddress;

    function mintToGateway(uint256 amount) public {
        require(msg.sender == gateway, "only the gateway is allowed to mint");

        _mint(gateway, amount);

Write a script named 3_deploy_loom_web3token.js under migrations directory to deploy the contract.

const LoomWeb3Token = artifacts.require("LoomWeb3Token");

module.exports = async function(deployer) {
  if (network === "loom") {
    await deployer.deploy(LoomWeb3Token);

Deploy it to Loom Network.

$truffle migrate --network loom

You've successfully deployed Web3Token and LoomWeb3Token contracts to Ethereum and Loom Network each. Next steps are mapping contracts and transferring your assets from and to Ethereum. If you're interested in how to do this, continue reading Part 2.