: SIP-10 (Tokens)

A simple SIP-10 token.

Defines the token with the identifier example.


(define-fungible-token example)

When a user lacks funds.


(define-constant ERR_INSUFFICIENT_BALANCE u1000)

When a user acts on behalf of another user.


(define-constant ERR_NOT_AUTHORIZED u1001)

Mint 100,000 uExample and send it to the contract deployer.


(ft-mint? example u100000 tx-sender)

User to user transfering.


(define-public (transfer 

Amount of tokens being sent.


        (amount uint) 

Sender of tokens.


        (from principal)

Receiver of tokens.


        (to principal) 

Optionally stores arbitrary data.


        (memo (optional (buff 34)))
    )
    
    (begin

Makes sure sender is the contract caller.


        (asserts! 
            (is-eq tx-sender from) 
            (err ERR_NOT_AUTHORIZED)
        )
        

Makes sure the sender has the funds.


        (asserts! 
            (>= (ft-get-balance example from) amount) 
            (err ERR_INSUFFICIENT_BALANCE)
        )
        

Send the tokens or panic.


        (unwrap-panic 
            (ft-transfer? example amount from to)
        )
        (ok true)
    )
)

The human-readable name of the token.


(define-read-only (get-name)
    (ok "Example")
)

The ticker of the token.


(define-read-only (get-symbol)
    (ok "EXP")
)

Where the decimal point is stored.


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

URL of the manifest (or none).


(define-public (get-token-uri)

Follows this specification.


    (ok (some "https://example.com/manifest.json"))
)

The total supply of tokens.


(define-read-only (get-total-supply)
    (ok (ft-get-supply example))
)

The balance of a specific user.


(define-read-only (get-balance (address principal))
    (ok (ft-get-balance example address))
)

Create our contract.


$ clarinet contract new SIP-10
Updated Clarinet.toml with contract SIP-10

Now add the source to the contract located at contracts/SIP-10.clar.

Enter the REPL.


$ clarinet poke
clarity-repl v0.21.0
Enter "::help" for usage hints.
Connected to a transient in-memory database.

List of contracts and callable functions.


Contracts
+---------------------+----------------------------------+
| Contract identifier | Public functions                 |
+---------------------+----------------------------------+
| address.SIP-10      | (get-balance(address principal)) |
|                     | (get-decimals)                   |
|                     | (get-name)                       |
|                     | (get-symbol)                     |
|                     | (get-token-uri)                  |
|                     | (get-total-supply)               |
|                     | (transfer                        |
|                     |     (amount uint)                |
|                     |     (from principal)             |
|                     |     (to principal)               |
|                     |     (memo (optional (buff 34)))) |
+---------------------+----------------------------------+

Wallets loaded in from settings/Devnet.toml, balances listed in uSTX.


Initialized balances
+--------------------+-----------------+
| Address            | STX             |
+--------------------+-----------------+
| address (deployer) | 100000000000000 |
+--------------------+-----------------+
| address (wallet_1) | 100000000000000 |
+--------------------+-----------------+
| address (wallet_2) | 100000000000000 |
+--------------------+-----------------+
| address (wallet_3) | 100000000000000 |
+--------------------+-----------------+
| address (wallet_4) | 100000000000000 |
+--------------------+-----------------+
| address (wallet_5) | 100000000000000 |
+--------------------+-----------------+
| address (wallet_6) | 100000000000000 |
+--------------------+-----------------+
| address (wallet_8) | 100000000000000 |
+--------------------+-----------------+
| address (wallet_7) | 100000000000000 |
+--------------------+-----------------+
| address (wallet_9) | 100000000000000 |
+--------------------+-----------------+

Now we can call the public functions.

Get the total supply of example.


$ (contract-call? .SIP-10 get-total-supply)
(ok u100000)

Transfer 100 of our uExample to a random user.
Note: Principales are prefixed by ‘.


$ (contract-call? .SIP-10 transfer u100 tx-sender 'SP3TZ3N
$ Y4GB3E3Y1K1D40BHE07P20KMS4A8YC4QRJ none)
Events emitted
{
  type: "ft_transfer_event",
  ft_transfer_event: {
    asset_identifier: "address.SIP-10::example",
    sender: "address",
    recipient: "address",
    amount: "100"
  }
}
(ok true)