Sign In / Up

Creating fungible tokens on Stacks

This contract implements the SIP-010 standard for fungible tokens on the Stacks blockchain (similar to ERC-20 on Ethereum).This is a complete implementation of a fungible token called "Clarity Coin" following the SIP-010 standard. The contract allows for minting tokens, transferring them between users, and retrieving token information.


Key Components

Trait Implementation

(impl-trait 'SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.sip-010-trait-ft-standard.sip-010-trait)

The contract implements the SIP-010 trait, ensuring compatibility with wallets, exchanges, and other applications in the Stacks ecosystem.

Token Definition

(define-fungible-token clarity-coin)

This creates a new fungible token named "clarity-coin" with no maximum supply limit.

Constants

(define-constant ERR_OWNER_ONLY (err u100))
(define-constant ERR_NOT_TOKEN_OWNER (err u101))
(define-constant CONTRACT_OWNER tx-sender)
(define-constant TOKEN_URI u"https://hiro.so")
(define-constant TOKEN_NAME "Clarity Coin")
(define-constant TOKEN_SYMBOL "CC")
(define-constant TOKEN_DECIMALS u6)

These define important values:

  • Error codes for ownership issues
  • Contract owner (deployer of the contract)
  • Token metadata including name, symbol, and decimals
  • URI pointing to token metadata (u"" indicates a UTF-8 string)
  • TOKEN_DECIMALS (u6) means values are displayed with 6 decimal places (1.000000 = 1 token)

SIP-010 Required Functions

1. Get Balance

(define-read-only (get-balance (who principal))
 (ok (ft-get-balance clarity-coin who))
)

Returns the token balance of a specified account.

2. Get Total Supply

(define-read-only (get-total-supply)
 (ok (ft-get-supply clarity-coin))
)

Returns the total number of tokens currently in circulation.

3. Get Name

(define-read-only (get-name)
 (ok TOKEN_NAME)
)

Returns the human-readable name of the token ("Clarity Coin").

4. Get Symbol

(define-read-only (get-symbol)
 (ok TOKEN_SYMBOL)
)

Returns the ticker symbol of the token ("CC").

5. Get Decimals

(define-read-only (get-decimals)
 (ok TOKEN_DECIMALS)
)

Returns the number of decimal places used for display (6).

6. Get Token URI

(define-read-only (get-token-uri)
 (ok (some TOKEN_URI))
)

Returns the URI for token metadata.

Token Operations

Mint Function

(define-public (mint (amount uint) (recipient principal))
 (begin
  (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_OWNER_ONLY)
  (ft-mint? clarity-coin amount recipient)
 )
)

Creates new tokens and assigns them to a recipient:

  • Only the contract owner can mint tokens
  • Uses Clarity's built-in ft-mint? function to create the tokens

Transfer Function

(define-public (transfer
 (amount uint)
 (sender principal)
 (recipient principal)
 (memo (optional (buff 34))))
 (begin
  (asserts! (or (is-eq tx-sender sender) (is-eq contract-caller sender)) ERR_NOT_TOKEN_OWNER)
  (try! (ft-transfer? clarity-coin amount sender recipient))
  (match memo to-print (print to-print) 0x)
  (ok true)
 )
)

Allows transferring tokens between accounts:

  • Verifies the sender is either the transaction sender or the contract caller
  • Uses Clarity's ft-transfer? function to move the tokens
  • Optionally prints a memo if provided
  • Returns success status


SIP-010 Token Vault

This contract is a simple vault that can hold and release any SIP-010 compliant tokens.


This contract acts as a vault for fungible tokens. It can receive and hold any tokens that follow the SIP-010 standard and allows the contract owner to release them.

Key Components

Trait Usage

(use-trait ft-token 'SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.sip-010-trait-ft-standard.sip-010-trait)

This imports the SIP-010 trait definition, allowing the contract to interact with any token that implements this trait.

Contract Owner

(define-constant contract-owner tx-sender)

Sets the contract deployer as the owner.

Get Balance Function

(define-public (get-balance (token <ft-token>))
  (contract-call? token get-balance (as-contract tx-sender))
)

Retrieves the balance of a specific token held by this contract:

  • Takes a token contract as parameter (must implement the ft-token trait)
  • Uses as-contract tx-sender to call from the contract's perspective
  • Returns the balance of the specified token held by this contract

Release Token Function

(define-public (release-token (amount uint) (token <ft-token>))
  (contract-call? token transfer amount (as-contract tx-sender) contract-owner none)
)

Transfers tokens from the contract to the contract owner:

  • Takes an amount and token contract as parameters
  • Calls the token's transfer function to move the specified amount
  • Sends tokens from the contract itself to the contract owner
  • No authorization check, which means any user can call this function (potentially a security issue)

This vault design allows the contract to store multiple different SIP-010 tokens and release them to the contract owner.


Lesson discussion

Swap insights and ask questions about “Build On Stacks”.

Be the first to start the discussion

Ask a question or share your thoughts about this lesson.