| name | clarity-developer |
| description | Creates Clarity smart contracts for Stacks blockchain. Use when writing Clarity contract code, implementing SIP009 NFTs, SIP010 fungible tokens, defining traits, or working with Clarinet for testing and deployment. Don't use for Solidity, Rust, or general blockchain development outside Stacks. |
Clarity Smart Contract Development
Procedures
Step 1: Project Setup
- Verify that Clarinet is installed by running
clarinet --version. If not installed, direct the user to install from https://github.com/hirosystems/clarinet.
- If starting a new project, run
clarinet new <project-name> to initialize the project structure.
- Navigate to the contracts directory to create or edit
.clar files.
- Read
references/clarinet.md for detailed Clarinet commands and usage.
Step 2: Syntax & Structure
- Write Clarity code using LISP-like S-expression syntax with parentheses.
- Use the template in
assets/contract-template.clar as a starting point for basic contracts.
- Ensure all expressions follow the pattern:
(function-name arg1 arg2 ...).
- Use comments (
;;) to document code, but remember: code is visible on-chain.
Step 3: Type System
- Read
references/types.md to understand primitive types (int, uint, bool, principal), sequence types (list, tuple, buffer, string), and composite types (response, optional, trait).
- Clarity enforces strict type safety - do not mix types in expressions.
- Use type signatures when defining variables and functions.
Step 4: Data Storage
- Define constants using
(define-constant NAME value).
- Define variables using
(define-data-var NAME TYPE initial-value).
- Define maps using
(define-map NAME KEY_TYPE VALUE_TYPE).
- Reference
references/keywords.md for full keyword syntax.
Step 5: Functions
- Define public functions with
(define-public (name (arg type)) ...) - must return a response type.
- Define private functions with
(define-private (name (arg type)) ...).
- Define read-only functions with
(define-read-only (name (arg type)) ...).
- State changes (variable updates, token transfers) only persist if the public function returns
ok. Returning err rolls back all changes.
Step 6: Control Flow & Error Handling
- Use
(asserts! condition (err code)) to validate conditions.
- Use
(try! expression) to handle response types.
- Use unwrap functions:
(unwrap! value default), (unwrap-panic value), (unwrap-err! ...).
- Use
(if condition true-expr false-expr) for conditional logic.
- Read
references/best-practices.md for coding style tips.
Step 7: Traits (Interfaces)
- Read
references/keywords.md to understand trait syntax.
- Define traits with
(define-trait NAME ((function-name (arg-types) (return-type)))).
- Implement traits with
(impltrait CONTRACT.TRAIT).
- Use traits for inter-contract calls and dynamic dispatch.
Step 8: Token Standards
- For NFTs, read
references/sip009-nft.md and implement the SIP009 interface.
- For fungible tokens, read
references/sip010-ft.md and implement the SIP010 interface.
- Ensure compliance with Stacks Improvement Proposals for interoperability.
Step 9: Practice Projects
- Read
references/practice-projects.md for detailed implementations of:
- Time-locked wallet (block-height based unlocking)
- Smart claimant (inter-contract calls)
- Multi-signature vault (voting mechanism with
fold)
Step 10: Building a Marketplace
- Read
references/marketplace.md for NFT marketplace implementation.
- Implement listing creation, cancellation, and fulfillment.
- Handle NFT escrow and payment processing.
Step 11: Runtime Cost Analysis
- Read
references/cost-analysis.md to understand execution costs.
- Run
clarinet check for cost analysis.
- Run
npm run test:report for detailed cost reports.
- Optimize by reducing contract calls, inlining variables, and avoiding unnecessary complexity.
Step 12: Best Practices
- Read
references/best-practices.md for:
- Coding style guidelines
- What to store on-chain (use hashes for large data)
- Contract upgradability patterns (modular design)
- Avoid hardcoding principals - use trait references.
- Separate storage and logic into different contracts.
Step 13: Working with sBTC
- Read
references/sbtc.md for sBTC integration.
- sBTC uses SIP010 standard with 8 decimals.
- Mainnet contract:
SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token
Step 14: Testing & Validation
- Run
clarinet check to analyze contracts for type errors and runtime costs.
- Run
clarinet test to execute unit tests.
- Use
clarinet console for interactive debugging.
- Use
::get_assets_maps to check balances.
- Use
::advance_chain_tip to simulate block progression.
Error Handling
- If Clarinet is not found, instruct the user to install it from https://github.com/hirosystems/clarinet.
- If
clarinet check fails with type errors, read references/types.md to verify type signatures.
- If public function does not return a response type, add
(ok value) or (err value) wrapper.
- If contract call returns
err unexpectedly, check that all state modifications are inside functions that return ok.
- For trait-related errors, verify the trait is defined and the implementation matches all function signatures.
- If runtime costs are too high, read
references/cost-analysis.md for optimization techniques.
- For upgradability issues, read
references/best-practices.md section on contract upgradability.
Resources