> For the complete documentation index, see [llms.txt](https://mvc-dao.gitbook.io/mvc-dao/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mvc-dao.gitbook.io/mvc-dao/knowledge-base/scrypt-language/stateful-contracts.md).

# Stateful Contracts

sCrypt contracts use the Unspent Transaction Output (UTXO) model: contracts reside within a UTXO and define how the Bitcoin within the UTXO can be spent. When a UTXO is spent (i.e., a public function of the sCrypt contract is successfully called), the contract is terminated. To maintain the contract's state and allow it to be called multiple times with variable states, follow these steps.

## State Modifiers

Use the modifier `@state` to declare any attribute as part of the state. State attributes can be used like regular attributes.

```c
contract Counter {
    @state
    int counter;

    constructor(int counter) {
        this.counter = counter;
    }
}
```

## Updating State

By storing the state in the locking script, the contract can maintain state across chained transactions. In the following example, the contract transitions from state0 to state1, and then to state2. Transaction tx1's input spends the UTXO from tx0, and tx2 spends tx1.

## Maintaining State

When you are ready to pass the new state to the next UTXO, simply call the built-in function `this.updateState()` with two parameters:

* `txPreimage`: The preimage of the current spending transaction. It must have a single output that contains the new state.
* `amount`: The number of satoshis in that single output.

This function is automatically generated for every stateful contract (i.e., a contract with at least one property decorated with `@state`). If you need to customize the sighash type (different from the default `SigHash.ALL | SigHash.FORKID`), you can use `updateStateSigHashType`.

Here is an example contract that records the number of `increment()` calls:

```c
contract Counter {
    @state
    int counter;

    public function increment(SigHashPreimage txPreimage, int amount) {
        // Change state
        this.counter++;

        require(this.updateState(txPreimage, amount));

        // Custom sighash type
        // require(this.updateStateSigHashType(txPreimage, amount, SigHash.SINGLE | SigHash.FORKID));
    }
}
```

## Advanced

If you need more granular control over the state, such as having multiple outputs in the spending transaction, you can call another built-in function `this.getStateScript()` to get the locking script containing the latest state properties.

Next, use `OP_PUSH_TX` to ensure the output containing the state is included in the current spending transaction. This is equivalent to using `this.updateState()` in the contract above.

```c
contract Counter {
    @state
    int counter;

    public function increment(SigHashPreimage txPreimage, int amount) {
        // Change state
        this.counter++;

        require(Tx.checkPreimage(txPreimage));

        // Get the locking script containing the latest state properties
        bytes outputScript = this.getStateScript();

        // Construct an output from the locking script and the satoshi amount
        bytes output = Utils.buildOutput(outputScript, amount);
        // Use only one input here
        require(hash256(output) == SigHash.hashOutputs(txPreimage));
    }
}
```

## Limitations

For any public function accessing stateful properties, a SigHashPreimage parameter verified by `Tx.checkPreimage()` must be included, using `OP_PUSH_TX`. This does not apply to any non-public functions, including constructors.

```c
contract Counter {
    @state
    int counter;

    constructor(int counter) {
        // Allowed: Non-public function
        this.counter = counter;
    }

    public function increment(SigHashPreimage txPreimage, int amount) {
        // Allowed
        this.counter++;

        require(Tx.checkPreimage(txPreimage));
    }

    public function foo(SigHashPreimage txPreimage, int amount) {
        require(Tx.checkPreimageOpt(txPreimage));

        // Allowed
        this.counter++;

        require(true);
    }

    public function bar(SigHashPreimage txPreimage) {
        // Not allowed: Missing Tx.checkPreimage*()
        this.counter++;

        require(true);
    }

    public function baz(int i) {
        // Not allowed: Missing SigHashPreimage
        this.counter++;

        require(true);
    }

    function baz() : int {
        // Allowed: Non-public function
        return this.counter;
    }
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mvc-dao.gitbook.io/mvc-dao/knowledge-base/scrypt-language/stateful-contracts.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
