> ## Documentation Index
> Fetch the complete documentation index at: https://scaffoldstacks.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Contracts

> Create and manage Clarity smart contracts

Add, test, and deploy Clarity contracts with auto-generated TypeScript bindings.

## Contents

* [Creating contracts](#creating-contracts)
* [Sample contract](#sample-contract)
* [Contract requirements](#contract-requirements)
* [Key concepts](#key-concepts)
* [Testing contracts](#testing-contracts)

## Creating contracts

Use the CLI to add new contracts to your project:

```bash theme={null}
# Create a blank contract
stacksdapp add message

# Create a SIP-010 fungible token
stacksdapp add my-token --template sip010

# Create a SIP-009 NFT
stacksdapp add my-nft --template sip009
```

## Sample contract

Here's a complete Clarity contract that demonstrates key concepts including sBTC payments, data storage, and read-only functions. This is based on the official Stacks Developer Quickstart.

```clarity theme={null}
;; Simple Message Board Contract
;; This contract allows users to read and post messages for a fee in sBTC.

;; Define contract owner
(define-constant CONTRACT_OWNER tx-sender)

;; Define error codes
(define-constant ERR_NOT_ENOUGH_SBTC (err u1004))
(define-constant ERR_NOT_CONTRACT_OWNER (err u1005))
(define-constant ERR_BLOCK_NOT_FOUND (err u1003))

;; Define a map to store messages
;; Each message has an ID, content, author, and Bitcoin block height timestamp
(define-map messages
  uint
  {
    message: (string-utf8 280),
    author: principal,
    time: uint,
  }
)

;; Counter for total messages
(define-data-var message-count uint u0)

;; Public function to add a new message for 1 satoshi of sBTC
(define-public (add-message (content (string-utf8 280)))
  (let ((id (+ (var-get message-count) u1)))
    (try! (restrict-assets? contract-caller 
      ((with-ft 'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token "sbtc-token" u1))
      (unwrap!
        ;; Charge 1 satoshi of sBTC from the caller
        (contract-call? 'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token
          transfer u1 contract-caller current-contract none
        )
        ERR_NOT_ENOUGH_SBTC
      )
    ))
    ;; Store the message with current Bitcoin block height
    (map-set messages id {
      message: content,
      author: contract-caller,
      time: burn-block-height,
    })
    ;; Update message count
    (var-set message-count id)
    ;; Emit event for the new message
    (print {
      event: "[Stacks Dev Quickstart] New Message",
      message: content,
      id: id,
      author: contract-caller,
      time: burn-block-height,
    })
    ;; Return the message ID
    (ok id)
  )
)

;; Withdraw function for contract owner to withdraw accumulated sBTC
(define-public (withdraw-funds)
  (begin
    (asserts! (is-eq tx-sender CONTRACT_OWNER) (err u1005))
    (let ((balance (unwrap-panic (contract-call? 'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token
        get-balance current-contract
      ))))
      (if (> balance u0)
        (contract-call? 'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token
          transfer balance current-contract CONTRACT_OWNER none
        )
        (ok false)
      )
    )
  )
)

;; Read-only function to get a message by ID
(define-read-only (get-message (id uint))
  (map-get? messages id)
)

;; Read-only function to get message author
(define-read-only (get-message-author (id uint))
  (get author (map-get? messages id))
)

```

## Contract requirements

For contracts that depend on external contracts (like sBTC), add requirements:

```bash theme={null}
cd contracts

clarinet requirements add SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-deposit
```

This wires up the official contracts for local testing and deployment.

## Key concepts

### sBTC Integration

This contract uses sBTC (Stacks' 1:1 backed Bitcoin) for payments:

* Requires the sBTC contract as a dependency
* Uses `restrict-assets?` for post-conditions
* Transfers sBTC using the official token contract

### Data Storage

* **Maps**: Store structured data (messages with metadata)
* **Data variables**: Track counters and global state
* **Constants**: Define immutable values

### Access Control

* `CONTRACT_OWNER` for privileged operations
* `asserts!` for authorization checks
* `tx-sender` vs `contract-caller` for security

### Read-Only Functions

* Query contract state without transactions
* Use `at-block` for historical data
* Return `Optional` types for safe lookups

## Testing contracts

Write tests in `contracts/tests/` using the Clarinet SDK (3.21+). Full patterns, ABI caching, and frontend Vitest coverage live in [Testing](/testing).

```typescript theme={null}
import { Cl, ClarityType } from "@stacks/transactions";
import { beforeEach, describe, expect, it } from "vitest";
import { initSimnet } from "@stacks/clarinet-sdk";

let simnet: Awaited<ReturnType<typeof initSimnet>>;
let address1: string;

beforeEach(async () => {
  simnet = await initSimnet();
  address1 = simnet.getAccounts().get("wallet_1")!;
});

describe("message", () => {
  it("allows user to add a new message", () => {
    const content = "Hello Stacks Devs!";
    const confirmation = simnet.callPublicFn(
      "message",
      "add-message",
      [Cl.stringUtf8(content)],
      address1
    );
    expect(confirmation.result.type).toBe(ClarityType.ResponseOk);
  });
});
```

```bash theme={null}
stacksdapp test
```
