Defining a Fungible Token
This is the first of many tutorials in a series where you'll be creating a complete FT smart contract from scratch that conforms with all the NEAR FT standards. Today you'll learn what a Fungible Token is and how you can define one on the NEAR blockchain. You will be modifying a bare-bones skeleton smart contract by filling in the necessary code snippets needed to add this functionality.
Introduction​
To get started, switch to the 1.skeleton
folder in our repo. If you haven't cloned the repository, refer to the Contract Architecture to get started.
If you wish to see the finished code for this portion of the tutorial, that can be found on the 2.defining-a-token
folder.
Modifications to the skeleton contract​
At its very core, a fungible token is an exchangeable asset that is divisible but is not unique. For example, if Benji had 1 Canadian dollar, it would be worth the exact same as Matt's Canadian dollar. Both their dollars are fungible and exchangeable. In this case, the fungible token is the canadian dollar. All fiat currencies are fungible and exchangeable.
Non-fungible tokens, on the other hand, are unique and indivisible such as a house or a car. You cannot have another asset that is exactly the same. Even if you had a specific car model, such as a Corvette 1963 C2 Stingray, each car would have a separate serial number with a different number of kilometers driven etc...
Now that you understand what a fungible token is, let's look at how you can define one in the contract itself.
Defining a fungible token​
Start by navigating to the 1.skeleton/src/metadata.rs
file. This is where you'll define the metadata for the fungible token itself. There are several ways NEAR allows you to customize your token, all of which are found in the metadata standard. Let's break them up into the optional and non-optional portions.
Required:
- spec: Indicates the version of the standard the contract is using. This should be set to
ft-1.0.0
. - name: The human readable name of the token such as "Wrapped NEAR" or "TEAM Tokens".
- symbol: The abbreviation of the token such as
wNEAR
orgtNEAR
. - decimals: used in frontends to show the proper significant digits of a token. This concept is explained well in this OpenZeppelin post.
Optional:
- icon: The image for the token (must be a data URL).
- reference: A link to any supplementary JSON details for the token stored off-chain.
- reference_hash: A hash of the referenced JSON.
With this finished, you can now add these fields to the metadata in the contract.
Loading...
Now that you've defined what the metadata will look like, you need someway to store it on the contract. Switch to the 1.skeleton/src/lib.rs
file and add the following to the Contract
struct. You'll want to store the metadata on the contract under the metadata
field.
Loading...
You've now defined where the metadata will live but you'll also need someway to pass in the metadata itself. This is where the initialization function comes into play.
Initialization Functions​
You'll now create what's called an initialization function; you can name it new
. This function needs to be invoked when you first deploy the contract. It will initialize all the contract's fields that you've defined with default values. It's important to note that you cannot call these methods more than once.
Loading...
More often than not when doing development, you'll need to deploy contracts several times. You can imagine that it might get tedious to have to pass in metadata every single time you want to initialize the contract. For this reason, let's create a function that can initialize the contract with a set of default metadata
. You can call it new_default_meta
.
Loading...
This function is simply calling the previous new
function and passing in some default metadata behind the scenes.
At this point, you've defined the metadata for your fungible tokens and you've created a way to store this information on the contract. The last step is to introduce a getter that will query for and return the metadata. Switch to the 1.skeleton/src/metadata.rs
file and add the following code to the ft_metadata
function.
Loading...
This function will get the metadata
object from the contract which is of type FungibleTokenMetadata
and will return it.