> ## Documentation Index
> Fetch the complete documentation index at: https://compact-by-example.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Hello World

> Write your first Compact smart contract on Midnight: ledger state, circuits, and disclose() — store and read a message with zero-knowledge proofs.

## The Contract

<Accordion title="View Contract Code">
  ```compact theme={null}
  pragma language_version >= 0.23;

  import CompactStandardLibrary;

  // On-chain storage for the message
  export ledger message: Opaque<"string">;

  // Store a new message
  export circuit storeMessage(customMessage: Opaque<"string">): [] {
      message = disclose(customMessage);
  }

  // Retrieve the current message
  export circuit getMessage(): Opaque<"string"> {
      return message;
  }
  ```
</Accordion>

## How It Works

### Pragma Directive

```compact theme={null}
pragma language_version >= 0.23;
```

Specifies the minimum Compact compiler version this contract supports.

### Import Statement

```compact theme={null}
import CompactStandardLibrary;
```

Provides built-in types like `Opaque`, `Bytes`, and stdlib functions.

### Ledger Declaration

```compact theme={null}
export ledger message: Opaque<"string">;
```

Declares on-chain state. `Opaque<"string">` stores a variable-length byte sequence whose value is opaque to the circuit (hashed inside ZK, full value visible off-chain).

### Circuits (Functions)

```compact theme={null}
export circuit storeMessage(customMessage: Opaque<"string">): [] {
    message = disclose(customMessage);
}
```

`circuit` declares a function that compiles to a zero-knowledge circuit. `export` makes it callable from outside the contract. `[]` is the empty-tuple unit type — the circuit returns nothing.

### The disclose() Function

```compact theme={null}
message = disclose(customMessage);
```

`Opaque<"string">` values are treated as witness-tainted: the compiler refuses to write them to the public ledger unless you explicitly **disclose** them. `disclose(x)` is a compiler annotation that says "I know this value flows from a private/witness source to a public location and that's intentional."

If you tried `message = customMessage` without `disclose`, the compiler would reject it with:

```
potential witness-value disclosure must be declared but is not
```

<Note>
  **Every** circuit parameter requires `disclose()` when it flows directly into
  a ledger write, regardless of its type. The compiler is conservative: it
  doesn't know whether a given call site supplies the parameter from a public
  source or from witness data, so it forces you to declare the disclosure
  explicitly at every ledger boundary.
</Note>

## What's Next

<CardGroup cols={2}>
  <Card title="First App - Counter" icon="arrow-right" href="/basics/first-app">
    Build an interactive counter with validation
  </Card>

  <Card title="Primitive Types" icon="shapes" href="/basics/primitive-types">
    Learn about Compact's type system
  </Card>
</CardGroup>
