Skip to content
Information Circle

The Spanning Demo App is live! Check it out here: https://demo.spanning.network/

We have also published the open-source demo code and related JavaScript utilities.

Your First Spanning ERC20 - DBUX

This tutorial will walk you through all of the setup necessary to deploy your first Spanning application; a SpanningERC20 token DBUX. DBUX is capable of being minted, owned, and transferred to users across the Spanning Network and only requires a single contract deployment.

This is the first of a series of tutorials that will teach you the basics of writing Spanning applications, from smart contracts to frontend deployments. By the end, you will have your own version of this demo application.

Recommended Developer Environment

We recommend using VS Code with the Remix plugin. For a more detailed description of how to set this up, please refer to this tutorial.

The source code and API for the Spanning contracts and base classes can be installed via:

npm install @spanning/contracts

Smart Contract Code

Contract Definition and Imports

Let's start by defining a new contract file called dbux.sol:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@spanning/contracts/token/ERC20/SpanningERC20.sol";
// Note: the following imports are included via SpanningERC20.sol
// but are included here to be explicit
import "@spanning/contracts/SpanningUtils.sol";
import "@spanning/contracts/Spanning.sol";

/**
 * The DBUX contract, utilizing the Spanning Protocol for multichain functionality.
 */
contract DBUX is SpanningERC20 {

}

This defines our new contract as a SpanningERC20 and gives us access to a host of multichain functionality and utilities, but it won't compile yet as we need to define a constructor.

Defining a Spanning Constructor

The constructor of a Solidity smart contract gets run by default when the contract is first instantiated on the blockchain. It allows the owner to pass in custom arguments for their deployment.

A SpanningERC20 constructor takes three arguments:

  • The token name
  • The token symbol
  • The local Spanning Delegate contract address to use for crosschain messaging

Our constructor for DBUX will take in one argument (the Spanning Delegate contract address) that it will pass to the SpanningERC20 constructor:

    /**
     * @dev Creates the contract, initializing various base contracts.
     *
     * @param delegateLegacyAddress - Legacy (local) Address of the Delegate
     */
    constructor(address delegateLegacyAddress)
        SpanningERC20("Dylan Bux", "DBUX", delegateLegacyAddress)
    {}

Congratulations! You have now written your first multichain token capable of being owned and transferred between users on any network! There is one more piece of functionality to add so users can get their first DBUX; minting.

Add Mint Functions

Like all ERC20s, SpanningERC20s have a default _mint function that can only be called internally. For an external user to access it we must create a new function:

    /**
     * @dev Mint DBUX to a Spanning Address
     *
     */
    function mint(bytes32 receiverAddress, uint256 amount) public {
        _mint(receiverAddress, amount);
    }

This allows a user to mint any amount of DBUX to the Spanning Address receiverAddress.

Let's also add some overrides to the mint function for user convenience.

    /**
     * @dev Mint DBUX to a local user address
     *
     * @param receiverLegacyAddress - Legacy (local) address that DBUX is minted to

     */
    function mint(address receiverLegacyAddress, uint256 amount) public {
        mint(getAddressFromLegacy(receiverLegacyAddress), amount);
    }

    /**
     * @dev Mint DBUX to the transaction sender
     */
    function mint(uint256 amount) public {
        mint(spanningMsgSender(), amount);
    }

Here we make use of two helper functions:

  • spanningMsgSender() which allows us to get the original message sender Spanning Address that has been validated by the Spanning Network
  • getAddressFromLegacy() which creates a Spanning Address for a user based on their local address and the Delegate-verified domain ID

Decimals

We are also going to override the number of decimal places our ERC20 token can have to zero from the default of 18. This will make it a bit easier to integrate with the final tutorial to build a web app.

    /**
     * @return uint8 - Number of decimals used to get a user representation.
     */
    function decimals() public view virtual override returns (uint8) {
        return 0;
    }

DBUX Full Code

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@spanning/contracts/token/ERC20/SpanningERC20.sol";
// Note: the following imports are included via SpanningERC20.sol
// but are included here to be explicit
import "@spanning/contracts/SpanningUtils.sol";
import "@spanning/contracts/Spanning.sol";

/**
 * The DBUX contract, utilizing the Spanning Protocol for multichain functionality.
 */
contract DBUX is SpanningERC20 {
    /**
     * @dev Creates the contract, initializing various base contracts.
     *
     * @param delegateLegacyAddress - Legacy (local) Address of the Delegate
     */
    constructor(address delegateLegacyAddress)
        SpanningERC20("Dylan Bux", "DBUX", delegateLegacyAddress)
    {}

    /**
     * @dev Mint DBUX to a Spanning Address
     *
     */
    function mint(bytes32 receiverAddress, uint256 amount) public {
        _mint(receiverAddress, amount);
    }

    /**
     * @dev Mint DBUX to a local user address
     *
     * @param receiverLegacyAddress - Legacy (local) address that DBUX is minted to

     */
    function mint(address receiverLegacyAddress, uint256 amount) public {
        mint(getAddressFromLegacy(receiverLegacyAddress), amount);
    }

    /**
     * @dev Mint DBUX to the transaction sender
     */
    function mint(uint256 amount) public {
        mint(spanningMsgSender(), amount);
    }

    /**
     * @return uint8 - Number of decimals used to get a user representation.
     */
    function decimals() public view virtual override returns (uint8) {
        return 0;
    }
}

Deploying Your Spanning Token

Your SpanningERC20 token is ready for deployment! The last consideration is where you want to deploy.

Check the latest Spanning Network deployment to see the most up-to-date Spanning Delegate addresses and deployable chains:

Mainnets

NetworkDomain IDSpanning Delegate AddressSpanning Address Library
Ethereum0x00000001Coming soon0x95e171b7ED0A147B51638d97aed92f15ffDE5f0D
Avalanche0x0000A86AComing soon0xF7139eA302b6735f57Ee9c563b547b295b25CedC
Arbitrum One0x0000A4B1Coming soon0x7Cdb610Ebd09B9f813EE2F5764d12898BC0286dC
Binance Smart Chain0x00000038Coming soon0xF7139eA302b6735f57Ee9c563b547b295b25CedC
Polygon0x00000089Coming soon0x1Cd3Ce05Ace44c3F4c560B0fcE0F39764030c299

Testnets

NetworkDomain IDSpanning Delegate Address
Mumbai0x000138810x2e613A930149A86D2fc42Dfbc1C5A63619FB3Bcb
Fuji0x0000A8690x9E6058C2bC70d11C7E2E4fF7128616C290374827
Goerli0x000000050x33f69d8e62e38C28bd7f0cbc61af6Eb8a0b3EF77

Deployable chains are networks on the Spanning Network that transactions can be written to. To get full multichain functionality, you must deploy your token on a deployable chain. Non-deployable networks can still host SpanningERC20s and be owned and transferred to multichain users, but they will be frozen for remote multichain owners until deployable status is added.

Here let's deploy DBUX to the Avalanche Fuji testnet. This means we must pass the constructor the Avalanche Fuji Delegate address upon construction.

Connecting VS Code Remix

If you are using VS Code and the Remix plugin, you can launch Remix by clicking the start remixd client menu option in the Ethereum Remix side menu:

Remix Launch

Follow the instructions in your VS Code terminal to go to https://remix.ethereum.org/ and connect to localhost in the File Explorer:

Remix Connect

Deploying a Contract on Remix

Open the dbux.sol file you created, compile and deploy your contract via Injected Web3 while connected to the Fuji Network.

When deploying the contract, make sure to use the correct Spanning Delegate address we got previously. Also, make sure that the contract being deployed is dbux.sol. Remix may default to deploying only the IERC20 contract.

Remix Deploy

You may also need Fuji testnet gas to deploy your application, which you can get here.

Your token is now live! In the next tutorials, we will walk through deploying a SpanningERC721 contract and building a user interface for your tokens that can connect to multiple networks to support multichain users.

Testing

You can test your token by using using the mint function calls right in Remix, and verify the results by looking at the Snowtrace testnet scanner and plugging in your newly deployed contract address: https://testnet.snowtrace.io/token/<YOUR_CONTRACT_ADDDRESS_HERE>

To test cross-chain functionality easily you can visit delegate.spanning.network which will allow you to submit transactions from any supported network to any smart contract on a deployable network. It can also be used for testing on the same chain if you don't want to go through Remix at all! Find more information about the Delegate App here.