# Modes of Operation

HollowDB has two modus operandi: **proofs** and **whitelisting**; both can be enabled together, or separately.

<table><thead><tr><th width="146">Mode</th><th width="129">Put</th><th width="214">Update</th><th width="197">Remove</th><th>Get</th></tr></thead><tbody><tr><td><strong>Proofs</strong></td><td>-</td><td>Zero-Knowledge<br>Proof</td><td>Zero-Knowledge<br>Proof</td><td>-</td></tr><tr><td><strong>Whitelisting</strong></td><td>PUT<br>whitelist</td><td>UPDATE<br>whitelist</td><td>UPDATE<br>whitelist</td><td>-</td></tr></tbody></table>

## Using Proofs

Using zero-knowledge proofs gives full control to the users on updating the value at their key. When proofs are enabled:

* Anyone can **read** and **put**.
* To **update** or **remove** a value at some key, user must provide a zero-knowledge proof (ZKP) of preimage knowledge of that key.

HollowDB makes use of a circuit that we call "HollowDB Authentication" circuit, to which you can find more information at:

{% content-ref url="../zero-knowledge-proofs/hollowdb-authentication" %}
[hollowdb-authentication](https://docs.hollowdb.xyz/zero-knowledge-proofs/hollowdb-authentication)
{% endcontent-ref %}

You can enable or disable proof checking with the following Admin command:

```typescript
const isProofRequired = true; // or false
await admin.updateProofRequirement("auth", isProofRequired);
```

If you are deploying your own contract, you must also provide the verification key that the proof verifier will use. You can find HollowDB's keys [here](https://github.com/firstbatchxyz/hollowdb/tree/master/config/circuits). You can either provide the key in the initial state, or use the Admin to update the verification key at a later time:

```typescript
await admin.updateVerificationKey("auth", newVerificationKey);
```

## Using Whitelisting

Whitelisting is an alternative authorization mechanism that can be used within HollowDB. It can provide a fine-grained control over who can put, update, or remove a value to the database. When whitelisting is enabled:

* Anyone can **read**.
* To **put**, the user must have been put-whitelisted by the contract owner.
* To **update** or **remove**, the user must have been update-whitelisted by the contract owner.

There is a separate whitelist for put and update/remove. You can enable/disable them with the Admin:

```typescript
const isPutWhitelistRequired = true; // or false
const isUpdateWhitelistRequired = true; // or false
await admin.updateWhitelistRequirement('put', isPutWhitelistRequired);
await admin.updateWhitelistRequirement('update', isUpdateWhitelistRequired);
```

You can add & remove users from the whitelist using the Admin:

```typescript
const whitelistType = "put"; // or "update"

// add some users
const addressesToAdd = [address1, address2 /*, ... */];
await admin.updateWhitelist(addressesToAdd, whitelistType, 'add');

// remove some users
const addressesToRemove = [address3, address4 /*, ... */];
await admin.updateWhitelist(addressesToRemove, whitelistType, 'remove');
```
