Ethereum 2.0 vs Symbol (Part 5): Fungible Tokens

ERC-20 and Mosaic

Ivy Fung
Coinmonks
Published in
13 min readFeb 21, 2021

--

When we talk about tokenization in the physical world, we want to make something intangible tangible. For example, a “token of appreciation” is how we make the intangible “appreciation” tangible through representing it with a gift. While in the digital or virtual world, when we talk about tokenization, we want to make something tangible intangible. For example, tokenizing USD to USD Tether.

Tokenization is an important and most used function of blockchain. It allows assets to be transferred from one party to another without an intermediary. There are 2 categories of tokens, the fungible ones, and the non-fungible ones. Fungible tokens are like loyalty points or money. For example, both of us have a dollar, if we exchange them, we still both have a dollar. The value won’t change. Non-fungible tokens are like a passport. Say we both hold a passport issued from the same country. They look the same from the outside but the information listed inside is different. If we exchange the passports, they do not really represent us anymore, as each passport is unique.

ERC-20

Tokens in Ethereum, in general, are generated through deploying a smart contract to the network. As Ethereum’s smart contract is very versatile, this also means anyone can deploy a smart contract to create a token in any format. Imagine if there is no standard form while we applying for a passport, everyone could be submitting their personal information in a different order and that would be a big headache for the officers. Hence, for a better user experience, especially for entities like exchanges, a standard is introduced — the ERC-20. It is by far the most commonly used standard. Check here for a list of ERC-20 tokens.

A smart contract for ERC-20 is called a token contract. There are 6 mandatory functions in an ERC-20 token contract, and 3 optional ones (items 7–9).

  1. totalSupply(): This tells how many tokens in circulation. This is the only function that needs to have a value while the smart contract is being deployed.
  2. balanceOf(address): Returns the number of tokens the address owns.
  3. transfer(address, value): Moves said amount of tokens to the address mentioned.
  4. transferFrom(address of the sender, address of receiver, value): Moves said amount of tokens from the sender to the receiver. Useful when you are using the tokens to pay for services, which means you need to call another contract.
  5. approve(address of the spender, value): This allowed a third party address to spend the total amount set by the token's owner.
  6. allowance(address of the owner, address of the spender): Return the balance of the tokens that the spender is still allowed to spend on behalf of the owner.
  7. name(): The name you want to give to the token. As there is no central registry for token contracts, name uniqueness is not guaranteed.
  8. symbol(): A shorter form of name(). E.g. “OMG” for OmiseGO. Usually will be the ticker. Uniqueness is not guaranteed.
  9. decimal(): Indicates the tokens to be displayed. The maximum divisibility for Ethereum is 18. Ethereum does not deal with decimal. This is for visual purposes.

How each function works will be explained with an example later on.

There are 2 events involves with token contracts.

  1. Transfer(address of the sender, address of receiver, value): This event triggers the transfer of tokens from one address to another. If the target address is a contract address, it triggers the codes in the contract.
  2. Approve(address of the owner, address of spender, value): This event is called to allow a third party to move funds on the owner’s behalf, usually a service contract. It specifies also the total amount allowed. If the tokens’ owner sends a few call to the same spender address, it supersedes the previous one.

Now that we have gone through the functions and events related to a token contract, let’s start with an example for illustration purposes.

Says you would like to create a token to represent a ticket to a concert. You start with preparing the smart contract. You name() it “concertTicket” with the symbol() "CTC". Since it does not make sense to divide a ticket, the decimal() will be “0". All these functions are optional, but you must state the value of totalSupplyl(). If you plan to sell 1,000 tickets, set the value to 1,000. The rest of the functions need to be there to comply with the ERC-20 standard.

You then deploy the token smart contract by sending it to the address “0x0”. Matter of fact, you do not actually create the tokens, you create the ledgers/contract/maps that record the ownership and the transfer of ownership of the tokens. Let me explain this along with other questions regarding the rest of the functions. Along the way, there could be other features that could be incorporated but will not be brought into the discussion to keep this piece simple. Blockchain is a rabbit hole.

The ledger/map of addresses with CTC balance.

After the “CTC” token contract has been deployed, you can now start selling the concert ticket. Say Alice bought a ticket from you and you want to send a ticket to her. You call the function transfer(Alice’s address, 1 ticket). This event will fire the event Transfer(your address, Alice’s address, 1 ticket) and change the balance of tickets owned by you (from 1,000 to 999) and Alice (from 0 to 1).

The ledger/map of addresses with CTC balance.

Says you also appoint a dealer to sell 100 tickets on your behalf, and you need to authorize the dealer to transfer the tickets on your behalf. You will need to call approve(dealer’s address, 100 tickets). It will fire the event Approve(your address, dealer’s address, 100 tickets) and change the balance of the allowance the dealer is allowed to sell to 100 tickets. Note that this does not change the balance of the CTC in your address.

The ledger/map of addresses with CTC allowance to spend.

When the dealer sells a ticket to Bob, the dealer will call the function transferFrom(your address, Bob’s address, 1 ticket). This changes the ticket balance from your address to 998, and Bob’s to 1, and the allowance of the dealer to 99.

The ledger/map of addresses with CTC balance.
The ledger/map of addresses with CTC allowance to spend.

When you want to check on the token an address owns, call function balanceOf(address). When you want to know the balance of the tokens allowed to be moved by a third party, called allowance(address of the owner, address of the spender).

With this, we have covered all the functions and the events related to a token contract. You might have noticed that all actions in relation to the CTC concert ticket token ownership transfer happen only within the token contract itself.

There are 2 types of accounts in Ethereum. Both these accounts are:

  • represented with address starts with 0x,
  • can receive, send and hold both ETH and tokens, and
  • can interact with deployed smart contracts.
  1. Externally-owned account (EOA): An account owned by a user and does not cost any transaction fee to create it. It is made up of a private and public keypair. It can initiate a transaction.
  2. Contract account: It is created by deploying a smart contract. Hence, it requires transaction fees as it uses network storage. It has no private key, hence can’t sign a transaction. Ownership of the tokens can change hands only upon receiving a transaction that triggers the code.

There are a few known issues with ERC-20 that need extra caution. First, event handling issue. The receiver will not be notified of incoming transactions nor will it be able to reject any valid transactions. This is not an issue if it is sent to the correct address. Here, I am not talking about A wants to send tokens to B but accidentally sent it to C. I am talking about A meant to send it to another EOA but accidentally sent it to a contract account. To make it worse, if the contract account you sent it to does not handle the tokens you sent, it will stay in the limbo.

Second, approve() issue. As mentioned when introducing the functions of token contract, newer approve() supersede the previous one. If the spender notices an incoming change in the approved allowance and withdraw the previous allowance and withdraw again when the new approve() comes in.

There are remedies to these issues proposed, like ERC-223 which will solve the first issue. Though backward-compatible, it is not commonly used. Ethereum is very versatile, there can be functions written to counter those issues. Careful and thorough thought processes and testing are crucial.

Side note: ETH is not an ERC-20 as it was created before the standard was established. Other topics in relation to ERC-20, like how ERC-223 solves the issue, will be discussed in other articles.

Mosaic

The fungible token of Symbol, the Mosaic, is one of the plugins. The standards of the Mosaic has been set before the platform launches. The native token of Symbol, XYM, itself is a Mosaic. Please refer to part 3 about plugins.

A Mosaic has 6 configurable properties.

  1. Initial supply: The initial number of Mosaic to be created initially. The maximum number of a Mosaic is 9 billions.
  2. Divisibility: This indicate how divisible the Mosaic is. The maximum divisibility for Mosaic is 6.
  3. Duration: Mosaic will expire after the duration is up. If you want to create a non-expiring Mosaic, set this property to zero. Else the maximum days a Mosaic can live is 3650 days. It is not renewable after expired.
  4. Suply mutable: This is a boolean filed. When it is set to “true”, the total supply of the Mosaic can be altered, under strict rules. Only the creator can alter the total supply of the Mosaic.
  5. Transferable: This is a boolean field. When it is set to “true”, the Mosaic can be exchanged between any accounts freely. Else, the creator can transfer it to any account but it will then only be able to transfer it back to the cretor. Not to any other account.
  6. Restrictable: This is a boolean field. When it is set to “true”, more advanced rules can be set upon the Mosaic. This will involve another plugin — the Mosaic Restriction.

Symbol does not go by smart contract concept but uses plugins, as discussed previously. To create the Mosaic, you need to call the related transactions — MosaicDefinitionTransaction and MosaicSupplyChangeTransaction. To make development easy, with the 6 properties provided, available SDKs will take care of the rest of the execution.

Let’s take the same example used earlier. You will set the initial supply to 1,000 to represent the concert tickets; set the divisibility to zero; set the duration to be 2 months right after the concert as you do not want any unused tickets to be still available; set the supply mutability to “false” as you do not intend to change the number of seats; set “false” to make the tickets non-transferrable as you do not want buyer to resell the ticket for a higher price; and you set “true” to make the Mosaic restrictable.

A one-time fee is payable to a sink account when creating the Mosaic, on top of the transaction fee. And you might have noticed, I didn’t mentioned about the name of the Mosaic. In Symbol, a Mosaic is represented by a 64-bit unsigned integer. To name the Mosaic, another plugin called Namespace is involved, and we shall talk about it another time. For now, just note that it is possible to make the Mosaic more recognisable.

In Symbol, there are 2 types of accounts:

  1. Account: It is a private and public keypair. It is a place to hold all the mosaics. In Symbol, the balances of the Mosaics owned by each account is recorded in the account state.
  2. Multisig Account: Converted from an account. After the conversion, it can no longer initiate any transaction. It can still do any thing like a normal account can do. It can hold mosaics and send transactions but the transactions must be initiated by the account(s) having custodian over it. You can imagine it as a joint-name bank account.

Now, you can start selling the ticket. Alice want to buy a ticket. She pays you XYM (Symbol native currency) and you send her a ticket. Both of you needs to call a TransferTransacation plugin for the exchange to happen. Now, you will own 999 tickets and Alice own one. You can make the exchange happens automatically by using Aggregate Transaction plugin too.

All these can be done in an aggregate transaction.

You can’t appoint a dealer to transfer the tickets out of your account. Also, as you have set the “transferrable” property of the ticket to “false”. So, the ticket will only be able to transfer once to the buyer and the buyer will transfer the ticket back to you on the day of the concert. However, you may change the account created the tickets to a Multisig Account and add the dealer to have co-custody over it. You may have the ticket-selling application to create transactions to send 10% of commission to the dealer and 90% to your account when the buyer make payment. Says now the dealer sells a ticket to Bob, he makes a payment, 90% to you and 10% to the dealer. Subsequent to that, you and the dealer both sign a transaction to send a ticket to Bob from the Multisig Account. All these can be one as if in one transaction using Aggregate Transaction.

Says this is a Lady Gaga concert and there will be only one show. 1,000 tickets are definitely not enough for everyone. So, you decided to sell them only for her fan club members. Since you have set the “Restrictable” property to “true”, you will be able to add advanced features to handle this.

There are 2 parts to configure. First, restricting the ticket Mosaics to be transferable to accounts that are tagged. Second, the account of the fans will need to be tagged by whoever is handling the KYC (know-your-client) process. With these set up, non-fan’s account will not be able to receive the ticket Mosaic.

Until here, we have gone through the features and behaviours of Mosaic.

A Closer Look at the Differences

  1. The standard of creating of a Mosaic is pre-set and must be complied. All Mosaics are transferrable to any accounts, except if they are non-transferrable or with restriction. Even so, the transaction will fail and no Mosaic will be caught in the limbo. The only way a Mosaic will be considered lost forever is if the account holding the Mosaics lost its private key. This issue applies to all blockchains.
  2. There is only one way to transfer Mosaic, which is through TransferTransaction. Even if Aggregate Transaction is used, the TransferTransaction is still warpped within the Aggregate Transaction.

In conclusion, both ERC-20 and Mosaic are both flexible. They are not a plane model that each piece has to go into it exact place to finish the model. Other than some skeleton that you need to follow the structure, you can use your imagination to build all sort of applications.

While Ethereum smart contract is like Play-Doh, Symbol plugins are like Lego. — Ethereum 2.0 vs Symbol (Part 3)

As we know, Ethereum are very versatile. You can literally have the dApp behaves in any manner. You just need to make sure it is well tested to fend off any malicious act.

If you need the token to perform complicated rules, Ethereum is a good choice. If you need to tokenize your assets for easy tracking and transfer, Symbol’s Mosaic is a clear winner for its simplicity and well-tested system.

Knowing a knife can cut is basic knowledge. Knowing how to use a knife to your advantage is power. You don’t need a machete to spread your butter.

Special thanks to Anthony for reviewing this article.

*All translation rights reserved.

References:

  1. https://eips.ethereum.org/EIPS/eip-20
  2. https://ethereum.org/en/developers/docs/accounts/
  3. https://medium.com/@dexaran820/erc20-token-standard-critical-problems-3c10fd48657b
  4. https://medium.com/@jgm.orinoco/understanding-erc-20-token-contracts-a809a7310aa5#:~:text=Essentially%2C%20a%20token%20contract%20is,a%20third%20the%20holder's%20reputation
  5. https://www.linkedin.com/pulse/erc-223-token-standard-kiran-kumar/
  6. https://docs.symbolplatform.com/concepts/mosaic.html

Join Coinmonks Telegram group and learn about crypto trading and investing

Also, Read

Get Best Software Deals Directly In Your Inbox

--

--

Ivy Fung
Coinmonks

On a mission to talk to everyone about Blockchain.