Token Vault (clarity)
(define-map balances { account: principal } uint)
;; #[allow(unchecked_data)]
(define-public (deposit (amount uint))
(let ((current (default-to u0 (map-get? balances { account: tx-sender }))))
(begin
(map-set balances { account: tx-sender } (+ current amount))
(ok true)
)
)
)
(define-public (withdraw (amount uint))
(let ((current (default-to u0 (map-get? balances { account: tx-sender }))))
(if (>= current amount)
(begin
(map-set balances { account: tx-sender } (- current amount))
(ok true)
)
(err u402) ;; insufficient funds
)
)
)
š§ Brief Overview
- Purpose: Track deposits and withdrawals of users on-chain.
- Data Storage: Each userās balance is stored using a map.
- Functions:
deposit: Add tokens to the senderās balance.withdraw: Subtract tokens if the sender has enough.
š Code Breakdown
šļø 1. Define the Balance Map
(define-map balances { account: principal } uint)
- A map named
balancesstores user balances. - Key:
{ account: principal }ā each userās address. - Value:
uintā the unsigned integer balance.
šø 2. Deposit Function
(define-public (deposit (amount uint))
(let ((current (default-to u0 (map-get? balances { account: tx-sender }))))
(begin
(map-set balances { account: tx-sender } (+ current amount))
(ok true)
)
)
)
- Public function ā any user can call it.
- Accepts an
amountto deposit. - Fetches the current balance:
- If none exists, defaults to
0.
- If none exists, defaults to
- Adds the deposit amount to the current balance.
- Updates the map.
- Returns
(ok true)to confirm success.
š§ 3. Withdraw Function
(define-public (withdraw (amount uint))
(let ((current (default-to u0 (map-get? balances { account: tx-sender }))))
(if (>= current amount)
(begin
(map-set balances { account: tx-sender } (- current amount))
(ok true)
)
(err u402) ;; insufficient funds
)
)
)
- Also public ā allows users to withdraw.
- Gets the userās current balance.
- Checks: is the balance >= withdrawal amount?
- ā If yes: subtracts and updates the balance.
- ā If no: returns
(err u402)ā an error for insufficient funds.
š Step-by-Step: How This Contract Works
Letās walk through a real-world scenario:
š§ User A wants to deposit 100 tokens:
- Calls:
(deposit u100)
- Contract:
- Reads balance (e.g.,
u0if new). - Adds
100. - Updates the map:
{ account: UserA } ā 100.
- Reads balance (e.g.,
š§ Now User A wants to withdraw 30 tokens:
- Calls:
(withdraw u30)
- Contract:
- Checks balance: 100.
- 100 ā„ 30 ā allowed.
- Subtracts 30 ā new balance = 70.
- Updates the map.
ā User A tries to withdraw 100 (but only has 70):
- Fails the check.
- Returns:
(err u402)
Which can be interpreted in your frontend as āInsufficient Fundsā.
š§© Real-World Analogy
Think of it like a digital piggy bank for each user:
- You drop in coins (
deposit). - You can take out coins if thereās enough (
withdraw). - If itās empty or has too little, you get an error.
š Summary Table
| Component | Purpose |
|---|---|
balances |
Map storing user balances |
deposit |
Adds tokens to the userās vault |
withdraw |
Removes tokens if user has enough |
err u402 |
Error code for āInsufficient Fundsā |