Supporting Multi-Native-Tokens in a Single Blockchain

Qi Zhou
Qi Zhou
Aug 23, 2018 · 5 min read

(Note that the feature is working in progress)

With standardized smart contracts for new tokens, e.g., ERC20 tokens, every person could easily create their tokens by paying the native token (e.g., ETH) on a blockchain. However, compared to native tokens, these smart-contract-based tokens have several fundamental limitations (without loss of generality, we use ETH as the native token and an ERC20 token as a smart-contract-based token):

Performing a smart contract transaction paid by a smart-contract-based token is complicated

Unlike paying such services via ETH, where a user can pay the smart contract directly and complete the rest transactions atomically, a common mistake of performing such transaction via an ERC20 token is that a user directly sends the ERC20 token to the smart contract address. This only modifies the balances of the addresses in the ERC20 wallet, and it does not complete the rest of the transactions (e.g., services) as the exchange of payment. If the mistake happens, a user may need to ask for a refund, or the owner of the smart contract may need to manually complete the rest transactions, both of which can be painful.

The correct way to perform a smart contract transaction by paying an ERC20 token generally has the following steps:

  1. Call approve() method of the ERC20 smart contract and provide the target smart contract address as the spender and the amount to be approved.
  2. Call the target smart contract method (e.g., requestAudit() in QSP) to complete the transaction paid by the ERC20.

The two-step payment is pretty inconvenient compared to one-step payment via ETH. In addition, paying via an ERC20 token introduces an attack called the allowance double-spend exploit if multiple payments are performed to the same target smart contract.

Performing a smart contract transaction paid by the smart-contract-based token needs native token as gas

Enable Multi-Native-Token on a Single Blockchain

  • Any user is able to create native tokens as long as the user pays sufficient gas represented by existing native tokens; and
  • A user could use a single-step payment to transfer any native token and complete the rest of transactions (services) atomically; and
  • A user could use any native token as gas for a transaction.

In the following, we will explain how to enable these features in details.

Introduction to Token Id

Transactions using Different Native Tokens

  • gasTokenId: an integer field to indicate which native token is used to pay gas; and
  • transferTokenId: an integer field to indicate which native token is transferred to the target address.

A miner is free to include any valid transactions in a block even each transaction have different gasTokenId’s. However, to maximize the miner’s economic benefits, it should include the transactions by ranking their values, which can be done by connecting to an external oracle source of pricing (e.g., an exchange) and determining the value of the transaction (e.g., gasPrice * gasUsed * tokenFiatPrice).

Creating New Native Token

  1. Submit a native token creation transaction, which includes gasPrice, gasTokenId, total supply, and genesis address as parameters; and
  2. When the transaction is executed (by being included in a block), the transaction will a), bump up a global integer called token id count and return the value as the new token id; b), set the balance of the genesis address of the token id as total supply; c), return success and the new token id.

VM Support for Multi-Native Token

  • GAS_TOKEN_ID, which returns the integer of current token id used to pay gas and is immutable in a transaction;
  • TRANSFER_TOKEN_ID, which returns the integer of current token id used to transfer value;
  • XCALL, XDELEGATECALL, etc, which need an extra parameter to change TRANSFER_TOKEN_ID of the subroutine.

Most of the smart contract may not be care about GAS_TOKEN_ID. However, it may revert the transaction if TRANSFER_TOKEN_ID does not match (e.g., must be the token id for payment). In addition, with XCALL, the smart contract is able to transfer value in a different native token, which enables applications such as crowdsale and decentralized exchange.

Other Thoughts

  • Use string as a token id, e.g., apple, orange.
  • Format of native-token aware address. We could enhance the address by adding token information. E.g., apple:0xabc, which means pay to address 0xabc using token apple with genesis token as gas.
  • We may also need special transactions to a) issue new tokens from an owner; b) change the owner of a native token. This allows an owner to create new native tokens for inflation model or fix total supply of a native token.


QuarkChain Official

QuarkChain provides a secure, decentralized and scalable…

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store