Example implementation of a Fungible Token contract which uses near-contract-standards and simulation tests. This is a contract-only example.
Note: this README is specific to Windows and this example. For development on OS X or Linux, please see README.md.
If you're using Gitpod, you can skip this step.
- Make sure Rust is installed per the prerequisites in
near-sdk-rs
- Ensure
near-cli
is installed by runningnear --version
. If not installed, install with:npm install --global near-cli
To build run in CMD:
build.bat
This smart contract will get deployed to your NEAR account. For this example, please create a new NEAR account. Because NEAR allows the ability to upgrade contracts on the same account, initialization functions must be cleared. If you'd like to run this example on a NEAR account that has had prior contracts deployed, please use the near-cli
command near delete
, and then recreate it in Wallet. To create (or recreate) an account, please follow the directions on NEAR Wallet.
Switch to mainnet
. You can skip this step to use testnet
as a default network.
set NEAR_ENV=mainnet
In the project root, log in to your newly created account with near-cli
by following the instructions after this command:
near login
To make this tutorial easier to copy/paste, we're going to set an environment variable for your account id. In the below command, replace MY_ACCOUNT_NAME
with the account name you just logged in with, including the .near
:
set ID=MY_ACCOUNT_NAME
You can tell if the environment variable is set correctly if your command line prints the account name after this command:
echo %ID%
Now we can deploy the compiled contract in this example to your account:
near deploy --wasmFile res/fungible_token.wasm --accountId %ID%
FT contract should be initialized before usage. You can read more about metadata at 'nomicon.io'. Modify the parameters and create a token:
near call %ID% new "{\"owner_id\": \""%ID%"\", \"total_supply\": \"1000000000000000\", \"metadata\": { \"spec\": \"ft-1.0.0\", \"name\": \"Example Token Name\", \"symbol\": \"EXLT\", \"decimals\": 8 }}" --accountId %ID%
Get metadata:
near view %ID% ft_metadata
Let's set up an account to transfer some tokens to. These account will be a sub-account of the NEAR account you logged in with.
near create-account bob.%ID% --masterAccount %ID% --initialBalance 1
Add storage deposit for Bob's account:
near call %ID% storage_deposit '' --accountId bob.%ID% --amount 0.00125
Check balance of Bob's account, it should be 0
for now:
near view %ID% ft_balance_of "{\"account_id\": \""bob.%ID%"\"}"
Transfer tokens to Bob from the contract that minted these fungible tokens, exactly 1 yoctoNEAR of deposit should be attached:
near call %ID% ft_transfer "{\"receiver_id\": \""bob.%ID%"\", \"amount\": \"19\"}" --accountId %ID% --amount 0.000000000000000000000001
Check the balance of Bob again with the command from before and it will now return 19
.
As with many Rust libraries and contracts, there are tests in the main fungible token implementation at ft/src/lib.rs
.
Additionally, this project has simulation tests in tests/sim
. Simulation tests allow testing cross-contract calls, which is crucial to ensuring that the ft_transfer_call
function works properly. These simulation tests are the reason this project has the file structure it does. Note that the root project has a Cargo.toml
which sets it up as a workspace. ft
and test-contract-defi
are both small & focused contract projects, the latter only existing for simulation tests. The root project imports near-sdk-sim
and tests interaction between these contracts.
You can run all these tests with one command:
cargo test
If you want to run only simulation tests, you can use cargo test simulate
, since all the simulation tests include "simulate" in their names.
- The maximum balance value is limited by U128 (
2**128 - 1
). - JSON calls should pass U128 as a base-10 string. E.g. "100".
- This does not include escrow functionality, as
ft_transfer_call
provides a superior approach. An escrow system can, of course, be added as a separate contract or additional functionality within this contract.
near-contract-standards is currently Rust-only. We strongly suggest using this library to create your own Fungible Token contract to ensure it works as expected.
Someday NEAR core or community contributors may provide a similar library for AssemblyScript, at which point this example will be updated to include both a Rust and AssemblyScript version.
When making changes to the files in ft
or test-contract-defi
, remember to use ./build.sh
to compile all contracts and copy the output to the res
folder. If you forget this, the simulation tests will not use the latest versions.