Blockchains use tokens as a fundamental means of conveying value. They can be the chain's native unit of exchange, they can be an app's unit of exchange, and they can even be used as currency in a game world. Tokens support robust DeFi activity on Sui and other blockchains as well.
Ethereum uses the ERC-20 standard for tokens. These tokens, which developers can create for a variety of purposes, are represented as smart contracts on Ethereum. On Sui, tokens use the Coin package. Like ERC-20 tokens, developers can build Coins on Sui for a wide range of uses. However, Sui's fundamentally different data model means that each coin is owned by an address on the network.
Going through the processes to create ERC-20 tokens on Ethereum and Coins on Sui shows the differences between these two standards. Ethereum developers might also be surprised by the flexibility of the Coin package on Sui.
Deploying an ERC-20 token
For this example, we will use the Remix IDE to demonstrate the steps required to create a token using the ERC-20 standard.
1. Begin by opening the online Remix IDE in your browser.
2. Select the ERC-20 project template from OpenZeppelin.
3. In File Explorer on the left pane, select Token.sol in the contracts directory to load its dependencies.
4. Add a
_mint
function to the default constructor to specify the number of tokens to create. The following code sample shows one method.
contract MyToken is ERC-20, ERC-20Permit { constructor() ERC-20("MyToken", "MTK") ERC-20Permit("MyToken") {_mint(msg.sender, 12);} }
5. Click the Compile icon in the quick menu.
6. Open the Deploy & Run Transactions plugin, select the Remix VM (Cancun) environment, and click the Deploy button.
Following the above steps copies the ERC-20 dependencies into your project. Your contract, along with those copied dependencies, compiles into EVM bytecode and deploys onto the virtual blockchain. Your transaction was mined, and the contract representing your ERC-20 tokens is now live in Remix’s virtual blockchain.
How ERC-20 tokens are represented
To find your tokens, go to the dependency contracts on Remix (.deps folder) and navigate to the ERC-20.sol file. The first line in that abstract contract is:
mapping(address account => uint256) private _balances;
This mapping is where all balances are stored for all users. To get a user’s balance, you can call your contract’s
balanceOf
function with the user’s address. It will query this mapping and fetch the value. When displaying your funds, your MetaMask wallet makes several balanceOf() calls to various contracts and shows the results.
In other words, all transfers, mints, burns, as well as DeFi protocols interactions, ultimately updates the values inside of this mapping.
Deploying a Coin
On Sui, deployed contracts do not represent new tokens. Rather, the Sui framework uses a Coin package to provide this functionality. Although a simplified analogy, you can think of a single package as a contract. It exposes functions that can take objects and return other objects.
Follow the documentation on installing Sui to set up your coding environment. Alternatively, you can use the Remix IDE mentioned above to write Move code on Sui by installing the WELLDONE Code plug-in.
The following Move code example imports the Coin module, and employs its
create_currency
function to initialize the coin.
use sui::coin::{Self, TreasuryCap}; public struct MY_COIN has drop {} fun init(witness: MY_COIN, ctx: &mut TxContext) { let (treasury, metadata) = coin::create_currency(witness, 6, b"MY_COIN", b"", b"", option::none(), ctx); transfer::public_freeze_object(metadata); transfer::public_transfer(treasury, ctx.sender()) }
When you call
create_currency()
, Sui returns TreasuryCap<T> and CoinMetadata<T> objects for your currency, where T is the type for your currency ( MY_COIN in the previous example).
Your wallet address actually holds these objects. They exist only in your wallet, and not anywhere else, as opposed to the ERC-20 method which uses mappings to track ownership.
TreasuryCap
, short for "treasury capability", is the key needed to mint new coin supply. The TreasuryCap can be transferred to a different address of a trusted third party, or it can be destroyed. Destroying a TreasuryCap is similar to renouncing ownership in an ERC-20 contract.
How Coin objects are represented
To mint new supply, the
TreasuryCap
holder calls the Coin mint function. The function mints, or creates, a Coin<T> object that represents the amount the function mints. It sits in your wallet (assuming your address is provided as the recipient), in the literal sense. If the TreasuryCap holder calls mint() again, the process creates another Coin<T> object and transfers that coin to your wallet as well. You can have multiple Coin objects for the same currency and your total balance of that currency is the sum of these coins.
ERC-20 vs Coin features
Although Ethereum and Sui offer similar actions, such as transferring and spending, when it comes to tokens, the fundamental structures of each blockchain creates underlying differences in how these actions work.
Minting and burning
An authorized user can mint new tokens on Ethereum by calling the
mint
function in that token’s contract. This updates the _balances mapping and increases the total supply. Any user can call the burn function, but they are only allowed to burn their own balance.
Similarly on Sui, an authorized user can call the
mint
function to mint new coins, as described above. The difference is that your balance on Sui is not represented by a mapping in a shared state, but is among the very objects in your wallet. In this sense, ERC-20 is like an ATM card letting you digitally manipulate cash in a bank vault, and Sui is like a physical wallet where your balance is inherent to the cash you have on hand.
Sui supports splitting and merging of coins that are of the same type. So if you have multiple Coin objects representing your currency, you can merge them into a single object. You can also take a single Coin object and split it into multiple Coin objects of the same type.
Transferring
When transferring tokens on Ethereum, you call the
transfer
function of the token contract. This function validates that you have the balance you are transferring, then deducts your balance and increases the balance of the address you transferred to, acting similar to a physical ledger.
On Sui, because you literally own the Coin objects, you just send the Coin object to another address. There is no central location that needs to be informed of the transaction to ensure the balances are kept up to date. The action of sending an owned object from one wallet to another does not impact the rest of the blockchain.
Sending an object in this manner is called a single-owner transaction, and does not require consensus by the blockchain. As such, Sui executes single-owner transactions in parallel, achieving finality very quickly. Only shared objects on Sui require consensus.
Spending
Ethereum users are familiar with the Approve concept. Whenever you interact with any DeFi protocol, you must first approve this protocol to spend your tokens on your behalf. When you swap on Uniswap, for example, the approved router calls the transfer function in the token contract. The token contract then validates that the caller is either the owner or an approved address.
Sui doesn’t have this construct. If you own an object, you are the only party able to transfer it. There is no way for another entity to withdraw that object from your wallet. Instead, protocols on Sui take Coin objects as inputs. For example, to call the swap function on a decentralized exchange, you must pass your Coin object into the swap function, giving ownership of the object to the protocol. Now that the protocol owns this Coin object, it can swap it to another Coin object of your desired type and transfer it to your wallet.
Understanding Sui
Developers experienced on Ethereum and other blockchains who are interested in building on Sui will find many similar paradigms. Tokens, for example, serve many of the same practical purposes. However, developers who don't take the time to learn the underlying differences described above will get tripped up.
Then again, developers experienced in traditional object-oriented programming environments will find similar structures in Sui. It's intuitive to think of an object as a thing that you can store in a wallet or manipulate through code.
If you would like to learn more about creating tokens on Sui, check out the documentation.