# Saving and reading state

### The contract state <a href="#the-contract-state" id="the-contract-state"></a>

Each contract has access to a sandboxed state for storage of data. The write actions on the state are rolled back in case the contract operation returns an error. If a transaction is successfully committed, it contains the hash of the state root so that any given state is committed to the blockchain.

### #Writing to the state <a href="#writing-to-the-state" id="writing-to-the-state"></a>

Use the `Set` operation on the contract context to save to the state.

```
Set(key []byte, pb proto.Message) error
```

`go-zeknd` mandates that the data being saved is a protobuf object.

### #Reading from the state <a href="#reading-from-the-state" id="reading-from-the-state"></a>

Use the `Has` operation to check whether a particular key exists in the state

```
Has(key []byte) bool
```

To read the value saved at a key, use the `Get` operation

```
Get(key []byte, pb proto.Message) error
```

Get will unmarshal the saved data into a protobuf struct.

### #Deleting a key <a href="#deleting-a-key" id="deleting-a-key"></a>

Data saved at a key can be deleted with

```
Delete(key []byte)
```


---

# Agent Instructions: 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://developer.opzeknd.xyz/go-contract-sdk/saving-and-reading-state.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.
