Creating a Token by Gateway API

Tokens on Radix

Creating your own token on Radix is easy. Token creation is a built-in feature of the Radix network, and requires only a single transaction using the Radix Node API.

A token creation transaction is no more complicated than one to perform a simple transfer of tokens, as described in Making Transactions. The only difference is that you use a special transaction type and must specify the parameters of the token you want to create, such as its name and supply.

This page describes the types of tokens you can create, the parameters you can specify, and how to use these tokens after created.

Radix Tokens vs. Smart Contract-based Tokens

If you’re familiar with creating tokens on Ethereum or other smart contract blockchains, Radix’s approach is very different. Because Radix is designed as a platform for decentralized finance, secure creation and management of tokenized assets is a core feature. Therefore Radix’s design makes tokens a global feature of the ledger, rather than requiring developers to deploy nearly-duplicate smart contracts each time they want token-like functionality.

For example, on Ethereum the native ETH token is a special, with all other tokens implemented simply smart contracts that seek to follow a common interface standard (ERC-20 and similar). Developers must interact with ETH and ERC-20 tokens differently. On Radix, because tokens are a core feature of the platform, the network’s native token XRD is implemented and transacted in exactly the same way as user-created tokens. The only thing special about XRD is that it is was created at genesis and is the only token that may be used to pay transaction fees or staked to validators.

The built-in token functionality described on this page is available on the current Olympia mainnet. This functionality is defined in the network’s application layer: Radix Engine v1. Later versions of the network will implement Radix Engine v2, which will include full smart contract functionality that will retain, and greatly extend, this core concept of tokens as global resources.

For more on Radix’s plans for Radix Engine v2, see this page on our Knowledgebase

Token Types and Features

Radix’s Olympia mainnet implements two simple types of token:

Fixed tokens

A token with fixed supply specified at creation. No minting/burning is possible.

Mutable tokens

A token with mutable supply whose creator is able to mint/burn tokens.

Fixed tokens have a supply that cannot ever be affected by anyone, including its creator, and so can provide confidence to holders in some cases. Mutable tokens are more flexible, but require trust in the creator to only mint or burn tokens appropriately.

Deriving Token rri identifier

For both types of tokens, before build transactions that create tokens, the rri needs to be derived. The API call to derive token token would look like below

curl -d '{
    "network_identifier": {
        "network": "mainnet"
    },
    "public_key": {
        "hex": "03f89249c269bde09e72f351b0debb348ced0d3542d7dc26ff1bf39b7ed4bb25ca"
    },
    "symbol":"gum"
}' -H "Content-Type: application/json" -X POST "https://mainnet.radixdlt.com/token/derive" | python -m json.tool

The public_key.hex in above request is the hex of the account which will sign the transaction for the creation of token

Response to the /token/derive call
{
    "token_identifier": {
        "rri": "gum_rr1q0l7z7v5gvpezrhvvq0avfgwntfh6rvyfwqjddr4z4rsxvw6j8"
    }
}

Making a Create Token Transaction

Both types of token may be created using a simple transaction. This transaction is created using exactly the same API process described on Making Transactions. The only difference is that the /transaction/build method call must include an action of type CreateTokenDefinition.

The two types of token use a set of similar, but slightly different, data fields to describe the token:

Fixed token action data

This type immediately issues the fixed supply of tokens, and so a recipient to address must be specified. Below are the fields in action that define creation of token

type

CreateTokenDefinition

to_account.address

The Radix address that will receive the new fixed supply of tokens

token_properties.symbol

Like btc or xrd, recommended to be 3-8 characters

token_properties.name

Like Bitcoin or Radix

token_properties.description

A brief description of the nature of the token and its use (max 255 characters)

token_properties.icon_url

A URL of a token icon page, recommended to be a 32x32 pixel PNG image

token_properties.url

A URL to a page providing more information about the token

token_properties.is_supply_mutable

As this is Fixed token, this is set to false

token_properties.token_supply.value

The total fixed number of tokens to be created and that will ever exist, specified in sub-unit quantities of 1x10^18 subunits per "whole" token. eg: A supply of 1000 tokens would be specified as 1000000000000000000000

token_properties.token_supply.token_identifier.rri

the rri of token derived by making call '/token/derive'

token_properties.granularity

Granularity of the token. At the Olympia release, the only supported value is '1'

token_properties.owner.address

Owner address of the token

Mutable token action data

This type allows the creator to mint and burn tokens freely and so no immediate supply is specified.

type

CreateTokenDefinition

to_account.address

The Radix address that will receive the new fixed supply of tokens

token_properties.symbol

Like btc or xrd, recommended to be 3-8 characters

token_properties.name

Like Bitcoin or Radix

token_properties.description

A brief description of the nature of the token and its use (max 255 characters)

token_properties.icon_url

A URL of a token icon page, recommended to be a 32x32 pixel PNG image

token_properties.url

A URL to a page providing more information about the token

token_properties.is_supply_mutable

As this is Mutable token, this is set to true

token_properties.token_supply.value

This needs to be set to zero

token_properties.token_supply.token_identifier.rri

the rri of token derived by making call '/token/derive'

token_properties.granularity

Granularity of the token. At the Olympia release, the only supported value is '1'

token_properties.owner.address

Owner address of the token

Example token creation transaction

The API call to build the token creation transaction would look something like this:

  • Fixed token

  • Mutable token

curl -d '{
    "network_identifier": {
        "network": "mainnet"
    },
    "actions": [
        {
            "type" : "CreateTokenDefinition",
            "token_properties":{
                "name": "Bubblegum",
                "description" : "With this token, you will never be all out of bubblegum.",
                "icon_url" :"https://www.roddysbubblegum.io/icon-gum-32x32.png",
                "url" :"https://www.roddysbubblegum.io/about-gum/",
                "symbol":"gum",
                "is_supply_mutable" : false,
                "granularity": "1",
                "owner": { "address":"rdx1qthu8yn06k75dnwpkysyl8smtwn0v4xy29auzjlcrw7vgduxvnwnst6derj"}
            },
            "token_supply":{
                "value":"100000000000000000000000",
                "token_identifier": {
                    "rri":"gum_rr1q0l7z7v5gvpezrhvvq0avfgwntfh6rvyfwqjddr4z4rsxvw6j8"
                }

            },
            "to_account" :{
                "address":"rdx1qthu8yn06k75dnwpkysyl8smtwn0v4xy29auzjlcrw7vgduxvnwnst6derj"
            }
        }

    ],
    "fee_payer": {
        "address": "rdx1qthu8yn06k75dnwpkysyl8smtwn0v4xy29auzjlcrw7vgduxvnwnst6derj"
    } ,
    "disable_token_mint_and_burn": true
}' -H "Content-Type: application/json" -X POST "https://mainnet.radixdlt.com/transaction/build" | python -m json.tool
curl -d '{
    "network_identifier": {
        "network": "mainnet"
    },
    "actions": [
        {
            "type" : "CreateTokenDefinition",
            "token_properties":{
                "name": "Bubblegum",
                "description" : "With this token, you will never be all out of bubblegum.",
                "icon_url" :"https://www.roddysbubblegum.io/icon-gum-32x32.png",
                "url" :"https://www.roddysbubblegum.io/about-gum/",
                "symbol":"gum",
                "is_supply_mutable" : false,
                "granularity": "1",
                "owner": { "address":"rdx1qthu8yn06k75dnwpkysyl8smtwn0v4xy29auzjlcrw7vgduxvnwnst6derj"}
            },
            "token_supply":{
                "value":"100000000000000000000000",
                "token_identifier": {
                    "rri":"gum_rr1q0l7z7v5gvpezrhvvq0avfgwntfh6rvyfwqjddr4z4rsxvw6j8"
                }

            },
            "to_account" :{
                "address":"rdx1qthu8yn06k75dnwpkysyl8smtwn0v4xy29auzjlcrw7vgduxvnwnst6derj"
            }
        }

    ],
    "fee_payer": {
        "address": "rdx1qthu8yn06k75dnwpkysyl8smtwn0v4xy29auzjlcrw7vgduxvnwnst6derj"
    } ,
    "disable_token_mint_and_burn": true
}' -H "Content-Type: application/json" -X POST "https://mainnet.radixdlt.com/transaction/build" | python -m json.tool

This should build the transaction; now you just need to sign, finalize, and submit it. See Making Transactions to see how.

Minting and Burning

If you have created a mutable supply token, the address that created the token has the exclusive ability to mint or burn these tokens. Doing either is also done by a simple transaction, this time of action type MintTokens or BurnTokens. If you wish , you can include these in same transaction during the token creation.

Here is what a build step of this might look like.

  • Mint tokens

  • Burn tokens

curl -d '{
  "network_identifier": {
        "network": "mainnet"
    },
  "actions": [
      {
        "type": "MintTokens",
        "to_account":{
          "address": "rdx1qthu8yn06k75dnwpkysyl8smtwn0v4xy29auzjlcrw7vgduxvnwnst6derj"
          },
        "amount": {
         "value": "1000000000000000000000"
         "token_identifier" : {
              "rri":  "gum_rr1q0l7z7v5gvpezrhvvq0avfgwntfh6rvyfwqjddr4z4rsxvw6j8"
              }
        }
      }
    ]
    "feePayer":
      {
        "address": "rdx1qspl7mgjqwgwqyjvy2tj8swe8a4lr6mxqdhwmn60cujl6a85mqh69eg37p9ph"
      }
}' -H "Content-Type: application/json" -X POST "https://mainnet.radixdlt.com/transaction/build" | python -m json.tool
curl -d '{
  "network_identifier": {
        "network": "mainnet"
    },
  "actions": [
      {
        "type": "BurnTokens",
        "from_account":{
          "address": "rdx1qthu8yn06k75dnwpkysyl8smtwn0v4xy29auzjlcrw7vgduxvnwnst6derj"
          },
        "amount": {
         "value": "1000000000000000"
         "token_identifier" : {
              "rri":  "gum_rr1q0l7z7v5gvpezrhvvq0avfgwntfh6rvyfwqjddr4z4rsxvw6j8"
              }
        }
      }
    ]
    "feePayer":
      {
        "address": "rdx1qspl7mgjqwgwqyjvy2tj8swe8a4lr6mxqdhwmn60cujl6a85mqh69eg37p9ph"
      }
}' -H "Content-Type: application/json" -X POST "https://mainnet.radixdlt.com/transaction/build" | python -m json.tool

As before, this should build the transaction; now you just need to sign, finalize, and submit it. See Making Transactions to see how.