# Zen Protocol Docs

Documentation of the ZP desktop wallet, web wallet, api, sdk and cli.

{% hint style="info" %}

#### Please note that the use of the software is subject to the terms of its [licence](https://github.com/zenprotocol/zenprotocol/blob/master/LICENSE.md) and [Authorized Protocol](https://github.com/zenprotocol/zenprotocol/blob/master/AUTHORIZED_PROTOCOL.pdf).&#x20;

{% endhint %}

### Apps

{% content-ref url="/pages/-LOlz32OSAWG25yioSjI" %}
[Headless Full Node](/apps/headless)
{% endcontent-ref %}

{% content-ref url="/pages/-MQS6bPH89a2i0RNAokf" %}
[Wallet](/apps/wallet)
{% endcontent-ref %}

{% content-ref url="/pages/-LOCyRQaX4LV-cV10Tjw" %}
[Web Wallet](/apps/wallet/web-wallet)
{% endcontent-ref %}

{% content-ref url="/pages/-L9oPpPwW22sD7V7ZwHm" %}
[Desktop Wallet](/apps/wallet/preparation)
{% endcontent-ref %}

{% content-ref url="/pages/-MT1DjYm7vsAZn006ddo" %}
[Explorer](/apps/explorer)
{% endcontent-ref %}

{% content-ref url="/pages/-LEsfyq2ZvvjbC7pf6q6" %}
[Zen.js](/apps/zen_js)
{% endcontent-ref %}

{% content-ref url="/pages/-LOmShX2ZYHWGIGe2G1C" %}
[Oracle](/apps/oracle)
{% endcontent-ref %}

{% content-ref url="/pages/-MRPJR8hiYDndKaUZn1L" %}
[Dex](/apps/dex)
{% endcontent-ref %}

{% content-ref url="/pages/-MRFqbjAa3s1s5cHuUye" %}
[Fixed Payout](/apps/fixed-payout)
{% endcontent-ref %}

### Smart Contracts

{% content-ref url="/pages/-MQh\_5c\_HCs15K6NECOO" %}
[Contract Structure](/contract-structure)
{% endcontent-ref %}

{% content-ref url="/pages/-MQvUXhtNlqyKqQZWDQT" %}
[Contract Cost](/contract-cost)
{% endcontent-ref %}

{% content-ref url="/pages/-MQwdlheRXRYRBC-MLTq" %}
[Contract Activation](/contract-activation)
{% endcontent-ref %}

{% content-ref url="/pages/-MQhbJIz19SFla8-ib5b" %}
[Contract Examples](/contract-examples)
{% endcontent-ref %}

{% content-ref url="/pages/-MQrZx8jX5nZAUtFEN0h" %}
[Smart Contracts SDK](/smart-contracts-sdk)
{% endcontent-ref %}

### Contract Language

{% content-ref url="/pages/-LNJxNKpkZMJFvWLr45A" %}
[Contracts Language ZF\*](/zf)
{% endcontent-ref %}

### Consensus

{% content-ref url="/pages/-MQh-PVzbxZ84F42Cp8O" %}
[Common Goods Pool](/common-goods-pool)
{% endcontent-ref %}

{% content-ref url="/pages/-MQhHvWl5yByAYvN8xWX" %}
[Block Validation](/block-validation)
{% endcontent-ref %}

{% content-ref url="/pages/-LAO3ifbUGjyShEKlQPH" %}
[Transaction Validation](/transaction-validation)
{% endcontent-ref %}

{% content-ref url="/pages/-LEAitBQQ83e4wmpO07P" %}
[Serialization](/serialization)
{% endcontent-ref %}

### Troubleshooting

{% content-ref url="/pages/-LCZOrZyyI8cJROa9384" %}
[Responsible Disclosure](/troubleshooting-1/responsible-disclosure)
{% endcontent-ref %}

{% content-ref url="/pages/-LE5NI-zjSVK9h6pegOP" %}
[Bug Bounty](/troubleshooting-1/bug-bounty)
{% endcontent-ref %}

{% content-ref url="/pages/-LANSWNugnN8OsbgNM6-" %}
[Known Bugs](/troubleshooting-1/troubleshooting)
{% endcontent-ref %}

### For Miners

{% content-ref url="/pages/-MQmUUOcqD2Y1KZf3SLz" %}
[Pools](/for-miners/for-miners)
{% endcontent-ref %}

{% content-ref url="/pages/-LGg-mTEQoh6HuUVjzaD" %}
[GPU Mining](/for-miners/gpu-mining)
{% endcontent-ref %}

{% content-ref url="/pages/-LGLLsRQLHK6-K4A9qqB" %}
[GPU Bounties](/for-miners/development-bounties)
{% endcontent-ref %}

#### Updates and discussions: <a href="#please-join-us-for-updates-and-discussions" id="please-join-us-for-updates-and-discussions"></a>

[Telegram](https://t.me/zenprotocol) | [Blog](https://blog.zenprotocol.com/) | [Forum](https://forum.zenprotocol.com) | [Youtube](https://www.youtube.com/channel/UCVm4j3TrmD8mSvvExG_CAIw)


# Headless Full Node

By running a full node you can validate the consensus rules of the Zen Protocol independently. There are two ways to run a full node:

{% content-ref url="/pages/-L9iwr2pZXahP-6FtOde" %}
[Full Node NPM Package](/apps/headless/headless)
{% endcontent-ref %}

{% content-ref url="/pages/-LATPwxZ5kVtlchDNlmd" %}
[Build from Source](/apps/headless/build-fromsource)
{% endcontent-ref %}

{% content-ref url="/pages/-L9nc-2Oy5iZbYwWDuh2" %}
[CLI](/apps/headless/cli)
{% endcontent-ref %}

{% content-ref url="/pages/-L9ivLpHyfBmcX7NOVQe" %}
[API](/apps/headless/api)
{% endcontent-ref %}

{% content-ref url="/pages/-MQv8JiqHJpem9FfOzrH" %}
[Deploy](/apps/headless/deploy)
{% endcontent-ref %}


# Full Node NPM Package

Run the Zen Node in headless mode

**Please note that the usage of the software is only permitted to anyone who purchased a license during the license sale period.** [**Sale Terms**](https://www.zenprotocol.com/legal/zen_protocol_token_sale_agreement.pdf)

## Install/Update Wallet <a href="#installupdate-wallet" id="installupdate-wallet"></a>

### OSX <a href="#osx" id="osx"></a>

1. Install [mono-devel](http://www.mono-project.com/download). If you choose to install via a package manager, add Mono's own repository first.
2. Install [brew](https://brew.sh)
3. Open the **Terminal** (can be found from **search** bar)
4. Install lmdb. Enter the command (in terminal) `brew install lmdb`.
5. [Install Nodejs](https://nodejs.org/en/download/)
   1. Recommended to install using [NVM](https://github.com/creationix/nvm#installation)
   2. Recommended to install Node LTS `nvm install 8.9.4`

### Windows <a href="#windows" id="windows"></a>

1. Install [.NET Framework 4.7](https://www.microsoft.com/en-us/download/details.aspx?id=55167).
2. [Install Nodejs](https://nodejs.org/en/download/) (LTS version recommended)
3. Open the [Command Prompt](https://www.lifewire.com/how-to-open-command-prompt-2618089)

### Linux <a href="#linux" id="linux"></a>

1. Install [mono-devel](http://www.mono-project.com/download). If you choose to install via a package manager, add Mono's own repository first.
2. Install lmdb. The package name is liblmdb0 on Ubuntu and lmdb on Fedora. `sudo apt install liblmdb0`
3. Install Nodejs (Version >= 6)
   1. Recommended to install using [NVM](https://github.com/creationix/nvm#installation)
   2. Recommended to install Node LTS (8.9.4) `nvm install --lts`

### Point your npm directory to our repository <a href="#step-1-installation" id="step-1-installation"></a>

Run the following commands in the Terminal / Command Prompt:

```
npm config set @zen:registry https://www.myget.org/F/zenprotocol/npm/
```

### Installing / Updating <a href="#step-1-installation" id="step-1-installation"></a>

Run the following commands in the Terminal / Command Prompt:

```
npm install @zen/zen-node -g
```

### Running the node <a href="#step-3-running-wallet-and-full-node" id="step-3-running-wallet-and-full-node"></a>

Run `zen-node` from anywhere in your command line (terminal) to start up the node

**Full Wipe (Clear Data)**

To completely wipe the blockchain + the wallet from your node run: `zen-node --wipe full`

**Running with a miner (CPU Only)**

Run the node with a miner. You can also choose the amount of threads you want to utilize.

`zen-node --miner 4`

### Running with options / arguments <a href="#running-with-arguments" id="running-with-arguments"></a>

```
USAGE: zen-node.exe [--help] [--test] [--api <string>] 
                    [--bind <string>] [--ip <string>] 
                    [--wipe [<full>]] [--miner [<threads>]] 
                    [--addressdb][--data-path <string>] 
                    [--service-bus <string>] 
                    [--publisher <string>] 
                    [--connectwallet] 
                    [--origin [<string>]] 
                    [--remote]

OPTIONS:

    --test                 use testnet
    --api <string>         enable api and set bind address
    --bind <string>        set the address the node should listen on
    --ip <string>          specify the IP the node should relay to other peers
    --wipe [<full>]        wipe database, specify full to wipe the wallet's private key
    --miner [<threads>]    enable miner and optionally specify number of threads
    --addressdb            enable the AddressDB module
    --data-path <string>   set the data folder path
    --service-bus <string> expose the service bus over zeromq address
    --publisher <string>   expose the publisher over zeromq address
    --connectwallet        connect the new desktop wallet
    --origin [<string>]    add CORS origin
    --remote               automatically configure for remote usages
    --help                 display this list of options.

```


# Build from Source

If you would like to build Zen Protocol from source you can clone the master brach of <https://github.com/zenprotocol/zenprotocol> and build it.

### Linux

1. Install mono-devel from <http://www.mono-project.com/download>. If you choose to install via a package manager, add Mono's own repository first.
2. Install lmdb. The package name is liblmdb0 on Ubuntu and lmdb on Fedora.
3. Run the following:

```
./paket restore
msbuild src /property:Configuration=Release -m
```

### OSX

1. Install mono-devel from <http://www.mono-project.com/download>. If you choose to install via a package manager, add Mono's own repository first.
2. Install lmdb. You can get it via brew with `brew install lmdb`.
3. Run the following:

```
./paket restore
msbuild src /property:Configuration=Release -m
```

### Windows

Windows is not yet supported

## Run

### Linux and OSX

```
cd src/Node/bin/Debug
./zen-node
```

### Windows

```
cd src\Node\bin\Debug
zen-node.exe
```

## CLI

You can communicate with the node with `zen-cli`. Enter the `bin` directory of the node (`src/Node/bin/Debug | Release`) and run:

### Linux and OSX

```
./zen-cli --help
```

## License

This software is available under the Zen Protocol Software License, which may be viewed at [LICENSE.md](https://github.com/zenprotocol/zenprotocol/blob/master/LICENSE.md).


# CLI

Interact with the headless Zen Node via the Command Line Interface

#### [The zen-cli comes bundled together with the zen-node package. So start by installing and running the zen-node package in headless mode.](/apps/headless/headless)

Open your terminal and run `zen-node`

Now you can open another tab and your terminal and run `zen-cli` commands

```
USAGE: zen-cli [--help] [--port <port>] [--test] [<subcommand> [<options>]]

SUBCOMMANDS:

    balance <options>            get wallet balance
    history <options>            list wallet transactions
    address <options>            get wallet address
    resync <options>             resync wallet
    import <options>             import wallet seed from mnemonic sentence
    send <options>               send asset to address
    activate <options>           activate contract
    extend <options>             extend contract activation
    execute <options>            execute contract
    active <options>             list active contracts
    publishblock <options>       publish a block to the network
    accountexists <options>      check for an existing account
    checkpassword <options>      check a password
    mnemonicphrase <options>     get the mnemonic phrase
    exportzenpublickey <options> export zen extended public key
    importzenpublickey <options> import zen extended public key 
                                 and create watch-only account
    removewallet <options>       remove wallet
    publickey <options>          derive a public key 
                                 from a given derivation path
    rawtx-create <options>       create a raw transaction that pass 
                                 the asset and amount to the address
    rawtx-sign <options>         sign all possible inputs of the raw
                                 transaction and return the signed 
                                 transaction
    rawtx-publish <options>      publish a fully signed raw transaction
    wallet-create <options>      create a wallet from a newly generated 
                                 mnemonic phrase
    blockchain-info <options>    get blockchain info
    walletkeys <options>         get wallet keys
    signmessage <options>        sign message with your privates

    Use 'zen-cli <subcommand> --help' for additional information.

OPTIONS:

    --port, -p <port>     port of zen-node API
    --test, -t            use testnet port
    --help                display this list of options.


```

## Examples

### Check your balances

```
> zen-cli balance

Asset	| Balance
============================
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000	| 1900000000
```

### Get wallet address

```
> zen-cli address

tp1q7n4l3dldcv69wfyqm32mpkwvf56q5kjdv7ma5p2668z05ljcv2gsq3ke4q
```

### Send Transaction

```
> zen-cli spend 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 1000000 tp1q7n4l3dldcv69wfyqm32mpkwvf56q5kjdv7ma5p2668z05ljcv2gsq3ke4q

Ok "Binary [||]"
```

### Import Wallet

```
> zen-cli import mypassword ability able about above absent absorb abstract absurd abuse access accident account accuse achieve acid acoustic acquire across act action actor actress actual adapt




```

### Resync Blockchain

```
> zen-cli resync

Success
```

### Activate Contract

```
> zen-cli activate path-to-file number-of-blocks rlimit


Success
```


# API

Documentation of the zen-node api end points

### Setup

Start by installing the [headless zen-node library](/apps/headless/headless) and running a node locally.

Use port *11567* for mainnet network or use *31567* for testnet network

### API End Points

{% content-ref url="/pages/-L9ef1WjO0PfdeFEW0Dy" %}
[Wallet](/apps/headless/api/wallet)
{% endcontent-ref %}

{% content-ref url="/pages/-L9efB461o86x9ostvqT" %}
[Contracts](/apps/headless/api/contracts)
{% endcontent-ref %}

{% content-ref url="/pages/-LHmy1d9Q8rgZp5HheqN" %}
[Blockchain](/apps/headless/api/blockchain)
{% endcontent-ref %}

{% content-ref url="/pages/-LHmwNbSTs\_oojP3vUfJ" %}
[General](/apps/headless/api/general)
{% endcontent-ref %}

{% content-ref url="/pages/-MRbDz5oIcA3GJ7NFPC9" %}
[AddressDB](/apps/headless/api/addressdb)
{% endcontent-ref %}

### Import API Collection with Postman

You can easily import all of the api end points and start playing with them using [Postman](https://www.getpostman.com/)

Link to import the Zen Protocol API Postman collection:

<https://www.getpostman.com/collections/808a5509180c0df55d18>


# Wallet

All of the wallet end points

## Wallet Exists?

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/wallet/exists`

Check if wallet has already been created / imported.\
\
Used for building a rich wallet client UI.

{% tabs %}
{% tab title="200 " %}

```javascript
true
```

{% endtab %}
{% endtabs %}

## Public Address

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/wallet/address`

Fetch your public key

{% tabs %}
{% tab title="200 " %}

```javascript
"tp1q7n4l3dldcv69wfyqm32mpkwvf56q5kjdv7ma5p2668z05ljcv2gsq3ke4q"
```

{% endtab %}
{% endtabs %}

## Asset Balances

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/wallet/balance`

{% tabs %}
{% tab title="200 " %}

```javascript
[
    {
        "asset": "asset",
        "balance": 2147483649
    }
]
```

{% endtab %}
{% endtabs %}

## Received by address

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/wallet/receivedbyaddress`

Transaction received by address

{% tabs %}
{% tab title="200 " %}

```json
[
    {
        "address": "tzn1q7fnh47xftwr2zpxtpxepf022l9u5k0kusahactcn099vlumxy58s4kzzx6",
        "asset": "00",
        "amount": "417971197827512"
    }
]
```

{% endtab %}
{% endtabs %}

## Address Output

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/wallet/addressoutputs`

#### Query Parameters

| Name                                      | Type   | Description |
| ----------------------------------------- | ------ | ----------- |
| address<mark style="color:red;">\*</mark> | string |             |

{% tabs %}
{% tab title="200 List of address outputs" %}

```json
[
    {
        "outpoint": {
            "txHash": "004ea75d74f2e3ac34634b43c979092b8eb04f9de544b905e5cb8ae8b316b120",
            "index": 2
        },
        "asset": "00",
        "amount": "187500000",
        "confirmations": 266423,
        "spent": true
    }
]
```

{% endtab %}

{% tab title="400 Error" %}

```
address is missing
```

{% endtab %}
{% endtabs %}

## Address Balance

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/wallet/addressbalance`

#### Path Parameters

| Name                                      | Type   | Description                              |
| ----------------------------------------- | ------ | ---------------------------------------- |
| address<mark style="color:red;">\*</mark> | string | Address you want to check the balance of |

{% tabs %}
{% tab title="200 " %}

```json
[
    {
        "outpoint": {
            "txHash": "004ea75d74f2e3ac34634b43c979092b8eb04f9de544b905e5cb8ae8b316b120",
            "index": 2
        },
        "asset": "00",
        "amount": "187500000",
        "confirmations": 266423,
        "spent": true
    },
    {
        "outpoint": {
            "txHash": "0052a006747ec056de0bf3bc044983a370d6ff5aa4659ebbbe45e03633d21843",
            "index": 2
        },
        "asset": "00",
        "amount": "1000000000",
        "confirmations": 380819,
        "spent": true
    }
]

```

{% endtab %}

{% tab title="400: Bad Request " %}

```
address is missing
```

{% endtab %}
{% endtabs %}

## Remove Wallet

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/wallet/remove`

Remove wallet

#### Request Body

| Name     | Type   | Description     |
| -------- | ------ | --------------- |
| password | string | wallet password |

{% tabs %}
{% tab title="200 " %}

```
```

{% endtab %}
{% endtabs %}

## Zen Public Key (XPUB)

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/wallet/zenpublickey`

Return the Zen public key (XPUB)

{% tabs %}
{% tab title="200 " %}

```json
tpubDDBhhX7DRpypAPZZhVMEtnyzJJrCRgQGSzNwgpqxTxXHdvedtkE2pjjVbY5NHvY6FLL2c8mzQcQnxK4s4pjt5BS6cBUHvan5y6NRtHft2tp
```

{% endtab %}
{% endtabs %}

## Resync

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/wallet/resync`

{% tabs %}
{% tab title="200 " %}

```
```

{% endtab %}
{% endtabs %}

## Transaction Count

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/wallet/transactioncount`

Get transaction count (used for pagination)

#### Path Parameters

| Name | Type   | Description |
| ---- | ------ | ----------- |
|      | string |             |

{% tabs %}
{% tab title="200 " %}

```
25
```

{% endtab %}
{% endtabs %}

## Transaction History

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/wallet/transactions`

Retreive the transaction history

#### Request Body

| Name | Type   | Description |
| ---- | ------ | ----------- |
| take | number |             |
| skip | number |             |

{% tabs %}
{% tab title="200 An array of tx objects, where each transaction can have a single or multiple tx deltas or incoming or outgoing assets." %}

```javascript
[
    {
        "txHash": "txHash",
        "asset": "00",
        "amount": 0,
        "confirmations": "someConfrimation"
    }
]
```

{% endtab %}

{% tab title="400 Remember to add the parameters skip and take" %}

```
Invalid input
```

{% endtab %}
{% endtabs %}

## Import Wallet

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/import`

#### Path Parameters

| Name  | Type  | Description                              |
| ----- | ----- | ---------------------------------------- |
| words | array | A list of 12 or 24 bip39 compliant words |

#### Request Body

| Name     | Type   | Description                                |
| -------- | ------ | ------------------------------------------ |
| password | string | A password to encrypt your mnemonic phrase |

{% tabs %}
{% tab title="200 The account was imported correctly" %}

```javascript
```

{% endtab %}

{% tab title="400 Account already exist" %}

```
```

{% endtab %}
{% endtabs %}

## Public Key

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/publickey`

Get the public key paired with the path

#### Request Body

| Name     | Type   | Description           |
| -------- | ------ | --------------------- |
| password | string | wallet password       |
| path     | string | bit44 derivative path |

{% tabs %}
{% tab title="200 " %}

```
0278e2befe3063f02b01d1f7c08abae7d0669b58be6691baac94e67ad52c540f22
```

{% endtab %}
{% endtabs %}

## Send Transaction

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/send`

Send a transaction to another regular wallet address

#### Request Body

| Name     | Type   | Description                          |
| -------- | ------ | ------------------------------------ |
| output   | string | compose of address, asset and amount |
| password | string | 1234                                 |

{% tabs %}
{% tab title="200 Return the transaction hash of the send transaction" %}

```javascript
4f49f18a0575e701661d95cd221feb4399dc25e6f8230d37c4e2860cbd248fb9
```

{% endtab %}
{% endtabs %}

## Sign

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/sign`

#### Path Parameters

| Name     | Type   | Description           |
| -------- | ------ | --------------------- |
| password | string | wallet password       |
| message  | string | txhash                |
| path     | string | bit44 derivative path |

{% tabs %}
{% tab title="200 " %}

```
fcea0b7537c68117144dd95a801bbb9a2e2628463abd0eaf7e0eed2f5cc48e0219cb883ae22b9117d2a661f61a6a6b5612087fe19afa4576eff7c5fc62e2cdfb
```

{% endtab %}
{% endtabs %}

## Check Password

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/checkpassword`

#### Path Parameters

| Name     | Type   | Description     |
| -------- | ------ | --------------- |
| password | string | wallet password |

{% tabs %}
{% tab title="200 " %}

```
true
```

{% endtab %}
{% endtabs %}

## Retrive Mnemonic Phrase

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/mnemonicphrase`

#### Path Parameters

| Name     | Type   | Description     |
| -------- | ------ | --------------- |
| password | string | wallet password |

{% tabs %}
{% tab title="200 " %}

```
child brain left age apart couch napkin balcony lobster retreat situate retreat capital judge arch between cart puzzle truly note abuse violin spell fashion
```

{% endtab %}
{% endtabs %}

## Create Hex Transaction

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/createrawtransaction`

Create a hex transaction

#### Request Body

| Name     | Type   | Description                          |
| -------- | ------ | ------------------------------------ |
| password | string | wallet password                      |
| output   | array  | composed of address asset and amount |

{% tabs %}
{% tab title="200 Return the raw transaction" %}

```
0000000001014f49f18a0575e701661d95cd221feb4399dc25e6f8230d37c4e2860cbd248fb901020220afea2e549bc52e05673396161e175ba8b5d9afca75c658ec3c4739fc4feeca020000370220ecc94205df8142d81f469eb7c62db9b65f58a3e186250908ec855a32c5d1b466007e0001740ca8163200010162010360c63d3a8228f6ba18f10b487bc1e2526479db65b866cd408c9c6f2fe1e423cb2c0e82ef5cf046ad5c814e5404ad7fe2b7edfd76d0cb359a484ddda8e7ca9fd1356150ef28a1d2fc59115510fd38c5125f17f12b80661b168bf342e181df4810
```

{% endtab %}
{% endtabs %}

## Create raw transaction

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/rawtransaction/create`

Create an unsigned raw transaction

#### Path Parameters

| Name                                      | Type   | Description                          |
| ----------------------------------------- | ------ | ------------------------------------ |
| outputs<mark style="color:red;">\*</mark> | string | composed of address asset and amount |

{% tabs %}
{% tab title="200 " %}

```json
{
    "txHash": "87f899d158c39c15c73d97126982c735a24cca743a180c5555b104634c0d384c",
    "tx": "000000000101e003c9e673c3e386f40cd06c1d4e9f1ddebaa701393729a94a4ebb62e5e43e3301020220afea2e549bc52e05673396161e175ba8b5d9afca75c658ec3c4739fc4feeca02000037022072a6aa805930d89ba685c7919812209de5bdd9d3c4fb86903930286283db9ced007e000001bef88776000101340103cca577d0e3e738dcd5f90dd7bd76283365498e28455d6aa1e933c0ed5926768c116d2f3434272f323538272f30272f312f30"
}
```

{% endtab %}
{% endtabs %}

## Sign Raw Transaction

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/rawtransaction/sign`

Receive a raw transaction and sign it

#### Request Body

| Name                                       | Type   | Description                  |
| ------------------------------------------ | ------ | ---------------------------- |
| password<mark style="color:red;">\*</mark> | string | wallet password              |
| tx<mark style="color:red;">\*</mark>       | string | tx transaction in hex format |

{% tabs %}
{% tab title="200 " %}

```json
{
    "txHash": "87f899d158c39c15c73d97126982c735a24cca743a180c5555b104634c0d384c",
    "tx": "000000000101e003c9e673c3e386f40cd06c1d4e9f1ddebaa701393729a94a4ebb62e5e43e3301020220afea2e549bc52e05673396161e175ba8b5d9afca75c658ec3c4739fc4feeca02000037022072a6aa805930d89ba685c7919812209de5bdd9d3c4fb86903930286283db9ced007e000001bef887760001006401620103cca577d0e3e738dcd5f90dd7bd76283365498e28455d6aa1e933c0ed5926768c5f54068fc75add5135f9a52b965831650912b0ea40ca82d5697ebe4ae01bde1f18851a491fb477014ed29aa5a667da8ed669006806daa416d9492b23348c8de5"
}
```

{% endtab %}
{% endtabs %}

## Get Wallet Keys

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/keys`

Get imported public keys

#### Path Parameters

| Name     | Type   | Description     |
| -------- | ------ | --------------- |
| password | string | wallet password |

{% tabs %}
{% tab title="200 " %}

```
[
    {
        "publicKey": string,
        "path": "m/44'/258'/0'/1/0"
    }
]
```

{% endtab %}
{% endtabs %}

## Publish Raw Transaction

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/rawtransaction/publish`

Parse a transaction from raw, verify that is fully signed and then publish the transaction

#### Request Body

| Name                                 | Type   | Description             |
| ------------------------------------ | ------ | ----------------------- |
| tx<mark style="color:red;">\*</mark> | string | signed tx in hex format |

{% tabs %}
{% tab title="200 " %}

```
"87f899d158c39c15c73d97126982c735a24cca743a180c5555b104634c0d384c"
```

{% endtab %}
{% endtabs %}

## Import watchonly address

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/importwatchonlyaddress`

#### Request Body

| Name    | Type   | Description                 |
| ------- | ------ | --------------------------- |
| address | string | Address to add as watchonly |

{% tabs %}
{% tab title="200 " %}

```
added
```

{% endtab %}

{% tab title="400 " %}

```
Address already exist
```

{% endtab %}
{% endtabs %}

## Get new address

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/getnewaddress`

Get a new address

{% tabs %}
{% tab title="200 return a new address" %}

```
{
    "address": "tzn1qjcvncgt9lgs55983sz3a9ns8jhq3ukua747a7f7c87japw964usslwtgs6",
    "index": 0
}
```

{% endtab %}
{% endtabs %}

## Restore new address

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/restorenewaddresses`

#### Request Body

| Name                                  | Type   | Description |
| ------------------------------------- | ------ | ----------- |
| max<mark style="color:red;">\*</mark> | number |             |

{% tabs %}
{% tab title="200 " %}

```
```

{% endtab %}
{% endtabs %}

## Import Zen Public Key

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/importzenpublickey`

Import Zen Public Key

#### Request Body

| Name      | Type   | Description |
| --------- | ------ | ----------- |
| publicKey | string | public key  |

{% tabs %}
{% tab title="200 " %}

```
zenKey imported 
```

{% endtab %}
{% endtabs %}

## Execute Contract

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/contract/execute`

Run a smart contract with parameters

#### Request Body

| Name                                            | Type    | Description                                                                                                                                                                                                         |
| ----------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| sign<mark style="color:red;">\*</mark>          | string  | path                                                                                                                                                                                                                |
| password<mark style="color:red;">\*</mark>      | string  | wallet password                                                                                                                                                                                                     |
| returnAddress<mark style="color:red;">\*</mark> | boolean | <p>Execute the contract with some default arguments, such as:<br> - returnAddress - allows the contract to automatically send funds back to in case it needs to. <br>{<br>    "returnAddress" : true/false<br>}</p> |
| message                                         | string  | send the contract some data                                                                                                                                                                                         |
| contractId<mark style="color:red;">\*</mark>    | string  | The contract address                                                                                                                                                                                                |
| command<mark style="color:red;">\*</mark>       | string  | <p>Trigger one of the functions in the contract such as:<br>"buy" / "redeem"</p>                                                                                                                                    |
| spends<mark style="color:red;">\*</mark>        | array   | an array of outputs                                                                                                                                                                                                 |

{% tabs %}
{% tab title="200 " %}

```javascript
daed7567b6a1bbcc20b996625fd81384727daf100b794b75726f5d3dd0ce9b5c
```

{% endtab %}
{% endtabs %}

## Activate Contract

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/contract/activate`

This how you activate a contract

#### Request Body

| Name           | Type   | Description                                                                                                                                                                                         |
| -------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| rlimit         | string | zebra's rlimit for recording hints                                                                                                                                                                  |
| password       | string | wallet password                                                                                                                                                                                     |
| numberOfBlocks | number | The number of blocks you want to activate your contract for                                                                                                                                         |
| code           | string | <p>Send valid fstar code, for example:<br><code>let main \_ \_ \_ \_ \_ \_ \_ \_ = Zen.ResultT.failw "This contract does nothing"\nlet cf \_ \_ \_ \_ \_ \_ \_ = Zen.Cost.ret (1 <: nat)</code></p> |

{% tabs %}
{% tab title="200 Cake successfully retrieved." %}

```javascript
{
    "address": "ctzn1qqqqqqqym4kfe8y5qg5tazkgjwn4qpesj05x6mqsvd5auwmzkhhs444fnkvwxhahr",
    "contractId": "000000009bad939392804517d1591274ea00e6127d0dad820c6d3bc76c56bde15ad533b3"
}
```

{% endtab %}

{% tab title="400 Could not find a matching in the query." %}

```javascript
```

{% endtab %}
{% endtabs %}

## Extend Contract

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/contract/extend`

This is to extend a contract

#### Request Body

| Name                                             | Type   | Description                                            |
| ------------------------------------------------ | ------ | ------------------------------------------------------ |
| password<mark style="color:red;">\*</mark>       | string | wallet password                                        |
| numberOfBlocks<mark style="color:red;">\*</mark> | string | Number of block until when the contract will be active |
| address<mark style="color:red;">\*</mark>        | string | address of the contract                                |

{% tabs %}
{% tab title="200 " %}

```
{
    "address": "ctzn1qqqqqqq8gjuu8rz5q9f7jz72p3qh0arjctcstyzgp8ydux7hjt7kz7gkg4v5lec88",
    "contractId": "00000000e89738718a802a7d217941882efe8e585e20b20901391bc37af25fac2f22c8ab",
    "txHash": "725bc205c88944e2b0cbdd5150027511cf91c9d6c0f103a31e61a9c8c6589c5d",
    "numberOfBlocks": "10"
}
```

{% endtab %}
{% endtabs %}

## Execute CGP Contract

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/contract/cgp`

Execute the CGP contract at the payout block

#### Request Body

| Name     | Type   | Description     |
| -------- | ------ | --------------- |
| password | string | wallet password |

{% tabs %}
{% tab title="200 " %}

```
6bde92400f3ffb52980e22bb821f385b0bf5d710c8c65ff056287521b3b005be
```

{% endtab %}
{% endtabs %}


# Contracts

## Active Contract Set

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/contract/active`

Returns all currently active contracts. May not be accurate until the blockchain is fully synced.

{% tabs %}
{% tab title="200 An array of contract objects, including their actual F-Star code." %}

```javascript
[
    {
        "contractHash": "55be2edd1e537869cce832bd014aa1e3251aba651c5c3f38f70db86417faa9c4",
        "address": "tc1q2klzahg72duxnn8gx27szj4puvj34wn9r3wr7w8hpkuxg9l648zqhc76xa",
        "expire": 19375,
        "code": "(* NAME_START: Example Token :NAME_END *)\nopen Zen.Types\nopen Zen.Vector\nopen Zen.Base\nopen Zen.Cost\nopen Zen.Asset\nopen Zen.Data\n\nmodule ET = Zen.ErrorT\nmodule OT = Zen.OptionT\nmodule Tx = Zen.TxSkeleton\nmodule CR = Zen.ContractResult.NoMessage\n\nlet buy txSkeleton contractHash returnAddress =\n  let! tokens = Tx.getAvailableTokens zenAsset txSkeleton in\n\n  let! contractAsset = getDefault contractHash in\n\n  let! txSkeleton =\n    Tx.lockToContract zenAsset tokens contractHash txSkeleton\n    >>= Tx.mint tokens contractAsset\n    >>= Tx.lockToAddress contractAsset tokens returnAddress in\n\n  CR.ret txSkeleton\n\nlet redeem txSkeleton contractHash returnAddress wallet =\n  let! contractAsset = getDefault contractHash in\n  let! tokens = Tx.getAvailableTokens contractAsset txSkeleton in\n\n  let! txSkeleton =\n    Tx.destroy tokens contractAsset txSkeleton\n    >>= Tx.lockToAddress zenAsset tokens returnAddress\n    >>= Tx.fromWallet zenAsset tokens contractHash wallet in\n\n  CR.ofOption \"contract doesn't have enough zens to pay you\" txSkeleton\n\nval main: txSkeleton -> hash -> string -> option data -> wallet:wallet -> cost (result (txSkeleton ** option message))  (2 + 66 + (64 + (64 + (64 + 64 + (Zen.Wallet.size wallet * 128 + 192) + 0)) + 25) + 29)\nlet main txSkeleton contractHash command data wallet =\n  let! returnAddress = data >!> tryDict >?> tryFindLock \"returnAddress\" in\n\n  match returnAddress with\n  | Some returnAddress ->\n      if command = \"redeem\" then\n        redeem txSkeleton contractHash returnAddress wallet\n      else if command = \"\" || command = \"buy\" then\n        buy txSkeleton contractHash returnAddress\n        |> autoInc\n      else\n        ET.autoFailw \"unsupported command\"\n  | None ->\n      ET.autoFailw \"returnAddress is required\"\n\nval cf: txSkeleton -> string -> option data -> wallet -> cost nat 24\nlet cf _ _ _ wallet = ret  (2 + 66 + (64 + (64 + (64 + 64 + (Zen.Wallet.size wallet * 128 + 192) + 0)) + 25) + 29)"
    },
    {
        "contractHash": "55be2edd1e537869cce832bd014aa1e3251aba651c5c3f38f70db86417faa9c4",
        "address": "tc1q2klzahg72duxnn8gx27szj4puvj34wn9r3wr7w8hpkuxg9l648zqhc76xa",
        "expire": 19375,
        "code": "(* NAME_START: Example Token :NAME_END *)\nopen Zen.Types\nopen Zen.Vector\nopen Zen.Base\nopen Zen.Cost\nopen Zen.Asset\nopen Zen.Data\n\nmodule ET = Zen.ErrorT\nmodule OT = Zen.OptionT\nmodule Tx = Zen.TxSkeleton\nmodule CR = Zen.ContractResult.NoMessage\n\nlet buy txSkeleton contractHash returnAddress =\n  let! tokens = Tx.getAvailableTokens zenAsset txSkeleton in\n\n  let! contractAsset = getDefault contractHash in\n\n  let! txSkeleton =\n    Tx.lockToContract zenAsset tokens contractHash txSkeleton\n    >>= Tx.mint tokens contractAsset\n    >>= Tx.lockToAddress contractAsset tokens returnAddress in\n\n  CR.ret txSkeleton\n\nlet redeem txSkeleton contractHash returnAddress wallet =\n  let! contractAsset = getDefault contractHash in\n  let! tokens = Tx.getAvailableTokens contractAsset txSkeleton in\n\n  let! txSkeleton =\n    Tx.destroy tokens contractAsset txSkeleton\n    >>= Tx.lockToAddress zenAsset tokens returnAddress\n    >>= Tx.fromWallet zenAsset tokens contractHash wallet in\n\n  CR.ofOption \"contract doesn't have enough zens to pay you\" txSkeleton\n\nval main: txSkeleton -> hash -> string -> option data -> wallet:wallet -> cost (result (txSkeleton ** option message))  (2 + 66 + (64 + (64 + (64 + 64 + (Zen.Wallet.size wallet * 128 + 192) + 0)) + 25) + 29)\nlet main txSkeleton contractHash command data wallet =\n  let! returnAddress = data >!> tryDict >?> tryFindLock \"returnAddress\" in\n\n  match returnAddress with\n  | Some returnAddress ->\n      if command = \"redeem\" then\n        redeem txSkeleton contractHash returnAddress wallet\n      else if command = \"\" || command = \"buy\" then\n        buy txSkeleton contractHash returnAddress\n        |> autoInc\n      else\n        ET.autoFailw \"unsupported command\"\n  | None ->\n      ET.autoFailw \"returnAddress is required\"\n\nval cf: txSkeleton -> string -> option data -> wallet -> cost nat 24\nlet cf _ _ _ wallet = ret  (2 + 66 + (64 + (64 + (64 + 64 + (Zen.Wallet.size wallet * 128 + 192) + 0)) + 25) + 29)"
    }
]
```

{% endtab %}
{% endtabs %}

## Contract ID

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/contract/contractId`

Get a contract identifier from a contract address.

#### Path Parameters

| Name                                      | Type   | Description             |
| ----------------------------------------- | ------ | ----------------------- |
| address<mark style="color:red;">\*</mark> | string | address of the contract |

{% tabs %}
{% tab title="200 " %}

```json
00000000e89738718a802a7d217941882efe8e585e20b20901391bc37af25fac2f22c8ab
```

{% endtab %}

{% tab title="400 " %}

```
invalid address map
  [("address",
    "notExistingContractAddress")]
```

{% endtab %}
{% endtabs %}

## Activate Contract

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/contract/activate`

This how you activate a contract

#### Request Body

| Name           | Type   | Description                                                                                                                                                                                         |
| -------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| password       | string | wallet password                                                                                                                                                                                     |
| numberOfBlocks | number | The number of blocks you want to activate your contract for                                                                                                                                         |
| code           | string | <p>Send valid fstar code, for example:<br><code>let main \_ \_ \_ \_ \_ \_ \_ \_ = Zen.ResultT.failw "This contract does nothing"\nlet cf \_ \_ \_ \_ \_ \_ \_ = Zen.Cost.ret (1 <: nat)</code></p> |

{% tabs %}
{% tab title="200 Cake successfully retrieved." %}

```javascript
{
    "address": "ctzn1qqqqqqqym4kfe8y5qg5tazkgjwn4qpesj05x6mqsvd5auwmzkhhs444fnkvwxhahr",
    "contractId": "000000009bad939392804517d1591274ea00e6127d0dad820c6d3bc76c56bde15ad533b3"
}
```

{% endtab %}

{% tab title="400 Could not find a matching in the query." %}

```javascript
```

{% endtab %}
{% endtabs %}

## Execute Contract

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/contract/execute`

Run a smart contract with parameters

#### Request Body

| Name                                            | Type    | Description                                                                  |
| ----------------------------------------------- | ------- | ---------------------------------------------------------------------------- |
| options<mark style="color:red;">\*</mark>       | string  | add sign and return address here if needed                                   |
| sign<mark style="color:red;">\*</mark>          | string  | the derivation path for the execution of the contract                        |
| password<mark style="color:red;">\*</mark>      | string  | wallet password                                                              |
| returnAddress<mark style="color:red;">\*</mark> | boolean | allows the contract to automatically send funds back to in case it needs to. |
| messageBody<mark style="color:red;">\*</mark>   | string  | send the contract some data                                                  |
| address<mark style="color:red;">\*</mark>       | string  | The contract address                                                         |
| command<mark style="color:red;">\*</mark>       | string  | Trigger one of the functions in the contract                                 |
| spends<mark style="color:red;">\*</mark>        | array   | an array of outputs                                                          |

{% tabs %}
{% tab title="200 " %}

```javascript
5222c826d8d403636a75f48fd91d7d177be6efbf04ac266f3822322733e938ad
```

{% endtab %}
{% endtabs %}

## Extend Contract

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/contract/extend`

This is to extend a contract

#### Request Body

| Name                                             | Type   | Description                                            |
| ------------------------------------------------ | ------ | ------------------------------------------------------ |
| password<mark style="color:red;">\*</mark>       | string | wallet password                                        |
| numberOfBlocks<mark style="color:red;">\*</mark> | string | Number of block until when the contract will be active |
| contractId<mark style="color:red;">\*</mark>     | string | ID of the contract                                     |

{% tabs %}
{% tab title="200 " %}

```
5222c826d8d403636a75f48fd91d7d177be6efbf04ac266f3822322733e938ad
```

{% endtab %}
{% endtabs %}


# General

General Usage

## Network Connections

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/network/connections/count`

Returns the number of network connections

{% tabs %}
{% tab title="200 Some number" %}

```
5
```

{% endtab %}
{% endtabs %}

## Decode Address

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/address/decode`

Extract a public key hash or a contract identifier from an address

#### Path Parameters

| Name    | Type   | Description       |
| ------- | ------ | ----------------- |
| address | string | Address to decode |

{% tabs %}
{% tab title="200 " %}

```
{
     "pkHash": "some pk hash"
}
```

{% endtab %}

{% tab title="400 " %}

```
Address missing
```

{% endtab %}
{% endtabs %}


# Blockchain

## CGP

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/blockchain/cgp`

Get the current CGP status of the Blockchain

{% tabs %}
{% tab title="200 " %}

```
{
    "interval": 2391,
    "allocation": 90,
    "payout": {
        "recipient": "tzn1q7fnh47xftwr2zpxtpxepf022l9u5k0kusahactcn099vlumxy58s4kzzx6",
        "spendlist": [{
            "asset": "00",
            "amount": "12300000000"
        }]
    }
}
```

{% endtab %}
{% endtabs %}

## CGP History

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/blockchain/cgp/history`

Get the history of the CGP up to the previous interval

{% tabs %}
{% tab title="200 " %}

```
[...
{
    "interval": 2389,
    "allocation": 89,
    "payout": {}
}, {
    "interval": 2390,
    "allocation": 89,
    "payout": {}
}]
```

{% endtab %}
{% endtabs %}

## CGP Info

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/blockchain/contract/cgp`

Provide info on how to execute the cgp contract

{% tabs %}
{% tab title="200 " %}

```
{
    "raw": {
        "dict": [
            [
                "Outputs",
                {
                    "list": [
                        {
                            "list": [
                                {
                                    "lock": {
                                        "PK": {
                                            "hash": "f2677af8c95b86a104cb09b214bd4af9794b3edc876fdc2f13794acff366250f",
                                            "address": "tzn1q7fnh47xftwr2zpxtpxepf022l9u5k0kusahactcn099vlumxy58s4kzzx6"
                                        }
                                    }
                                },
                                {
                                    "list": [
                                        {
                                            "string": "000000000000000000000000000000000000000000000000000000000000000000000000"
                                        },
                                        {
                                            "u64": 12300000000
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            ]
        ]
    },
    "encoded": "0c01074f7574707574730d010d02080220f2677af8c95b86a104cb09b214bd4af9794b3edc876fdc2f13794acff366250f0d0206483030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030300500000002dd231b00000000",
    "cgpContract": "00000000eac6c58bed912ff310df9f6960e8ed5c28aac83b8a98964224bab1e06c779b93"
}
```

{% endtab %}
{% endtabs %}

## Total ZP

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/blockchain/totalzp`

Get the total minted ZP up to a precise block

#### Path Parameters

| Name        | Type   | Description |
| ----------- | ------ | ----------- |
| blockNumber | string |             |

{% tabs %}
{% tab title="200 " %}

```
236520
```

{% endtab %}
{% endtabs %}

## Block headers

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/blockchain/headers`

Returns a list of some information about each header on the main chain in JSON format

#### Query Parameters

| Name        | Type   | Description                                            |
| ----------- | ------ | ------------------------------------------------------ |
| blockNumber | string | start to take from blockNumber. Must be used with take |
| take        | string | take the first n blocks instead of all of the headers  |

{% tabs %}
{% tab title="200 " %}

```javascript
[{
        "hash": "hash"
        "timestamp": timestamp,
        "date": "19-07-21 11:16:17",
        "blockNumber": 1,
        "difficulty": "difficulty",
        "target": "target"
}...]
```

{% endtab %}
{% endtabs %}

## Blockchain Info

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/blockchain/info`

Returns information about the current status of the blockchain

{% tabs %}
{% tab title="200 " %}

```
{
    "chain": "testnet",
    "blocks": "blocks",
    "headers": "headers",
    "difficulty": "difficulty",
    "medianTime": "medianTime",
    "initialBlockDownload": false,
    "tip": "tip"
}
```

{% endtab %}
{% endtabs %}

## Block

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/blockchain/block`

Return the content of a block by providing either the block number or the hash of the block&#x20;

#### Path Parameters

| Name        | Type   | Description         |
| ----------- | ------ | ------------------- |
| blockNumber | string | block number wanted |
| hash        | string | hash of block       |

{% tabs %}
{% tab title="200 " %}

```json
{
    "hash": "0000000000134025e160d8bc9e2aa4679922577d6c4a19e913e794d9553fc7b1",
    "header": {
        "version": 0,
        "parent": "000000000005f82adc623950001be45869a55a9f6547988f691352bc3e569d21",
        "blockNumber": 173,
        "commitments": "a81f0356128748f3b32f75bb81b204efc326d29e200f8b02bcd30dcd0f2e8011",
        "timestamp": 1530385197246,
        "difficulty": 455897445,
        "nonce": [
            450089378218827185,
            -5391090228939172857
        ]
    },
    "transactions": {
        "6a8e563d53a1dcdf7eb8827a1643d7d9edf1af4665c50146f24d648578469a8d": {
            "version": 0,
            "inputs": [],
            "outputs": [
                {
                    "lock": {
                        "Coinbase": {
                            "blockNumber": 173,
                            "pkHash": "72c9f711659f19759967607f305da968f77f49e67ff23488d36fbd4df6a07b57",
                            "address": "zen1qwtylwyt9nuvhtxt8vplnqhdfdrmh7j0x0lerfzxnd775ma4q0dtscc2tjc"
                        }
                    },
                    "spend": {
                        "asset": "00",
                        "amount": "5000000000"
                    }
                }
            ],
            "witness": []
        },
        "89d60fdaab712639b38159b95503e20c1d93d71be547098233c89167de8ef033": {
            "version": 0,
            "inputs": [
                ...,
                {
                    "outpoint": {
                        "txHash": "a7934d6f8d88c120e2b65350889767ab1c2b075b0e4c596de4ef410e33a6d454",
                        "index": 0
                    }
                }
            ],
            "outputs": [
                {
                    "lock": {
                        "PK": {
                            "hash": "3ef74862aad449d4e509cdcdf6131f9f462ada5d0f999992855a6eba04ac3860",
                            "address": "zen1q8mm5sc4263yafegfehxlvyclnarz4kjap7veny59tfht5p9v8psqdzng5l"
                        }
                    },
                    "spend": {
                        "asset": "00",
                        "amount": "100000000000"
                    }
                }
            ],
            "witness": [
                ...,
                {
                    "PKWitness": {
                        "sigHash": "txHash",
                        "hash": "72c9f711659f19759967607f305da968f77f49e67ff23488d36fbd4df6a07b57",
                        "address": "zen1qwtylwyt9nuvhtxt8vplnqhdfdrmh7j0x0lerfzxnd775ma4q0dtscc2tjc",
                        "signature": "cdbf797eb5d4da7f4e4ab7c4ad02435d86a6548341ceab827ebf0354dbd734363ca0180df6dbf8623ec963bd054d07a7803e3f190655855c3ecded890cb23560"
                    }
                }
            ]
        }
    }
}
```

{% endtab %}

{% tab title="400: Bad Request " %}

```
hash or blockNumber are missing
```

{% endtab %}
{% endtabs %}

## Block Reward

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/blockchain/blockreward`

Return the reward at a given block

#### Path Parameters

| Name                                          | Type   | Description              |
| --------------------------------------------- | ------ | ------------------------ |
| blockNumber<mark style="color:red;">\*</mark> | string | Number of block to check |

{% tabs %}
{% tab title="200 " %}

```
5000000000

```

{% endtab %}

{% tab title="400: Bad Request " %}

```
blockNumber is missing
```

{% endtab %}
{% endtabs %}

## Get Transaction

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/blockchain/transaction`

Return the data of the provided transaction

#### Query Parameters

| Name                                   | Type   | Description                             |
| -------------------------------------- | ------ | --------------------------------------- |
| hash<mark style="color:red;">\*</mark> | string | Hash of a transaction                   |
| hex                                    | string | if true it returns the tx in hex format |

{% tabs %}
{% tab title="200 " %}

```json
{
    "tx": {
        "version": 0,
        "inputs": [
            {
                "outpoint": {
                    "txHash": "a880d71f4711d329d8de232a6ca762bd1a921f8bcc5cbbe5c951410271cd7487",
                    "index": 0
                }
            },
            {
                "outpoint": {
                    "txHash": "af95d752102168833c17d5b811fe8d29b95bc362c795cfe4c369651f18536947",
                    "index": 0
                }
            },
            {
                "outpoint": {
                    "txHash": "b1e957ca66a35496c2e1ab452dc214d727b14786734644b9bee935795ceb562f",
                    "index": 0
                }
            },
            {
                "outpoint": {
                    "txHash": "b8bc6169206fd11b8c49885e1f344d6ebbc57257b542b11cfc9ab99faefefce3",
                    "index": 0
                }
            },
            {
                "outpoint": {
                    "txHash": "be137110b99d6c73cd96b2b3b2b5d799140bd5d435e178aa7e50b692f4ac6571",
                    "index": 0
                }
            },
            {
                "outpoint": {
                    "txHash": "c0cbea76ee2051a5cfa173e483da630275f5594ea2223fbfc20359ea27d10e88",
                    "index": 0
                }
            },
            {
                "outpoint": {
                    "txHash": "d6c23a31aab8d523d53b0ae291a818b7c22382212b2d49c53008a65449e389cd",
                    "index": 0
                }
            },
            {
                "outpoint": {
                    "txHash": "d8326a8e17bc4f3a01310755b921d22f3d6828007e514368c3d6fb82f373008b",
                    "index": 0
                }
            },
            {
                "outpoint": {
                    "txHash": "e953b9b14e4620e12dbaeb3a12a99452ae936d86a0d89bcb7b2f995924adfff5",
                    "index": 0
                }
            },
            {
                "outpoint": {
                    "txHash": "efb796ba6d8ff18ff0ad5a70a1591b4ca30ffbf917bf9a44d6e7954092749d94",
                    "index": 0
                }
            }
        ],
        "outputs": [
            {
                "lock": {
                    "PK": {
                        "hash": "3ef74862aad449d4e509cdcdf6131f9f462ada5d0f999992855a6eba04ac3860",
                        "address": "zen1q8mm5sc4263yafegfehxlvyclnarz4kjap7veny59tfht5p9v8psqdzng5l"
                    }
                },
                "spend": {
                    "asset": "00",
                    "amount": "50000000000"
                }
            }
        ],
        "witness": [
            {
                "PKWitness": {
                    "sigHash": "txHash",
                    "hash": "72c9f711659f19759967607f305da968f77f49e67ff23488d36fbd4df6a07b57",
                    "address": "zen1qwtylwyt9nuvhtxt8vplnqhdfdrmh7j0x0lerfzxnd775ma4q0dtscc2tjc",
                    "signature": "8e8b0295b2f6407812d8de1853200ceab5c218f8626cb0d32b2fc655f25ce78b61b82f811ab7e602082d3ed21171c5c6a5f5ebd97d080114e27b443a292fc03e"
                }
            },
            {
                "PKWitness": {
                    "sigHash": "txHash",
                    "hash": "72c9f711659f19759967607f305da968f77f49e67ff23488d36fbd4df6a07b57",
                    "address": "zen1qwtylwyt9nuvhtxt8vplnqhdfdrmh7j0x0lerfzxnd775ma4q0dtscc2tjc",
                    "signature": "8e8b0295b2f6407812d8de1853200ceab5c218f8626cb0d32b2fc655f25ce78b61b82f811ab7e602082d3ed21171c5c6a5f5ebd97d080114e27b443a292fc03e"
                }
            },
            {
                "PKWitness": {
                    "sigHash": "txHash",
                    "hash": "72c9f711659f19759967607f305da968f77f49e67ff23488d36fbd4df6a07b57",
                    "address": "zen1qwtylwyt9nuvhtxt8vplnqhdfdrmh7j0x0lerfzxnd775ma4q0dtscc2tjc",
                    "signature": "8e8b0295b2f6407812d8de1853200ceab5c218f8626cb0d32b2fc655f25ce78b61b82f811ab7e602082d3ed21171c5c6a5f5ebd97d080114e27b443a292fc03e"
                }
            },
            {
                "PKWitness": {
                    "sigHash": "txHash",
                    "hash": "72c9f711659f19759967607f305da968f77f49e67ff23488d36fbd4df6a07b57",
                    "address": "zen1qwtylwyt9nuvhtxt8vplnqhdfdrmh7j0x0lerfzxnd775ma4q0dtscc2tjc",
                    "signature": "8e8b0295b2f6407812d8de1853200ceab5c218f8626cb0d32b2fc655f25ce78b61b82f811ab7e602082d3ed21171c5c6a5f5ebd97d080114e27b443a292fc03e"
                }
            },
            {
                "PKWitness": {
                    "sigHash": "txHash",
                    "hash": "72c9f711659f19759967607f305da968f77f49e67ff23488d36fbd4df6a07b57",
                    "address": "zen1qwtylwyt9nuvhtxt8vplnqhdfdrmh7j0x0lerfzxnd775ma4q0dtscc2tjc",
                    "signature": "8e8b0295b2f6407812d8de1853200ceab5c218f8626cb0d32b2fc655f25ce78b61b82f811ab7e602082d3ed21171c5c6a5f5ebd97d080114e27b443a292fc03e"
                }
            },
            {
                "PKWitness": {
                    "sigHash": "txHash",
                    "hash": "72c9f711659f19759967607f305da968f77f49e67ff23488d36fbd4df6a07b57",
                    "address": "zen1qwtylwyt9nuvhtxt8vplnqhdfdrmh7j0x0lerfzxnd775ma4q0dtscc2tjc",
                    "signature": "8e8b0295b2f6407812d8de1853200ceab5c218f8626cb0d32b2fc655f25ce78b61b82f811ab7e602082d3ed21171c5c6a5f5ebd97d080114e27b443a292fc03e"
                }
            },
            {
                "PKWitness": {
                    "sigHash": "txHash",
                    "hash": "72c9f711659f19759967607f305da968f77f49e67ff23488d36fbd4df6a07b57",
                    "address": "zen1qwtylwyt9nuvhtxt8vplnqhdfdrmh7j0x0lerfzxnd775ma4q0dtscc2tjc",
                    "signature": "8e8b0295b2f6407812d8de1853200ceab5c218f8626cb0d32b2fc655f25ce78b61b82f811ab7e602082d3ed21171c5c6a5f5ebd97d080114e27b443a292fc03e"
                }
            },
            {
                "PKWitness": {
                    "sigHash": "txHash",
                    "hash": "72c9f711659f19759967607f305da968f77f49e67ff23488d36fbd4df6a07b57",
                    "address": "zen1qwtylwyt9nuvhtxt8vplnqhdfdrmh7j0x0lerfzxnd775ma4q0dtscc2tjc",
                    "signature": "8e8b0295b2f6407812d8de1853200ceab5c218f8626cb0d32b2fc655f25ce78b61b82f811ab7e602082d3ed21171c5c6a5f5ebd97d080114e27b443a292fc03e"
                }
            },
            {
                "PKWitness": {
                    "sigHash": "txHash",
                    "hash": "72c9f711659f19759967607f305da968f77f49e67ff23488d36fbd4df6a07b57",
                    "address": "zen1qwtylwyt9nuvhtxt8vplnqhdfdrmh7j0x0lerfzxnd775ma4q0dtscc2tjc",
                    "signature": "8e8b0295b2f6407812d8de1853200ceab5c218f8626cb0d32b2fc655f25ce78b61b82f811ab7e602082d3ed21171c5c6a5f5ebd97d080114e27b443a292fc03e"
                }
            },
            {
                "PKWitness": {
                    "sigHash": "txHash",
                    "hash": "72c9f711659f19759967607f305da968f77f49e67ff23488d36fbd4df6a07b57",
                    "address": "zen1qwtylwyt9nuvhtxt8vplnqhdfdrmh7j0x0lerfzxnd775ma4q0dtscc2tjc",
                    "signature": "8e8b0295b2f6407812d8de1853200ceab5c218f8626cb0d32b2fc655f25ce78b61b82f811ab7e602082d3ed21171c5c6a5f5ebd97d080114e27b443a292fc03e"
                }
            }
        ]
    },
    "confirmations": 640787
}
```

{% endtab %}

{% tab title="400: Bad Request " %}

```
transaction not found
```

{% endtab %}
{% endtabs %}

## Publish Block

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/blockchain/publishblock`

Publish a block only provide block in hex format or header and body

#### Request Body

| Name   | Type   | Description   |
| ------ | ------ | ------------- |
| body   | string | in hex format |
| header | string | in hex format |
| block  | string | in hex format |

{% tabs %}
{% tab title="200 " %}

```
000000000008bf918c4672a4b5b7a4928cf180adefab696947de56c948240e47
```

{% endtab %}

{% tab title="400 error" %}

```
proof of work failed
```

{% endtab %}
{% endtabs %}

## Submit Header

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/blockchain/submitheader`

Submit hex formatted header to add the block

#### Request Body

| Name   | Type   | Description          |
| ------ | ------ | -------------------- |
| header | string | The header to submit |

{% tabs %}
{% tab title="200 " %}

```
cb746bfdbc472602064dbc04e66326a8edf11a3c64d08ddfa90257e86e866b0f
```

{% endtab %}
{% endtabs %}

## Block Template

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/blockchain/blocktemplate`

Request a block template to add on top the mempool transaction

#### Path Parameters

| Name    | Type   | Description            |
| ------- | ------ | ---------------------- |
| address | string | Miner coinbase address |

{% tabs %}
{% tab title="200 " %}

```json
{
    "header": "000000010000000004357e167370845a22b741b01cfc392a3d0cafa5736042ea13910a8c000085c82deddef70ebc9a16f150047ad0fe9118b46b6099c2b89c4bef0d09a1e620c575000001884358696e1c0582dd00000000000000000000000000000000",
    "body": "039bf2e442f34d15fd09d2a6a6cf97e9d65758a39a4a1cba8b76102e15e81a7ec334e357f5efa4b6cdaf25a1c51f4ab17769ab29594d318e45b6fa9281f8c60516f7e92b9cb5a9e696a0d7cfc1f00e974ce2c1693b63a5e647a00f545dbd996818010000000000010624000085c8f2677af8c95b86a104cb09b214bd4af9794b3edc876fdc2f13794acff366250f007e0000012a0603760000",
    "target": "000000000582dd00000000000000000000000000000000000000000000000000",
    "parent": "0000000004357e167370845a22b741b01cfc392a3d0cafa5736042ea13910a8c",
    "blockNumber": 34248
}
```

{% endtab %}
{% endtabs %}

## Publish Transaction

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/blockchain/publishtransaction`

Publish an hex encoded transaction into the mempool&#x20;

#### Request Body

| Name                                 | Type   | Description               |
| ------------------------------------ | ------ | ------------------------- |
| tx<mark style="color:red;">\*</mark> | string | transaction in hex format |

{% tabs %}
{% tab title="200 " %}

```
e4592f72c0201345b750fde240309224a7964e2b516440e2bfa0f62d3bc59bb5
```

{% endtab %}

{% tab title="400 " %}

```
invalid transaction
```

{% endtab %}
{% endtabs %}

## Execute Contract

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/blockchain/contract/execute`

Execute a contract by given different data&#x20;

#### Request Body

| Name         | Type   | Description                      |
| ------------ | ------ | -------------------------------- |
| command      | string | command provided to the contract |
| messageBody  | string | message body in hex format       |
| otion.sender | string | bip39 path                       |
| tx           | string | Tx in hex format                 |
| address      | string | Contract Address                 |

{% tabs %}
{% tab title="200 tx in hex format" %}

```
123456789abcdef 
```

{% endtab %}
{% endtabs %}


# AddressDB

## Resync

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/addressdb/resync`

{% tabs %}
{% tab title="200 " %}

```
```

{% endtab %}
{% endtabs %}

## Adressess Balance

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/addressdb/balance`

Given a list of addresses return the balance per asset of those addresses

#### Path Parameters

| Name       | Type  | Description |
| ---------- | ----- | ----------- |
| addressess | array | addressess  |

{% tabs %}
{% tab title="200 " %}

```
```

{% endtab %}
{% endtabs %}

## Addressess Outputs

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/addressdb/outputs`

Given a list of addresses and a mode return a list of outpoint and spend per address

#### Request Body

| Name       | Type   | Description        |
| ---------- | ------ | ------------------ |
| mode       | string | all or unspentOnly |
| addressess | array  | address list       |

{% tabs %}
{% tab title="200 " %}

```
[
   {
        outpoint: Outpoint,
        spend: {
            asset: string,
            amount: number
        },
        lock: {
            PK?: {
                hash: string,
                address: string
            },
            Coinbase?: {
                blockNumber: number,
                pkHash: string,
                address: string
            },/// all the other lock as well
        }
    }

]
```

{% endtab %}
{% endtabs %}

## Addressess Transactions

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/addressdb/transactions`

Given a list of addresses return the transaction count with the skip and take methods

#### Request Body

| Name       | Type   | Description        |
| ---------- | ------ | ------------------ |
| take       | string | used in pagination |
| skip       | string | used in pagination |
| addressess | array  | address list       |

{% tabs %}
{% tab title="200 " %}

```
```

{% endtab %}
{% endtabs %}

## Addressess Transaction Count

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/addressdb/transactioncount`

Given a list of addresses return the transaction count

#### Request Body

| Name       | Type  | Description  |
| ---------- | ----- | ------------ |
| addressess | array | address list |

{% tabs %}
{% tab title="200 " %}

```
```

{% endtab %}
{% endtabs %}

## Contract History

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/contract/history`

Given a contractID return the history of the execution of that contract

#### Request Body

| Name       | Type   | Description        |
| ---------- | ------ | ------------------ |
| take       | string | used in pagination |
| skip       | string | used in pagination |
| contractId | string | contract ID        |

{% tabs %}
{% tab title="200 " %}

```
```

{% endtab %}
{% endtabs %}

## Contract Info

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/contract/info`

This is used to compute the hints and queries for the contract activation in ZenJs.

#### Request Body

| Name   | Type   | Description                                                                                                                                                       |
| ------ | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| rlimit | string | Zebra's rlimit for recording hints                                                                                                                                |
| code   | string | Send valid fstar code, for example: `let main _ _ _ _ _ _ _ _ = Zen.ResultT.failw \"This contract does nothing\"\nlet cf _ _ _ _ _ _ _ = Zen.Cost.ret (1 <: nat)` |

{% tabs %}
{% tab title="200 " %}

```
{
    "contractId": "00000000e126b3c70693a7661109d7c7350128f48bf59a7a79ca39a65cf0fc78a9ca7436",
    "address": "ctzn1qqqqqqq8py6euwp5n5anpzzwhcu6sz285306e57neegu6vh8sl3u2njn5xc4qap9y",
    "hints": "[\"04f68069bd73872a976a71eb765538d9\",[[\"Ze126b3c70693a7661109d7c7350128f48bf59a7a79ca39a65cf0fc78a9ca7436.mainFunction\",1,2,1,[\"@MaxIFuel_assumption\",\"@query\",\"Prims_pretyping_ae567c2fb75be05905677af440075565\",\"Prims_pretyping_ce036b6b736ef4e0bc3a9ff132a12aed\",\"Zen.Types.Main_pretyping_5bd8c5a85db081605d2f2b0ef5761cbb\",\"Zen.Types.Main_pretyping_8d0bd552ce32ff91a3c9f4725122e3be\",\"data_typing_intro_Zen.Types.Main.Anonymous@tok\",\"equation_Prims.nat\",\"equation_Ze126b3c70693a7661109d7c7350128f48bf59a7a79ca39a65cf0fc78a9ca7436.cf\",\"equation_Zen.Types.Main.maxCost\",\"fuel_guarded_inversion_Zen.Types.Main.context\",\"function_token_typing_Prims.nat\",\"int_typing\",\"lemma_Zen.Cost.Realized.force_inc\",\"lemma_Zen.Cost.Realized.force_ret\",\"primitive_Prims.op_Addition\",\"proj_equation_Zen.Types.Main.CostFunc_f\",\"proj_equation_Zen.Types.Main.CostFunc_n\",\"projection_inverse_BoxInt_proj_0\",\"projection_inverse_Zen.Types.Main.CostFunc_f\",\"projection_inverse_Zen.Types.Main.CostFunc_n\",\"refinement_interpretation_Prims_Tm_refine_ba523126f67e00e7cd55f0b92f16681d\",\"refinement_interpretation_Zen.Types.Main_Tm_refine_8ae4abcfc6bc8d4903b7e1f40e070ec2\",\"string_inversion\",\"token_correspondence_Ze126b3c70693a7661109d7c7350128f48bf59a7a79ca39a65cf0fc78a9ca7436.cf\",\"token_correspondence_Zen.Types.Main.__proj__CostFunc__item__f\",\"typing_Zen.Cost.Realized.ret\"],0,\"17bfc1c24d1308a3cb3612020f013590\"]]]\n",
    "queries": 27,
    "rlimit": 2723280
}
```

{% endtab %}
{% endtabs %}


# Deploy

### Via Systemd

{% content-ref url="/pages/-MQv9IMj9IqmkxpTuRkX" %}
[Systemd](/apps/headless/deploy/systemd)
{% endcontent-ref %}

### Via Docker

{% content-ref url="/pages/-MQv8q1ilab0p53G39ld" %}
[Docker](/apps/headless/deploy/docker)
{% endcontent-ref %}

## Via Shell Script


# Systemd

## Install a node via NPM

{% content-ref url="/pages/-L9iwr2pZXahP-6FtOde" %}
[Full Node NPM Package](/apps/headless/headless)
{% endcontent-ref %}

## Install Service

Create a new file in `/etc/systemd/system/zen-node.service` with the following:

```
[Unit]
Description=Zen Node
After=network.target

[Service]
Type=simple
WorkingDirectory=/usr/lib/node_modules/@zen/zen-node/Release/
ExecStart=/usr/bin/mono /usr/lib/node_modules/@zen/zen-node/Release/zen-node.exe
Restart=on-failure

[Install]
WantedBy=multi-user.target

```

## Enable and Run Service:

1. Enable by writing on the terminal:\
   `systemctl enable zen-node.service`
2. Run the service by writing:\
   `systemctl start zen-node.service`

## View Service Logs

1. Run on the terminal:\
   `journalctl -f -u zen-node.service`


# Shell script

To fast install of a full node use the following

## Normal Node

```shell
#!/bin/bash

# install mono-devel and other libs needed to get ZEN NODE up and running.
install_mono(){

  echo "Adding Mono-devel Repo"
  sudo apt install gnupg ca-certificates -y
  sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
  echo "deb https://download.mono-project.com/repo/ubuntu stable-bionic main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list

  sudo apt update
  sudo apt upgrade -y

  # install mono-devel, Lighting Memory-Mapped Database lib and unzip
  sudo apt install mono-devel -y
  sudo apt install liblmdb0 -y
  sudo apt install unzip -y

}


#---------------------------------------------------------------------------------------
#ENTRY POINT

# check for mono-devel.
which mono || install_mono  # only install and upgrade the system if mono-devel is missing


# NVM Sections
echo "---------------------------------------------------"
echo "NVM SETUP."
sudo echo ' '

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"

nvm install --lts
npm config set @zen:registry https://www.myget.org/F/zenprotocol/npm/
npm install @zen/zen-node -g


# set data path location for the database
DATAPATH="$HOME/.config/zen-node"

echo "---------------------------------------------------"
echo "Generating Zen-Node Service File..."

# generate the service file then save it appropriately
printf "[Unit]
Description=Zen Node
After=network.target

[Service]
Type=simple
WorkingDirectory=$HOME/.nvm/versions/node/$(node --version)/lib/node_modules/@zen/zen-node/Release/
ExecStart=/usr/bin/mono $HOME/.nvm/versions/node/$(node --version)/lib/node_modules/@zen/zen-node/Release/zen-node.exe --data-path "$DATAPATH" --api "*:11567"
Restart=on-failure

[Install]
WantedBy=multi-user.target
" | sudo tee /etc/systemd/system/zen-node.service


# check for the blockchain DB, if present, continue.
# if absent, check for the zipped version and extract it.
# if no zipped version present, download the one hosted.
if [[ ! -s $DATAPATH ]] ; then
  echo "---------------------------------------------------"
  if [[ ! -s "zen-node.zip" ]] ; then
    echo "Downloading Blockchain..."
    # download zen-node.zip from s3
    wget https://node-backups.s3-eu-west-1.amazonaws.com/zen-node.zip
  fi

  echo "Unziping The BlockchainDB in $DATAPATH..."
  unzip zen-node.zip -d "$HOME/.config"

fi

echo "---------------------------------------------------"
echo "Starting ZEN NODE...."
sudo systemctl enable zen-node.service
sudo systemctl start zen-node.service
sudo journalctl -f -u zen-node.service
```

## Address Node (Explorer and Exchange)

```shell
#!/bin/bash

# install mono-devel and other libs needed to get ZEN NODE up and running.
install_mono(){

  echo "Adding Mono-devel Repo"
  sudo apt install gnupg ca-certificates -y
  sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
  echo "deb https://download.mono-project.com/repo/ubuntu stable-bionic main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list

  sudo apt update
  sudo apt upgrade -y

  # install mono-devel, Lighting Memory-Mapped Database lib and unzip
  sudo apt install mono-devel -y
  sudo apt install liblmdb0 -y
  sudo apt install unzip -y

}


#---------------------------------------------------------------------------------------
#ENTRY POINT

# check for mono-devel.
which mono || install_mono  # only install and upgrade the system if mono-devel is missing


# NVM Sections
echo "---------------------------------------------------"
echo "NVM SETUP."
sudo echo ' '

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"

nvm install --lts
npm config set @zen:registry https://www.myget.org/F/zenprotocol/npm/
npm install @zen/zen-node -g


# set data path location for the database
DATAPATH="$HOME/.config/zen-node"

echo "---------------------------------------------------"
echo "Generating Zen-Node Service File..."

# generate the service file then save it appropriately
printf "[Unit]
Description=Zen Node
After=network.target

[Service]
Type=simple
WorkingDirectory=$HOME/.nvm/versions/node/$(node --version)/lib/node_modules/@zen/zen-node/Release/
ExecStart=/usr/bin/mono $HOME/.nvm/versions/node/$(node --version)/lib/node_modules/@zen/zen-node/Release/zen-node.exe --data-path "$DATAPATH" --api "*:11567" --addressdb
Restart=on-failure

[Install]
WantedBy=multi-user.target
" | sudo tee /etc/systemd/system/zen-node.service


# check for the blockchain DB, if present, continue.
# if absent, check for the zipped version and extract it.
# if no zipped version present, download the one hosted.
if [[ ! -s $DATAPATH ]] ; then
  echo "---------------------------------------------------"
  if [[ ! -s "zen-node.zip" ]] ; then
    echo "Downloading Blockchain..."
    # download zen-node.zip from s3
    wget https://node-backups.s3-eu-west-1.amazonaws.com/zen-node-addressdb.zip
  fi

  echo "Unziping The BlockchainDB in $DATAPATH..."
  unzip zen-node.zip -d "$HOME/.config"

fi

echo "---------------------------------------------------"
echo "Starting ZEN NODE...."
sudo systemctl enable zen-node.service
sudo systemctl start zen-node.service
sudo journalctl -f -u zen-node.service
```


# Docker

#### Docker File

```
FROM mono

RUN curl -sL https://deb.nodesource.com/setup_12.x | bash -
RUN apt-get update && apt-get install -y nodejs liblmdb0 unzip wget libgomp1
RUN /usr/bin/npm i -g npm

RUN /usr/bin/npm config set @zen:registry https://www.myget.org/F/zenprotocol/npm/
RUN /usr/bin/npm install @zen/zen-node@latest -g

CMD ["zen-node"]
```


# Technical Model

## Actor Model

The Actor model is a programming paradigm that enables concurrent and distributed systems to be designed and implemented more easily. In the Actor model, computation is modeled as a collection of independent actors that communicate with each other by sending messages.

An actor is a unit of computation that can receive messages, perform computations, and send messages to other actors. Each actor has its own internal state, which can be accessed only by the actor itself. Actors can create new actors, and each actor has a unique address or identifier that other actors can use to send messages to it.

In the Actor model, message passing is the primary means of comm

unication between actors. When an actor receives a message, it can perform some computation and then send messages to other actors, including the original sender. Actors can also send messages to themselves, which can be used for scheduling future work or for implementing timeouts.

One of the main benefits of the Actor model is that it simplifies the design of concurrent and distributed systems. Because each actor has its own internal state, there is no need for locks or other synchronization mechanisms to coordinate access to shared resources. This can make it easier to reason about the behavior of a system and to avoid race conditions and deadlocks.

Another advantage of the Actor model is that it can be used to build highly scalable systems. Because actors are independent and communicate only by message passing, it is easy to add or remove actors as needed to handle changes in the load on the system.

## Service Bus and Publisher - NetMQ

NetMQ is a software library that provides tools for enabling efficient and reliable communication between applications over computer networks. It offers various messaging patterns, such as request-reply, publish-subscribe, and push-pull, among others. With NetMQ, developers can implement messaging functionality in their applications, allowing them to communicate with other applications or services seamlessly.

A service bus is an architectural pattern that provides a central messaging system for different applications or services to communicate with each other. The service bus acts as an intermediary, routing messages between applications and providing useful features like message queuing, transformation, and routing. This allows for loosely coupled communication between applications and services, making it easier to maintain and scale distributed systems.

In the context of messaging patterns like publish-subscribe, a publisher is an application or component that sends messages to a messaging system or service bus. The publisher is responsible for publishing messages to a specific topic or channel, which subscribers can then consume. This allows for broadcasting messages to multiple recipients in a scalable and efficient way.

In summary, NetMQ, service bus, and publisher are all tools and patterns that help facilitate communication between applications or services in a distributed system. They enable developers to build scalable and reliable systems that can handle complex messaging scenarios.


# AddressDB

The AddressDB is a component of the Zen Protocol node, it connects to the node service bus to store the blockchain data so that it can be retrieved faster . The addressDB can be used by everyone who downloads the node installer. It is used to monitor all UTXOs and blockchain contract executions. It can retrieve informations like balance, outputs, transactions, contract history, and a lot more. <br>

A list of the addressDB API's can be found here :&#x20;

{% content-ref url="/pages/-MRbDz5oIcA3GJ7NFPC9" %}
[AddressDB](/apps/headless/api/addressdb)
{% endcontent-ref %}


# Wallet

The Zen Protocol Wallet is designed to give users complete control over their financial assets by making ZP easy to use, creating and interacting with smart contracts and voting for the next upgrades.

{% hint style="info" %}

#### Please note that the use of the software is subject to the terms of its [licence](https://github.com/zenprotocol/zenprotocol/blob/master/LICENSE.md) and [Authorized Protocol](https://github.com/zenprotocol/zenprotocol/blob/master/AUTHORIZED_PROTOCOL.pdf).&#x20;

{% endhint %}

## Desktop Wallet

Using the Desktop Wallet is the most secure way to validate the network, make transaction and run smart contracts.

{% content-ref url="/pages/-L9oPpPwW22sD7V7ZwHm" %}
[Desktop Wallet](/apps/wallet/preparation)
{% endcontent-ref %}

## Desktop Wallet Full Node

This mode allow to connect to a local node using the addressdb module.

```
zen-node --connectwallet
```

Then in the Desktop wallet under Settings -> Node Connectivity you can choose one of the localhost node.

## Web Wallet

{% content-ref url="/pages/-LOCyRQaX4LV-cV10Tjw" %}
[Web Wallet](/apps/wallet/web-wallet)
{% endcontent-ref %}

## Difference between the wallet versions

|                                                                      | Web Wallet                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | Desktop Wallet                                                                                                                                                                                                                                 | Chrome Desktop App (PWA)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Store Seed**                                                       | Encrypted using a password of your choice and stored in local storage                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | Encrypted using a password of your choice and stored in local storage                                                                                                                                                                          | Encrypted using a password of your choice and stored in local storage                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| <p><strong>Blockchain</strong></p><p><strong>Validation</strong></p> | Uses a "trusted" remote node to sync with the blockchain and validate the consensus rules, and relays signed transactions on its behalf                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | <p>Uses a "trusted" remote node to sync with the blockchain and validate the consensus rules, and relays signed transactions on its behalf.</p><p>This is the only way for you to connect to a local node running in the localhost network</p> | Uses a "trusted" remote node to sync with the blockchain and validate the consensus rules, and relays signed transactions on its behalf                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| **Access**                                                           | <p>Is via a web browser, which can be compromised in multiple ways such as</p><p>\* having a <a href="https://arstechnica.com/information-technology/2018/05/malicious-chrome-extensions-infect-more-than-100000-users-again/">malicious Chrome Extension</a></p><p>\* If the server that is serving the client gets hacked, the hacker could deliver a version of the website that steals your seed.</p><p>\* <a href="https://en.wikipedia.org/wiki/Phishing">Phishing</a> - someone could create a website with a domain that looks very similar to the real official wallet domain and serve a malicious version of the wallet.</p> | A desktop application to your computer once from a trusted source.                                                                                                                                                                             | <p>A <strong>PWA</strong> is a web application that can be “installed” on your system, which can be compromised in multiple ways such as</p><p>\* having a <a href="https://arstechnica.com/information-technology/2018/05/malicious-chrome-extensions-infect-more-than-100000-users-again/">malicious Chrome Extension</a></p><p>\* If the server that is serving the client gets hacked, the hacker could deliver a version of the website that steals your seed.</p><p>\* <a href="https://en.wikipedia.org/wiki/Phishing">Phishing</a> - someone could create a website with a domain that looks very similar to the real official wallet domain and serve a malicious version of the wallet.</p> |


# Desktop Wallet

Here you can find the installation guide for the different Operating System and its User Guide.

## Installation

### Desktop installers .exe (windows) / .dmg (mac) / appImage /debian / tar

{% content-ref url="/pages/-MTl3zmmDGkY8y6FmBgP" %}
[Installers](/apps/wallet/preparation/installers)
{% endcontent-ref %}

## User Guide

{% content-ref url="/pages/-MRFP3dUgmQd2m8sM5Jy" %}
[Wallet User Guide](/apps/wallet/wallet-structure)
{% endcontent-ref %}


# Installers

## Installers Links

### Mac OS

After installing drag the Zen Wallet icon to the applications folder, add login credentials for authentication if needed.\
Right click and choose *Open* and confirm by clicking the *Open* button

* [Mac](https://zen-distributables.s3.eu-west-1.amazonaws.com/Zen+Wallet-0.2.2.dmg)
* [Mac SHA256](https://zen-distributables.s3.eu-west-1.amazonaws.com/Zen+Wallet-0.2.2.dmg_SHA256)&#x20;

  \[8e46ffa3511dd65cf6afa1088c336bb1da28249aa97c900483ad73b4620e9a32]

### Windows <a href="#windows" id="windows"></a>

Your browser may warn that the download is not commonly downloaded. Click "keep" to download it anyway.\
After running the installer. You'll need to click the `More Info` button and click `Run anyway`

* [Windows](https://zen-distributables.s3.eu-west-1.amazonaws.com/Zen+Wallet+Setup+0.2.2.exe)
* [Windows SHA256](https://zen-distributables.s3.eu-west-1.amazonaws.com/Zen+Wallet+Setup+0.2.2.exe_SHA256) \[834a047e84003f1c2035b342a4872cc96d9f2359277e51ce3ffdf3125efa1057]

### AppImage <a href="#linux" id="linux"></a>

* [AppImage](https://zen-distributables.s3.eu-west-1.amazonaws.com/Zen+Wallet-0.2.2.AppImage)
* [AppImage SHA256 ](https://zen-distributables.s3.eu-west-1.amazonaws.com/Zen+Wallet-0.2.2.AppImage_SHA256)\[133b03b1a038c972cf0b5ca6ca2ec8e1d6dca4ea6f9213ef1300395bb8e2c0b9]

### Debian <a href="#linux" id="linux"></a>

* [Deb 64 ](https://zen-distributables.s3.eu-west-1.amazonaws.com/zenwallet-desktop_0.2.2_amd64.deb)
* [Deb 64 SHA256 ](https://zen-distributables.s3.eu-west-1.amazonaws.com/zenwallet-desktop_0.2.2_amd64.deb_SHA256)\[e0f720d4eb23a563d41b49bfe59cbc2930a67391fa0a2d562a9a1fb2f4d2abd2]

### Linux Tar <a href="#linux" id="linux"></a>

* [Linux Tar](https://zen-distributables.s3.eu-west-1.amazonaws.com/zenwallet-desktop-0.2.2.tar.gz)
* [Linux Tar SHA256 ](https://zen-distributables.s3.eu-west-1.amazonaws.com/zenwallet-desktop-0.2.2.tar.gz_SHA256)\[05fa735b8e9d16d6cc6bd2fe342996324d8ce80e75a6e04dfac346861130febe]

## Verify Installer

{% hint style="info" %}
Check the downloaded file using the SHA256 algorithm:

```
# Mac terminal
shasum -a 256 [file-to-hash]

# Windows command prompt
certutil -hashfile [file-to-hash] sha256

# Linux shell
sha256sum [file-to-hash]
```

{% endhint %}


# Web Wallet

This option is easier to use and does not require time to sync up with the network or install any prerequisites.

## Accessing the Web Wallet - <https://wallet.zp.io>

{% hint style="warning" %}
We advise you to bookmark the wallet url (<https://wallet.zp.io>) for an easier and safer access
{% endhint %}

{% hint style="danger" %}
**Security Notice**

Web wallets are inherently less secure than other forms of cryptocurrency wallets. You should not use this web wallet to secure or control any tokens or resources that you cannot afford to lose. The major weakness in any web wallet is that its code is delivered in the form of a web page, meaning that if the server is compromised, the attacker can cause it to deliver phishing code to the user, stealing private key data and using it to steal funds. An additional attack vector is the injection of malicious code into a compromised javascript dependency, for example MobX.js. Please use the [Desktop Wallet](/apps/wallet/deprecated-desktop-wallet/installers) if you want a higher level of security. Steps for using the web wallet as securely as possible:
{% endhint %}

Security Tips:

1. Only use a computer that you are sure is not infected with a virus. Viruses such as [keystroke loggers](https://en.wikipedia.org/wiki/Keystroke_logging) can steal your 24 word mnemonic phrase while you are typing it.
2. You should use a web browser with as little as possible extensions or none at all - and only if you completely trust those extensions. Preferably you should use a browser without any extensions.
3. For Chrome users use the [PWA](https://support.google.com/chrome/answer/9658361) version for more efficency and phishing security.

{% content-ref url="/pages/-LODjJdEGAnEwXy55zG1" %}
[Run Locally](/apps/wallet/web-wallet/run-locally)
{% endcontent-ref %}

{% content-ref url="/pages/-MRFP3dUgmQd2m8sM5Jy" %}
[Wallet User Guide](/apps/wallet/wallet-structure)
{% endcontent-ref %}


# Run Locally

By running the web wallet locally you can remove the risk of phishing attacks.

### [PWA](https://support.google.com/chrome/answer/9658361)

### Install a PWA

1. On your computer, open Chrome.
2. Go to <https://wallet.zp.io>
3. At the top right of the address bar, click Install ![Add](https://lh3.googleusercontent.com/A1rx226Em2QI88gjHcLgWuAoFpxEtq2TF4OUQi4Ti_9xoX044b7hTFxp6wbjTZEefToK=w36-h36).
4. Follow the onscreen instructions to install the PWA.

### &#x20;Desktop Wallet <a href="#desktop-wallet" id="desktop-wallet"></a>

{% content-ref url="/pages/-L9oPpPwW22sD7V7ZwHm" %}
[Desktop Wallet](/apps/wallet/preparation)
{% endcontent-ref %}


# Wallet User Guide

Here you can find a full overview of all features available on the Zen Protocol wallet.

{% content-ref url="/pages/-MRtNFcKq2CaNhXXnlRs" %}
[Connect a Wallet](/apps/wallet/wallet-structure/onboarding)
{% endcontent-ref %}

{% content-ref url="/pages/-MRtNaD7vmO1J2eaPh9k" %}
[My Wallet](/apps/wallet/wallet-structure/my-wallet)
{% endcontent-ref %}

{% content-ref url="/pages/-MRtN\_mjmvUFxlYNBNzx" %}
[Contracts](/apps/wallet/wallet-structure/contracts)
{% endcontent-ref %}

{% content-ref url="/pages/-MRtNvpxuqdzPFvhJjgO" %}
[Voting](/apps/wallet/wallet-structure/voting)
{% endcontent-ref %}

{% content-ref url="/pages/-MRtNy9Zx0TrlBrH9Z0B" %}
[Settings](/apps/wallet/wallet-structure/settings)
{% endcontent-ref %}


# Connect a Wallet

## Multi Wallet

WIth the new released wallet, multi accounts can be imported in a secure and organized way. A name can be give for future references and a passphrase can be added to enhance the security of the wallet.&#x20;

What is Passphrase

What is Name

How this interacts together

{% content-ref url="/pages/-MRtO5ZduTSZFUE9Mtxj" %}
[Create a Wallet](/apps/wallet/wallet-structure/onboarding/create-a-wallet)
{% endcontent-ref %}

{% content-ref url="/pages/-MRtO6KpIKmbOK4CYHp-" %}
[Import a Wallet](/apps/wallet/wallet-structure/onboarding/import-a-wallet)
{% endcontent-ref %}

{% content-ref url="/pages/Rs4aUacYl1yafBOHVLHq" %}
[Watch Mode](/apps/wallet/wallet-structure/onboarding/watch-mode)
{% endcontent-ref %}


# Create a Wallet

When creating a new wallet, a 24 word mnemonic phrase is generated for you. This is the most important secret you MUST save and SECURE in order to access all of your funds.

{% hint style="warning" %}
**Security Notice**

* Zen Protocol does not offer support to recover or reset private keys as the 24 words mnemonic phrase. We always suggest writing down private keys and passwords on physical paper/notebooks for safekeeping.
* If you lose the 24 words mnemonic phrase there is no way to recover it.
* Keeping, sharing, or even entering your mnemonic phrase on any digital platform can put your funds at risk if the device you are using is not secured.
* The Zen Protocol developers have not yet released official hardware wallet integration — If you decide to use your own solution, do so with caution.
  {% endhint %}

### Step by Step Guide

**Step 1: Click the ‘Create a Wallet’ button**

<figure><img src="/files/GOh1jNePuY3GuPszpxFD" alt=""><figcaption></figcaption></figure>

**Step 2: Read and Confirm the Term and Conditions**

![](/files/-MYtbpfjHR2Kk-ruEtWV)

**Step 3: Read the security notice and click ‘Continue’**

![](https://lh5.googleusercontent.com/vtnMJ9LWsvpByKikzsskd0_PK6MmI9Q5rpL3BziHU-AyaJGExqZU_pIjmACiVFkgMGwitNKYSS3GNv4nYm3-6QZ3yBF2EGdrEJB3ukwa9Wu4d9Lkj5pw63odtynBTgO55GCrEYss)

**Step 4: Save your 24 mnemonic phrase**

* Write down the 24 words mnemonic phrase in chronological order and save it in a secure place.
* Double check these words are spelled correctly
* Click the checkbox to continue
* We won’t be able to recover this 24 words mnemonic phrase.
* Whoever has access to your mnemonic phrase will have access to the funds stored under it.

**Step 5: Verify saving your 24 mnemonic phrase correctly**

![](https://lh3.googleusercontent.com/pMN1qc5h4MigEVBHJbdgWLrMqQjlGQWeL16VfUJN5-6RN4tnwSOnEM-9pH4FfmJxgS5--WemaebnyVAVnuwlD5Z7f7tt24prX2Fr1J-vjgSjlkoHu2WB01NkLsNMlfQqKykvZlR3)

* To ensure you have written your 24 words mnemonic phrase correctly you will be asked randomly to type in specific words, only when you typed these correctly you will be able to click ‘Continue’ to proceed to the next step.
* If for some reason you did not save it correctly create a new wallet.

**Step 6: Choose password**

![](https://lh4.googleusercontent.com/-gvAr0aD7U3H8VfAJC3ZrUeNTx3aqRqe4s9WAE7eA7WTkOk1-UYxAVVuKlZP362aj8naVCDDEu62A51OqDPH_c4Pq4HjYsFCROMWUPWOB8-dJTxAPdwMgTzSzKpo7Ej6S4uU7nEu)

* Choose a STRONG password to quickly access your wallet without the need of entering your 24 words mnemonic phrase on each session.&#x20;
* This password is also required for creating transactions on the blockchain such as: send tx or voting tx, for activating or extending a contract, backuping your wallet or wiping the blockchain.
* This password must contain at least 8 characters long with at least one number, a lowercase and an uppercase letter.
* If for some reason you forget your password, it is always possible to re-import your wallet using your 24 words mnemonic phrase.
* You can always change your password through the settings page →  ‘Change password’
* Set the amount of time before your wallet will be automatically logged out.

**Step 7: Choose a Passphrase**&#x20;

<figure><img src="/files/fx4rxLACEIbQYVXeTcGU" alt=""><figcaption></figcaption></figure>

**Step 8: Choose a Name**

<figure><img src="/files/TtE1XocWvIqzMMgXXqVm" alt=""><figcaption></figcaption></figure>

**Step 9: Confirm Wallet Creation**

<figure><img src="/files/6mdNTMbL30BpLBqppB8l" alt=""><figcaption></figcaption></figure>


# Import a Wallet

Use this option if you already have your 24 words mnemonic phrase and you wish to connect your wallet.

{% hint style="danger" %}
**Security Notice**

Entering your mnemonic phrase on any digital platform can put your funds at risk. Make sure the device you are using is secured.
{% endhint %}

### Step By Step Guide

#### **Step 1: Click the ‘Import a Wallet’ button**

<figure><img src="/files/jyLbpv9HpQ3RjKoTRSh1" alt=""><figcaption></figcaption></figure>

**Step 2: Read and Confirm the Term and Conditions**

![](/files/-MYtbpfjHR2Kk-ruEtWV)

**Step 3: Enter your 24 words mnemonic phrase**

![](https://lh4.googleusercontent.com/dcz0_45MSRkWccxSSRLMM3i2WMBAGWGkNQZHYwVxmmJ6tE3n-LVhamCNmWlFmTd0IFlzuhSU9GcOjhCTSexkTX4lclveejkJKyZk68ZsEu23l0qDNvMbnXW7msEeNKTiUQ0uUZx3)

* Make sure you have entered your 24 words mnemonic phrase in the right order and all are spelled correctly.&#x20;
* Once all the fields contain a valid bip39 word and have a blue checkmark, you will be able to click the “Continue” button.

**Step 4: Choose password**

![](https://lh4.googleusercontent.com/-gvAr0aD7U3H8VfAJC3ZrUeNTx3aqRqe4s9WAE7eA7WTkOk1-UYxAVVuKlZP362aj8naVCDDEu62A51OqDPH_c4Pq4HjYsFCROMWUPWOB8-dJTxAPdwMgTzSzKpo7Ej6S4uU7nEu)

* Choose a STRONG password to quickly access your wallet without the need of entering your mnemonic phrase on each session.&#x20;
* This password is also required for creating transactions on the blockchain such as: send transactions or voting transactions, for activating a contract, backup your wallet or wiping the blockchain.
* This password must contain at least 8 characters long with at least one number, a lowercase and an uppercase letter.
* If for some reason you forget your password, it is always possible to re-import your wallet using your 24 words mnemonic phrase.
* You can always change your password through the settings page →  ‘Change password’
* Set the amount of time before your wallet will be automatically logged out.

**Step 7: Choose a Passphrase**&#x20;

<figure><img src="/files/fx4rxLACEIbQYVXeTcGU" alt=""><figcaption></figcaption></figure>

**Step 8: Choose a Name**

<figure><img src="/files/TtE1XocWvIqzMMgXXqVm" alt=""><figcaption></figcaption></figure>

**Step 9: Confirm Wallet Creation**

<figure><img src="/files/6mdNTMbL30BpLBqppB8l" alt=""><figcaption></figcaption></figure>


# Watch Mode

Use this option if you already have an address or a public key and you wish to watch your wallet.

The Watch Mode empowers users to import public addresses or a public key, enabling direct wallet observation without the need for private keys. Easily monitor your Zen Protocol wallet without using your passphrase.&#x20;

Additionally, when importing your wallet using either the public address or public key, you also have the ability to include the change address.

### Step by Step Guide

**Step 1: Click the ‘Watch only mode’ button**

<figure><img src="/files/DbVacGTVTfl7DejwwYSc" alt=""><figcaption></figcaption></figure>

**Step 2: Read and Confirm the Term and Conditions**

<figure><img src="/files/8A4JC3uvFMqifTZPS1yf" alt=""><figcaption></figcaption></figure>

**Step 3: Import your public address or public key**

<figure><img src="/files/zR4D3MB0TT92rlQ7HYrn" alt=""><figcaption></figcaption></figure>

**Step 4: Choose password**

<figure><img src="/files/FwdEyothxswuAAN94X0r" alt=""><figcaption></figcaption></figure>

**Step 5: Choose a Name**

<figure><img src="/files/YYYwsrBy1tDchngmz7HY" alt=""><figcaption></figcaption></figure>

**Step 6: Confirm Wallet Creation**

<figure><img src="/files/XHZjPwJIC0yMX33v6a4J" alt=""><figcaption></figcaption></figure>


# My Wallet

View a summary of your portfolio and transaction history, get your receive address or create a transaction.

{% content-ref url="/pages/tgHyFuojnkADgd2Nn2zT" %}
[Navigation Bar](/apps/wallet/wallet-structure/my-wallet/navigation-bar)
{% endcontent-ref %}

{% content-ref url="/pages/-MRtODq1BDwissaQLnlM" %}
[Portfolio](/apps/wallet/wallet-structure/my-wallet/portfolio)
{% endcontent-ref %}

{% content-ref url="/pages/-MRtOGTKzhqMAlMBEQuc" %}
[Receive](/apps/wallet/wallet-structure/my-wallet/receive)
{% endcontent-ref %}

{% content-ref url="/pages/-MRtOIeiuHObOJ1XGDWO" %}
[Send / Execute](/apps/wallet/wallet-structure/my-wallet/send-execute)
{% endcontent-ref %}

{% content-ref url="/pages/-MRtONuBvECFPAue8143" %}
[Transaction History](/apps/wallet/wallet-structure/my-wallet/transaction-history)
{% endcontent-ref %}

{% content-ref url="/pages/Rjc4SZLYSrCSNofp0b1T" %}
[Signer](/apps/wallet/wallet-structure/signer)
{% endcontent-ref %}


# Navigation Bar

<figure><img src="/files/vhtxTK52d1jnBt5fGbtI" alt=""><figcaption></figcaption></figure>

The address displayed in the top right corner of your wallet represents the External wallet address associated with the active account.

The Wallet icon allow you to view all your connected account:

<figure><img src="/files/CcRABXYjjQ09jIFEW9N7" alt=""><figcaption></figcaption></figure>

The balance on the top right corner of your wallet is a representation of the total ZP of the connected account only.


# Portfolio

View the ‘Portfolio’ page to see a full list of your assets and their amount stored in your account.

Go to the ‘Portfolio’ page under “My wallet” tab in the top up navigation bar

<figure><img src="/files/85UQycuMuv87HER8fCSi" alt=""><figcaption></figcaption></figure>


# Receive

Use your main address to receive ZP token or any other compatible tokens to your wallet.

**Step 1:** Go to the ‘Receive’ tab under “My wallet” in the top up navigation bar

**Step 2**: Copy your main or changed public address and send it to the sender

* Receive using your QR code
  * If the Sender uses a mobile app, he can quickly scan the QR code to get the recipient address.
  * Click on the QR code icon to expand it.

{% hint style="info" %}
Save and share the QR code to encapsulates a link to your wallet. For users with compatible wallets, scanning the QR code provides direct access to the send page for  transactions.
{% endhint %}

<figure><img src="/files/jHJlmXBauCR4bTZIs3bG" alt=""><figcaption></figcaption></figure>


# Send / Execute

Use the send form in order to send ZP token or any other compatible token to a valid address. A valid address can be the encoding of an account PK Hash or of a contract ID.

{% hint style="info" %}
**Note:** you can also use the form to execute a contract by providing a contract address in the destination address.&#x20;
{% endhint %}

### **Step By Step Guide**

**Step 1**: Go to the’ Send’ tab under “My wallet” in the top up navigation bar.

<div data-full-width="false"><figure><img src="/files/V9G2iK9LX6S6140CRyUO" alt=""><figcaption></figcaption></figure></div>

**Step 2:** Enter a valid destination address.

**Step 3:** Choose the asset you want to send using the drop down assets list. The list is constructed of your portfolio’s assets. &#x20;

**Step 4:** Enter the amount you would like to send (note the amount will be converted to Kalapas)

**Step 5:** Click the ‘Send’ button to create your transaction.

**Step 6:** Verify your transaction by reviewing the transaction summary.

![](https://lh6.googleusercontent.com/RWFDAbQ_n1k_UwRznQ_8AelWQWrrgR68vegRijJ5hX5670r8IqhahTXD6Zhd1UE2xTxv6wECooNKFKsRtdv8FKAaK7Cs2szatB15XQVUppyhXX_EfUsAzCEgE8INnf8qnLNp7uN-)

**Step 7:** Enter your password/passphrase to continue

<figure><img src="/files/L9th8uCFdrBaY8ovPY5u" alt=""><figcaption></figcaption></figure>

**Step 8:** Confirm transaction by clicking the ‘Publish’ button and when the process is complete a successful message will appear.

* You can NOT cancel a transaction after publishing it.

![](https://lh6.googleusercontent.com/kdDoUz7vBVsxF0FRkcQ8pOGeHchAHWKM454_JznLeVOiT7dDSiU5s8MDdowF12TlK9Vc-MZceAhk4hF4dOF-esMGkBEMK05NChVJfJPSifMcgTV5RKudLURI_Ccx7nOd8dU_9d4o)

### Send multiple assets

If you wish to send more than one asset to one recipient address, then click ‘Add asset & Amount’.

<figure><img src="/files/2WwwvHDCscLZGAdXssm9" alt=""><figcaption></figcaption></figure>

### Sending using QR code

Filling the destination address is also possible by scanning a QR code with an encoded address. The QR code will be found in the ‘Recieve’ page of the recipient wallet account, under ‘My Wallet’.

### Verify your transaction was successfully propagated and check up on it’s status

**Step 1:** Check your Transaction history tab, under My wallet, there you will be able to see the status of your transaction. The transaction will be indicted as ‘pending’ till it gets its first confirmation. Only after the first confirmation you will be able to see it in the Block Explorer.

<figure><img src="/files/PYs1cIR3Ui0r0bgKqoXK" alt=""><figcaption></figcaption></figure>

### Execute a contract using the Send form

When entering an address of a contract the form will automatically recognize it and will enable you to not only send a ZP token or compatible tokens to it, but you will also have the option to execute it by using the additional part added to the send form.

<figure><img src="/files/qR5eRfLPffsAV7jcNMNW" alt=""><figcaption></figcaption></figure>

In order to send ZP token or compatible tokens to a contract address, follow the same steps as a regular send transaction.<br>

### Contract Execution steps

**Step 1:** Enter a valid contract address

**Step 2:** Choose the asset and amount you want to send to the contract

**Step 3:** Choose ‘Command’ (a phrase which tells the contract what to do)

**Step 4:** Message body in YAML format

**Step 5:** Include return address (when the contract is expected to pay back to the address)

**Step 6:** include authentication (when the contract is expected to sign the contract execution with the sender address)

**Step 7:** Click the execute button to Execute the contract.

**Step 8:** Review the execution summary and click ‘Continue’.

**Step 9:** Enter your password sign the transaction

**Step 10: Enter passphrase if your wallet is secured with a passphrase**

**Step 11:** Verify your transaction by reviewing the transaction summary.

**Step 12:** Publish the transaction by clicking the ‘Publish’ button

**Step 13**: When the process is complete a successful message will appear.&#x20;

* You can NOT cancel an execution after confirming it.


# Transaction History

Check the complete history of all recorded transactions of your account under ‘My Wallet’--> ‘Tx History’. On this tab can track account activities like sent/received.

In the table you will be able to check on which block a transaction was made, the asset & amount was sent/received and the number of confirmations of each transaction.

<figure><img src="/files/HemI3VtucYbDfKQUaueC" alt=""><figcaption></figcaption></figure>

### **Transaction Status**

The status ‘Pending’ indicates that a transaction has yet to be added to a block even if it was propagated in the network and has a zero confirmation.

**Transaction Information**

To get more information about a transaction, click the ‘Tx Hash’. This will redirect you to the transaction page in the Block Explorer.

To get more information about an asset, like the total issued, it’s distribution etc, click the ‘Asset’. This will redirect you to the asset page in the Block Explorer.\ <br>


# Contracts

{% content-ref url="/pages/-MRtOWH1Ky0IeqX-ljxu" %}
[Active Contracts](/apps/wallet/wallet-structure/contracts/active-contracts)
{% endcontent-ref %}

{% content-ref url="/pages/-MRtObWlbNgBTf7ufiY4" %}
[Execute a Contract](/apps/wallet/wallet-structure/contracts/execute-contract)
{% endcontent-ref %}

{% content-ref url="/pages/-MRtOdCnl9Zq2jYWJUZQ" %}
[Extend a Contract](/apps/wallet/wallet-structure/contracts/extend-contract)
{% endcontent-ref %}

{% content-ref url="/pages/-MRtOds6Ye8jrMircSv\_" %}
[Activate a Contract](/apps/wallet/wallet-structure/contracts/activate-contract)
{% endcontent-ref %}


# Active Contracts

View a full list of the current active contracts on the blockchain.&#x20;

<figure><img src="/files/1K9iss5lSjipqriBkTTy" alt=""><figcaption></figcaption></figure>

**Contract information**

To view more information of an active contract click on the Contract ID/Address

![](https://lh4.googleusercontent.com/6AXKBC7l8Pjbq9G8ZgVUnIa5bmUmyBmRiv1m7wfuoU6_SvJeSCZocKGcxWSKwnUMkPJpNEJc3AfdcmQgmaxV1oQniQ-VOuwfgHMjE9XI-Ryy1RXXrBuOfpZ3W3iSPfpekhZx6LMk)

**Active Until**

Active until indicates till which block a contract is active for.

![](https://lh6.googleusercontent.com/T_1N-HgVE9CXXjbLLYANaPntoR9vx2wo3l0N3GNi90XdFU7Ds_fSMFEVXutICaMA6YlIRwmGv5RlHnYDQZ2uJXUtmsLiaeTnDnZdwuVtfOD5YqHxLdY0F0BNVTzNdabfvKu_sR3w)

**Contract Code**

To view a contract code click the ‘\</>’ icon

![](https://lh5.googleusercontent.com/MKy2jxZ5_UB-X-T_m9WEEUgD3lwsZnUaaWB56SsKdbjj300L5WsJcNSkwoHd539vBfKCj1v9-VsrOixVDb6F6Q3jiHO6b4iC3fTDLB3DXmOBiedLfsyIQSc58n04PkYZa5C9IrXu)

![](https://lh5.googleusercontent.com/2T-lRnThAdoWHmXkpdZh2bluJ_gKT5jD3B3ZnHDe8V25PU0koXS2hr4xdKNuSVsWNMwHutTLtM6ba7qWTZngLk-GLKhRo5YmTqvBHgn6q3GD4ME2vSLL2zCcVoQNX0PULnWnBI1A)


# Execute a Contract

### Step By Step Guide

**Step 1:** Click the ‘Execute’ button

![](https://lh6.googleusercontent.com/qVukcVFosxL4J-Jpt4icOxIcDUOxPUTf7qO4xurFO3WYI1Ezw_VXCWOZ0at8VRWkZgHEEcV29gMhwJ_1X5i1GyU-dq9aSM5P-HVEJthTl3SffDKqE93dAEzXAm4fdOl5QZaj-UzH)

**Step 2:** Fill in the ‘Execute Contract’ dialog box with the relevant data

![](https://lh5.googleusercontent.com/-6kKxnwX4qXVx2GIIxKXrKmb0VE6cphlaOStHppbYOi6C6mtsJw4iijbh5E06kG5JsA3wF3lzO9v1dtmsTF2UVRtG4YR-UIYTRFWlky27yByrNKw1rY-n8Ju2BCQoS-BDZz0w2OI)

* You can also execute a contract using the ‘Send’ form under ‘My Wallet’. Pasting a contract address in the destination address field, will automatically adjust the form.

**Step 3:** Review your Execution summary and click ‘Continue’<br>

![](https://lh3.googleusercontent.com/PUhysAvD9zeSN-OBTjLzXGN_faclul9-o49EroFlCga0zs3qS4O5eZY5dGkCw4x8mghNOIUEiI3485sfabWL9cKD1NXnhoi9amGJC1GBeh-r7523s9zW1FTVHp6FHcOHZbDT5Mvq)

**Step 4:** Enter your password to sign the transaction and click ‘Continue’

Optional: In case a passphrase was use when wallet was connected, the passphrase will be required for this step

<figure><img src="/files/L9th8uCFdrBaY8ovPY5u" alt=""><figcaption></figcaption></figure>

**Step 5:** Confirm your contract execution transaction and click ‘Publish’

![](https://lh4.googleusercontent.com/KnDDKyimnc0aFV87WjEdv90oZvEQ4r6-E1lHvv5dZZzXypIikWOKGMAonAfOnI367NvqHms5BMQ-XrCPy5OV5M8NE3FSP4msYT_uC8tYO-jjOUwV8hlNpS0kTPR6K85HbxJEubxI)

{% content-ref url="/pages/-MXS03BVUkj-obupvmzz" %}
[Message Body Field](/apps/wallet/wallet-structure/contracts/execute-contract/message-body-field)
{% endcontent-ref %}


# Message Body Field

This field expect a [YAML](https://en.wikipedia.org/wiki/YAML):

| Type                          | Prefix   | Suffix |
| ----------------------------- | -------- | ------ |
| U32 (32 bit unsigned integer) | !uint32  | ul     |
| U64 (64 bit unsigned integer) | !uint64  | UL     |
| I64 (64 bit signed integer)   | !!int    |        |
| String                        | !!str    |        |
| Hash (256-bit hash value)     | !hash    |        |
| Lock                          | !address |        |
| PublicKey                     | !pk      |        |


# Extend a Contract

### Step By Step Guide

**Step 1:** Click on the ‘+’ icon

![](https://lh3.googleusercontent.com/jo6PRa5Iv6alrsiHDbS9S2Azwmvsi5R38sZIxqyZdidTHR95OAnnog1CGCInr-PZjTz-9QY4paLHwTv4fJTq7Mwg-XZaX14tzsSTIHRkCZDzxpPHiBmrPkjXfhO3CT1-5cTp4BGJ)

**Step 2:** In the dialog box, insert the number of blocks you wish to extend the contract for and click ‘Continue’.

![](https://lh5.googleusercontent.com/1G4uJFi6ElNLvGgZBO7LWl7RwF-GuvfQzMGavm9z8356Nnm-_jlnJ0SbG5w-2IG21Ih6UGvhhsY5IUDwjrCIw6NyaW4Fy3W6BGdygX9v9BH8PlWhhFLvl3AaDaXHcaPhu9-P0Jzd)

**Step 3:** Enter your password to sign the transaction and click ‘Continue’

Optional: In case a passphrase was use when wallet was connected, the passphrase will be required for this step

<figure><img src="/files/L9th8uCFdrBaY8ovPY5u" alt=""><figcaption></figcaption></figure>

**Step 4:** Confirm your transaction for extending the contract and click ‘Publish’

![](https://lh3.googleusercontent.com/MvnbAYEMptuCWioIDAs5aupFa54KGHvpo9oLsCfgDrMnJBwrmuh3kRATohDH7lObd90Dv0AUXH2USUhF9DfeztzlEShMuhs0an23YcDZoZHqyO7lDjx4ZCnFabr5H1Wbb2iQXxZ9)

**Step 5:** After publishing your transaction a success message will appear.

**Step 6:**  View your transaction on the ‘Transaction History’ page, you might first see the transaction on pending status, till it will get its first confirmation.\
\ <br>


# Activate a Contract

{% hint style="info" %}
**Activation of a contract is available only through the desktop wallet connected with a local headless node.**
{% endhint %}

**Step 1:** Click the ‘Activate’ button

![](https://lh4.googleusercontent.com/73rGwYTD5bY9b8GkcYCBGXiww2IKFjNT6CcVjrCprgvkq5H70Cy1U_PdC76F4efYOJ6eo7SxV8bcYTXY7DiI99kzVj0_8iZQho68HkfEemBFAJyRtzLxHvQAuvqsVJVYAnaz1ISP)

**Step 2:** Drag an .fst file to the dialog box or choose an .fst file from your library

**Step 3:** Choose the numbers of block you wish the contract to be active for

**Step 4:** The Rlimit is for more advanced users, it will affect the cost of a contract, and is not suggested to be used by non advanced users as the rlimit is the upper bout for which the hints of the contract will be recorded.&#x20;

**Step 5:** Click ‘Continue’

![](https://lh3.googleusercontent.com/hSESJE6LTTdMPgC8MT644PbmhEe6OWRKOg2ewwuUrXrP7i63fi3UHhwCleAd4f_cS6NJhwLOCGO7bc0t_9XxdvRcRwZxo0DhCfv2iUM7nHzl74htI0b249Vph9_YrJqTTZgdX1po)

**Step 6:** Enter your password and click ‘Continue’

Optional: In case a passphrase was use when wallet was connected, the passphrase will be required for this step

<figure><img src="/files/L9th8uCFdrBaY8ovPY5u" alt=""><figcaption></figcaption></figure>

**Step 7:** Confirm your activation by clicking the ‘Publish’ button, make sure to review the summary of the transaction before publishing it.

![](https://lh4.googleusercontent.com/4VQNekdSS2cAByEiFOer6DNkXvoX2c7F6eDhGjFXSpg1O6agXtpwATZidG0GjvmPpxDglKgr_zQOGvnc2RWCI_7LEjbIO6xn7-x-jP2R6NtQKWyVDhXk1aK5pTdCzyf9UcyEYZGo)

**Step 8:** After publishing your transaction a success message will appear.

**Step 9:** After activating your contract you will be able to see it in the ‘Active Contracts’ table

* On the transaction page you might first see the transaction of the execution on pending, till it will get its first confirmation.


# Voting

{% content-ref url="/pages/-MRtOv2cHCsFmrZT3vq0" %}
[Common Goods Pool](/apps/wallet/wallet-structure/voting/common-goods-pool)
{% endcontent-ref %}

{% content-ref url="/pages/-MRtP4DchhxA3sekItTg" %}
[Governance](/apps/wallet/wallet-structure/voting/governance)
{% endcontent-ref %}


# Common Goods Pool

Vote on how to allocate part of the block reward to the CGP and on how it should distribute its funds go to ‘Common Good Pool’--> ‘Voting’.

### Step By Step Guide

#### Vote for a proposed payout Ballot

To Vote for a proposed payout go to ‘Common Good Pool’ under the ‘Voting’ tab in the main navigation.

**Step 1:** Here you can do one of the following

1. Choose a Payout Ballot ID in the ‘Ballot ID’ field using the dropdown menu
2. Click one of the proposed Ballot IDs from the Nominees Board

**Step 2:** Click the ‘Vote’ button to continue

**Step 3:** Review your voting summary  and click ‘Continue’

**Step 4:** Enter your password to execute the vote transaction by clicking the ‘Vote’ button.

**Step 5:** After publishing your transaction a success message will appear.

**Step 6:** after executing your vote transaction you will be able to see it on the ‘Transaction History’ page

* You might first see the transaction on ‘Pending’, till it gets its first confirmation

#### Vote for a the reward distribution:

To Vote for the reward distribution go to ‘Common Good Pool’ under the ‘Voting’ tab in the main navigation.

**Step 1**: use the horizontal scroll bar to choose a valid allocation or use the dedicated input box

**Step 2**: Click the ‘Vote’ button to continue

**Step 3:** Review your voting summary  and click ‘Continue’

**Step 4**: Enter your password to execute the vote transaction by clicking the ‘Continue’ button

**Step 5**: After publishing your transaction a success message will appear.

**Step 6**: after executing your vote transaction you will be able to see it on the ‘Transaction History’ page

You might first see the transaction on ‘Pending’, till it gets its first confirmation.


# Generating a Ballot ID

Prepare a new ballot without the needs of waiting for a voting interval

### Step By Step Guide

1. Choose: "Generate Ballot" in the CGP voting page.
2. Upon selection, a new pop up will appear allowing for the creation of a new ballot ID

<figure><img src="/files/oS45XpNm3s5TZue99jRY" alt=""><figcaption></figcaption></figure>

3\. Upon selection of the recipient address, asset and amount fields, a ballot ID will be generated and can be submitted for voting in the next phase.


# Governance

{% hint style="info" %}
Protocol development is managed by token holders, by participating in semi-annual coin votes, which determine protocol upgrades. As stated in the Authorized Protocol document token holders needs to vote on a working implementation of the protocol by first contest the implementation in the network and if it passes the threshold of 3% of the total ZP issued then it will pass to the candidate phase where token holder can vote on the new implementations.&#x20;
{% endhint %}

#### **Vote in Contestant Phase**

**Step 1**: Go to ‘Governance’ tab under ‘Voting’ in the main navigation

**Step 2:** Insert your preferred valid commit ID&#x20;

**Step 3**: Click the ‘Vote’ button to continue

**Step 4**: Review your voting summary  and click ‘Continue’

**Step 5**: Enter your password to execute the vote transaction by clicking the ‘Continue’ button.

**Step 6**: After publishing your transaction a success message will appear.

**Step 7**: after executing your vote transaction you will be able to see it on the ‘Transaction History’ page

* You might first see the transaction on ‘Pending’, till it gets its first confirmation

#### Vote in Candidate Phase

**Step 1**: Go to ‘Governance’ tab under ‘Voting’ in the main navigation

**Step 2**: Choose your preferred valid commit ID&#x20;

**Step 3**: Click the ‘Vote’ button to continue

**Step 4**: Review your voting summary  and click ‘Continue’

**Step 5**: Enter your password to execute the vote transaction by clicking the ‘Continue’ button.

**Step 6**: After publishing your transaction a success message will appear.

**Step 7**: after executing your vote transaction you will be able to see it on the ‘Transaction History’ page

* You might first see the transaction on ‘Pending’, till it gets its first confirmation


# Signer

View unsigned transactions, sign, and publish with Zen Wallet.

{% hint style="info" %}
**Note:** The Watch Wallet mode allows the creation of unsigned transactions.&#x20;
{% endhint %}

### **Step By Step Guide**

**Step 1**: Go to the’ Signer’ tab in the top up navigation bar.

<figure><img src="/files/PwuottScTjZ5ymWtsBx2" alt=""><figcaption></figcaption></figure>

**Step 2:** Enter a valid unsigned transaction.

<figure><img src="/files/Q9AojCCmOiDjR8ssYQbe" alt=""><figcaption></figcaption></figure>

**Step 3: R**eview the summary of the transaction and verify the outputs before signing.

**Step 4:** Click the ‘Sign’ button to sign your transaction

**Step 5:** Enter your password/passphrase to continue

<figure><img src="/files/L9th8uCFdrBaY8ovPY5u" alt=""><figcaption></figcaption></figure>

**Step 6:** Verify your transaction by reviewing the summary

<figure><img src="/files/SeR3TMJrU1Y2OYayu690" alt=""><figcaption></figcaption></figure>

**Step 7:** Publish the transaction by clicking the ‘Publish’ button


# Settings

Click the ‘Settings’ icon on the top right corner of your screen to control your account and connectivity configurations. (on mobile, it will be found in the side menu)

{% content-ref url="/pages/-MRtPA3xjMY1W\_cB3iRp" %}
[Account Settings](/apps/wallet/wallet-structure/settings/account-settings)
{% endcontent-ref %}

{% content-ref url="/pages/-MRtPDalEWOfgtfhpIpQ" %}
[Node Connectivity](/apps/wallet/wallet-structure/settings/node-connectivity)
{% endcontent-ref %}


# Account Settings

Under ‘Account Setting’ you will be able to configure the wallet settings

**Name your account**&#x20;

Set up and configure the account name according to your preferences

<figure><img src="/files/nPP3mBGCBSK3MeaN55dv" alt=""><figcaption></figcaption></figure>

**Auto logout**

Enter the number of minutes to set the inactivity timeout. After this time you will need to login again&#x20;

![](https://lh3.googleusercontent.com/MG13VGvH_RMJg1egR3LtLTw00ChNcPkbRdlO7FzqwyKlhpq0H1AK55NEIFVtTZsjgSMcx-sPXGQuH3iN1mo5VrDFPL6GXycQ3atEMKCmIZBnZiKtKxsv32R8Kd4S2i8BrWb3vlsU)

**Login Password**

**Step 1**: Click the “Change’ button to change your current password to a different one.

![](https://lh6.googleusercontent.com/pi3-zcfFOL_4_jn5RBCmgCoioJZ2y-WRmXl13zhz8BQ_Ke7surjbLVdX5RGP8xylhGn5A7xrxJxG0k_0DoBm9dm6LHJU8bTusfOKoDdfRNOaux5ww8-sHqLT1vSKrlpV_Atpxh9j)

**Step 2**: Enter a new secure password and click ‘Save Changes’

* When changing your password remember to:

**Step 3**: Choose password

![](https://lh5.googleusercontent.com/vCTvTpUxIU1_6YvkOJYrlWE8jb0REKEUhXrFnpxzrNwXYCFJ8i6VwA4Zxlz3eIwl73o8tlKs8qqPh7JHLM4bpQLoVRkIIwU0wpJ14d8tCzxt1hQGySROB29pIODtpwtyYpKpOBoZ)

#### View your Accounts

Under the View your accounts dialog you will be able to view your connected accounts

**Step 1**: Click the ‘View’’ button to view your connected accounts.

<figure><img src="/files/OTcpMy3Fi8ulai3lZaPk" alt=""><figcaption></figcaption></figure>

**Step 2**: View your connected Accounts&#x20;

<figure><img src="/files/Kfz2JOW2fI6vBfkgclGT" alt=""><figcaption></figcaption></figure>

**Backup Wallet**

{% hint style="warning" %}
Security notice

Showing your mnemonic phrase on a digital platform can put your funds at risk. Make sure the device you are using is secured.&#x20;
{% endhint %}

Under the backup wallet dialog you will be able to view your wallet’s private info by providing the wallet password:

**Step 1**: Click the ‘Show’’ button to view your wallet’s private info.

![](https://lh3.googleusercontent.com/-iENCM5p14KpNOKuPINTHR-I7V50EtS0s90Q4QVF-FBt1DetcQ_JuQjRhtqkeR_zbM-4qMl7FYnOLck-ee1UdMuVBJ7ZaB7tqfO-AHGr7nQIoqgQ1yKB4g0bbycnbuDGv6A4Lfnd)

**Step 2**: Read the security warning and confirm to continue.

![](https://lh4.googleusercontent.com/PTeYaqvYVQ3u5xNhZmLjYAZN0QKjgQ907uUw-1PmUho2nz4BBuJgBX4bFsPBr65dy2SRvYGrnuiuIvfUG6TzN4XjqXvMpQVOqje-ECJ9oAyhFVYkEst0SG-esWm616hBrV3hyr0Z)

**Step 3**: Enter your password to continue.

**Step 4**: View your private infos

* **PK hash:** The decoded address used to lock the UTXO to
* **XPUB KEY**:  Public key derived from the mnemonic phrase
* **PUBLIC KEY External**: Public key used to derive the external address
* **PUBLIC KEY Change:** Public key used to derive the change address
* **Menominic**: A valid BIP39 24 words phrase used to derive public and private keys
* **XPRIV KEY**: Private key of the main account derived from the mnemonic phrase

![](https://lh5.googleusercontent.com/FhiHlj_Js9V1o6yXNnV_5VYKZiQIULMDVwkzqQYHWUoGyXg57mgyEYaSf9j81a4Ed3Fq23ff5RG0X-YM39aitDQP9yVS6BGif3lIcs_t-_o5BzE0PuzxTCV6Bu06ur72XVHB1WhV)

**Wipe Wallet**&#x20;

Wipe the wallet secured mnemonic to import a new one.

**Step 1**: Click the “Wipe’ button to delete your wallet

Optional: added more than one account, choose between wiping all the account or just the current one

![](https://lh6.googleusercontent.com/hg5neqFP3MyHM_96PXYwsA2SfVUdZV2atCZR-Q3jnk8aI5pszVeKS1PqXyZocgAGO9i2fO8_3SF-hnI8Uev4LUCiBdeyPIIigKtLJ5Szx45fTfKtXBlD9KXRynH0M8Fls9jjDrKC)

**Step 2**: Choose between:

* &#x20;‘Wipe’ in order to erase your wallet
  1. Provide the wallet password to continue
* &#x20; “Backup Wallet’
  1. Provide the wallet password to see your wallet’s private info.
  2. Confirm deleting your wallet  by clicking the ‘Wipe’ button.

![](https://lh5.googleusercontent.com/bDPiKTGBBF-vUIZg6fTE3j5R9GC7fwOb3FcIt-RP4K_rOIgVimDdqiMp3BYqvhXM_jqzMbUU_4XD2ft64BKaw19qXANwwx_iX5teAAvXa9HL_B-gMdMzq_DBHVp30I2lgRn5zIpw)


# Node Connectivity

Choose among the provided remote nodes to connect the wallet to the network. On default, your wallet is connected to the remote node on the mainnet.

Click the ‘Node Connectivity’ tab under the ‘Settings’ icon on the top right corner of your screen (on mobile, it will be found in the side menu)

![](https://lh6.googleusercontent.com/W_5zZd298M-aRfQxVnZ1JnxI65FR251h1LVwOfA-frna-GhcleFrZHEh_V9f2_yYL_X68lHLryisX_WyncfwKVuz6eXFccbV7A6VXQSdH15mgg8bWSD2Chg2iz7bk4UiD-kkbjPv)

#### Web and Desktop:

* Mainnet | Remote Node |[ ](https://mainnet-nodes.zp.io)<https://mainnet-nodes.zp.io>
* Testnet | Remote Node |[ https://testnet-nodes.zp.io](https://testnet-nodes.zp.io)

#### Desktop only:

* Mainnet | Local Node |[ http://localhost:11567](http://localhost:11567/)
* Testnet | Local Node |[ http://localhost:31567](http://localhost:31567/)


# Deprecated Desktop Wallet

Wallet GUI with Node Wrapped inside

{% hint style="danger" %}
The Zen-Protocol-Wallet was deprecated. The node and the Wallet have been separated in the new release.
{% endhint %}

### From source

{% content-ref url="/pages/-LE8jld8g8tg0lgIUZoj" %}
[Executable Installers](/apps/wallet/deprecated-desktop-wallet/installers)
{% endcontent-ref %}

## Usage Instructions

{% content-ref url="/pages/-L9kCd1GECNumAa5Qd\_s" %}
[Wallet Structure](/apps/wallet/deprecated-desktop-wallet/wallet-walkthrough)
{% endcontent-ref %}


# Executable Installers

Download and installation for users without development experience.

### Prerequisites

Please make sure to install all of the necessary dependencies below before trying to run the Zen Wallet Software.

### Windows

1. Download the most recent ***Zen Wallet Setup.exe*** from [Github](https://github.com/zenprotocol/zenwallet/releases)
2. Your browser may warn that the download is not commonly downloaded. Click "keep" to download it anyway.
3. Run the installer. You'll need to click the `More Info` button and click `Run anyway`

### Mac OSX

1. Download the most recent **Zen Wallet.dmg** file from [Github](https://github.com/zenprotocol/zenwallet/releases)
2. After installing drag the Zen Wallet icon to the applications folder, add login credentials for authentication if needed.
3. Right click and choose *Open .*
4. Confirm by clicking the *Open* button

### Linux

1. Download the most recent **Zen Wallet.AppImage** file from [Github](https://github.com/zenprotocol/zenwallet/releases)
2. Once extracted you can run the executable named zen-wallet.

## Link to Download Installers

<https://github.com/zenprotocol/zenwallet/releases>


# Wallet Structure

Here you can read an overview of the basic send and receive features, and information about the different aspects of the desktop wallet.

## Wallet Overview <a href="#wallet-overview" id="wallet-overview"></a>

* Portfolio – View list of assets, their hash name, and current balance.
* Send – Submit address you want to send your tokens to, select asset (token) you would like to send, and enter the amount.
* Receive – Address used to receive Zen Tokens (or other compatible tokens) to your wallet
* Transaction - View all recent transaction to and from your wallet&#x20;
* Active Contracts – This is a list of all contracts that are currently active on the blockchain.
* Saved Contract – Easy access to previously used contracts and templates
* Blockchain Logs - See some of the important messages from the CLI for easy troubleshooting purposes
* Settings - Update your settings, wipe the blockchain and seed from your device, or switch to the 'Testnet' with a single click

### Receive Tokens (From Others) <a href="#receive-tokens-from-others" id="receive-tokens-from-others"></a>

1. Click the **Receive** tab (left panel).
2. Click on address or copy button
   1. Either one will copy your address to receive tokens to the clipboard for easy pasting
3. Send your address to someone who wants to transfer you tokens.

### Send Tokens (To Others) <a href="#send-tokens-to-others" id="send-tokens-to-others"></a>

1. Click the **Send** tab (left panel).
2. Enter other person's address.
3. Choose Asset
   1. Tokens in portfolio are already hard-coded options.
4. Enter *Amount* you want to send
5. Click *Send* (blue)

## General Info (Bottom Left)

**Chain:** mainnet or testnet (testnet is a separate chain for development and testing purposes).

**Blocks:** # of blocks downloaded locally from the current chain.

**Headers:** # of blocks validated in the current chain.

**Mining Difficulty:** The current difficulty of mining.

**MTP:** “Median Time Past” — the minimum time for all future blocks on this chain.

**Connections:** # of active nodes you are paired with.

**Wallet Version:** Current wallet GUI (General User Interface) version — v0.9.0 will be the first Mainnet wallet release.

**Node Version:** Current node version — v0.9.0 will be the first Mainnet node release.


# Video Tutorials

This section provides video instructions on different features of the Testnet. If you want to comment or have any videos you think would be helpful please e-mail isaac\@zenprotocol.com

#### Installation & Update Instructions

{% embed url="<https://www.youtube.com/watch?v=tYtMcELj3T0>" %}

#### Creating a Wallet

{% embed url="<https://www.youtube.com/watch?v=GGvAc51AlLc>" %}

#### Importing an existing wallet seed

{% embed url="<https://www.youtube.com/watch?v=FuKz2bTIbmw>" %}

#### Claim Crowdsale Tokens

{% embed url="<https://www.youtube.com/watch?v=NSjVduDJuBs>" %}

#### Create and Activate a Smart Contract

{% embed url="<https://www.youtube.com/watch?v=XUTk5lpzZHI>" %}

#### Send and Receive Tokens

{% embed url="<https://www.youtube.com/watch?v=p478tF0-OxM>" %}


# Explorer

{% hint style="info" %}
The Mainnet Zen Protocol Explorer can be reached at: <https://zp.io>
{% endhint %}

### Stats Page

#### Statistic

* Chain
* Blocks
* Transactions Count
* Mining Difficulty
* Network Hash Rate
* CGP Balance
* CGP Current Allocation
* Zen Wallet Version
* Zen Node Version

#### Charts

* Transactions Per Day
* Block Difficulty
* Network Hash Rate
* Zp Rich List
* ZP Supply

### View By

#### Blocks

View all the latest blocks in an informative table

#### Contracts

View all the contracts activated in the blockchain

#### Assets

View all the assets minted in the blockchain

### Voting

#### Governance

Protocol development is managed by token holders, by participating in semi-annual coin votes, which determine protocol upgrades.

The community vote is split into two phases, each phase has it’s own snapshot:

* **Proposal Phase**: Proposals which received an aggregated vote weight of more than 3% of the outstanding ZP will be considered eligible release candidates in the community vote.
* **Vote Phase**: Vote on the eligible release candidates. The release candidate which wins the community vote must be upgraded to prior to the version expiry.

The protocol is held under a proprietary [open source license](https://github.com/zenprotocol/zenprotocol/blob/master/AUTHORIZED_PROTOCOL.pdf) which is designed to force coin holders to reach consensus, rather than bifurcate the network

#### CGP - Common Goods Pool

Every 10,000 blocks, token holders can vote to determine what percentage of newly minted coins will go to miners, and what percentage will go to the Common Goods Pool. In addition token holders will be able to vote on what it should do with its funds, based on token weighted basis.

{% content-ref url="/pages/-MQh-PVzbxZ84F42Cp8O" %}
[Common Goods Pool](/common-goods-pool)
{% endcontent-ref %}


# Zen.js

Zen.JS is the library for interacting with the Zen Protocol node via JavaScript.

Zen.js is helps in:

* Generate Mnemonic phrase
* Secure Mnemonic phrase
* Serialise and deserialise Consensus types
* Sign transactions
* Defining the contract message body
* Create a wallet instance to interact with the blockchain
* Encode and decode extendend keys to address

{% embed url="<https://gitlab.com/zenprotocol/zen.js>" %}

### Install

```
npm config set @zen:registry https://www.myget.org/F/zenprotocol/npm/ 
npm install --save @zen/zenjs
```

### Generating mnemonic phrase, keys and accepting payments

```typescript
import {Mnemonic, ExtendedKey} from '@zen/zenjs'
const mnemonic = Mnemonic.generateMnemonic(24);
const extendedKey = ExtendedKey.fromMnemonic(mnemonic);
const derivedExtendedKey = extendedKey.derivePath("m/44'/258'/0'/0/0");
const privateKey = derivedExtendedKey.getPrivateKey();
const publicKey = derivedExtendedKey.getPublicKey();
const address = publicKey.toAddress('main');
console.log(address, publicKey.toAddress('main'));
```

### Creating and signing transactions

To create a transaction using a TransactionBuilder, you need to:

* Add an input: This involves providing the transaction hash (txHash) of a previous transaction that contains the unspent transaction output (UTXO) you want to use as an input, along with the index of the UTXO in that transaction. Additionally, you need to provide the private key associated with the UTXO's address.
* Add an output: This involves specifying the receiver's address (where you want to send the funds), the amount of Kalapas (the cryptocurrency) to send, and the asset ID (the identifier of the asset being transferred).

Once you have added the input and output to the transaction, you can proceed to sign it. The signing process involves using the private key associated with the input UTXO to create a digital signature for the transaction. The signature ensures the integrity and authenticity of the transaction.

After the transaction is signed, it needs to be transformed into hexadecimal format (hex) so that it can be published on the network. This encoding ensures that the transaction can be transmitted and understood by the blockchain network.

Here an example:

```typescript
import {TransactionBuilder,ExtendedKey} from '@zen/zenjs'
import {post} from 'axios'

const mnemonic = 'one one one one one one one one one one one one one one one one one one one one one one one one';
const privateKey = ExtendedKey.fromMnemonic(mnemonic).derivePath("m/44'/258'/0'/0/0").getPrivateKey();
const tb = new TransactionBuilder('test');
tb.addInput('0000000000000000000000000000000000000000000000000000000000000000',0, privateKey);
tb.addOutput('tp1qfyplhxql09lvvg53dxg7t77tkkxhsp3l6q8xjjpj85hvqlw0ttqswjdapx', 100, '00');
const tx = tb.sign();
console.log(tx.hash(), tx.toJson());
const hex = tx.toHex();// Transaction is ready to be published 
post('http://127.0.0.1/:31567/blockchain/publishtransaction',hex,{ headers: { 'Content-Type': 'application/json' }});
```

### Wallet functionalities

```typescript
export class Wallet {
    constructor(extendedKey: ExtendedKey, actions: WalletActions, index?: number);
    static fromMnemonic(key: string, actions: WalletActions): Wallet;
    getExternalPublicKey(): PublicKey;
    getExternalPublicKeyHash(): Hash;
    getExternalAddress(): string;
    connectWallet();
    getActiveContracts(): Promise<ActiveContracts[]>;
    getBalance(addresses?: string[]): Promise<{}>;
    submitRepoVote(repoVotingContract: string, commitID: string, phase: "Contestant" | "Candidate", currentInterval: number, privates: PrivateKey[], publish?: boolean): Promise<string>;
    submitCGPBallot(cgpVotingContract: string, command: string, ballotData: Payout | Allocation, isNomination: boolean, currentInterval: number, privates: PrivateKey[], publish?: boolean): Promise<string>;
    signMessage(msg: Buffer, path: string, privates: PrivateKey[]): Signature;
    getAddress(path: string): string;
    getTransactions(skip?: number, take?: number): Promise<Transactions>;
    getTransactionCount(): Promise<number>;
    send(outputs: Array<SpendType>, privates: PrivateKey[], publish?: boolean): Promise<string>;
    sendRaw(outputs: Array<SpendType>): Promise<RawTransaction>;
    executeContract({ address, contractData, privates, publish }?: any): Promise<string>;
    extendContract({ contractId, numberOfBlocks, privates, publish }?: any): Promise<string>;
    activateContract({ code, limit, numberOfBlocks, privates, publish }?: any): Promise<string>;
    signTransaction(unspentTx: Transaction | string, privateKeys: PrivateKey[]): Promise<string>;
    signContractExecution(unspentTx: Transaction | string, sign: string | undefined, privateKeys: PrivateKey[]): Promise<string>;
    collectRaw(requiredAmounts: {[s: string]: string;}, addresses?: string[]);
}
```


# Payment Processing

## Payment Processing

Zen Protocol is a multi-token blockchain, any contract can issue any number of tokens. Each token (called an *asset*) is represented by the contract identifier and optional sub type (of 32 bytes).

Zen assets are represented by one byte of the value *0* (zero).

Each asset also has a string representation, which is being used in the UI and API. Zen tokens are represented by the string *00* (zero zero).

Unlike bitcoin, when sending an asset we have to specify which asset are we spending. Therefore the API always requires an additional *asset* parameter on the `wallet/send` and `wallet/execute` API calls.

### Hot wallet payment processing

The Zen-Node exposes an API for accepting payments.&#x20;

For each payment we generate a new unique address and provide it to the end-user. Then periodically check the amount received for each address and save it. When the amount for address changed between calls you know the user made a payment. You can also specify the minimum confirmations required to consider a payment as complete.

All the assets belong to the wallet and can be spent by the `wallet/send` API call.

You first have to create a wallet, either through the UI or via the `zen-cli`. The private key is encrypted, however it is still on the hot zen-node machine, therefore this solution should be treated as a hot wallet.

### API Calls

## Send Assets

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/send`

Accepts a list of assets, amounts and destination addresses, in order to create, sign and publish a transaction.

#### Path Parameters

| Name | Type  | Description                                                                                    |
| ---- | ----- | ---------------------------------------------------------------------------------------------- |
|      | array | <p>\[{<br>  "address": "tp1q7n4l3dldcv69wf",<br>  "asset": "00",<br>  "amount": 1234<br>}]</p> |

#### Request Body

| Name     | Type   | Description |
| -------- | ------ | ----------- |
| password | string | "1234"      |

{% tabs %}
{% tab title="200 " %}

```
```

{% endtab %}
{% endtabs %}

## Get New Address

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/getnewaddress`

Generate a unique new address. Returns both the address and the address index. Save the index as well in order to restore the wallet in the future.

{% tabs %}
{% tab title="200 " %}

```
{
    "address": "tzn1q7gye0nkgxuwal949y4ke94mwfwsf7eaafy7p5tkdcr6ujuyglqwsnjv2gt",
    "index": 0
}
```

{% endtab %}
{% endtabs %}

## Received By Address

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:31567/wallet/receivedbyaddress`

Return the amount received for each address and asset in the wallet. The amount can only grow, spending an input that belongs to one of the addresses **does not** decrease the amount received. Amount received is the amount the address received in it's entire lifetime.

{% tabs %}
{% tab title="200 An array of addresses and the asset and amount in each address." %}

```
[
    {
        "address": "tzn1q7huplz5q5w7w9234a43hk4llyaegedq6dlfgm7mfp5w3em6s3uus4hwj7q",
        "asset": "00",
        "amount": 9497378334165913
    },
    {
        "address": "tzn1q7huplz5q5w7w9234a43hk4llyaegedq6dlfgm7mfp5w3em6s3uus4hwj7q",
        "asset": "000000006a26b38c2875d1379405bb7d140078ccffb560aff839a3d846850e99ab3d9de84265617200000000000000000000000000000000000000000000000000000000",
        "amount": 199999994
    },
    {
        "address": "tzn1qlvm8ey4m5mj6ak3an39qdfzf7yx4uz59flzlant6jp0gzld48egsj433m6",
        "asset": "00",
        "amount": 1855040761794
    }
]
```

{% endtab %}
{% endtabs %}

## Account Discovery

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/restorenewaddresses`

Have a new node run an account discovery on a certain amount of addresses.

#### Path Parameters

| Name | Type   | Description                                                  |
| ---- | ------ | ------------------------------------------------------------ |
| max  | string | Write the number of addresses you want the node to discover. |

{% tabs %}
{% tab title="200 " %}

```
```

{% endtab %}
{% endtabs %}

###

### Cold wallet payment processing

You can also use cold wallet for the payment processing.&#x20;

You will have to use [zen.js](/apps/zen_js) library for the process.

Generate an extended private key on a secure computer and import the extended public key.

```javascript
import {Mnemonic, ExtendedKey} from '@zen/zenjs'

const mnemonic = Mnemonic.generateMnemonic(24); // Generate once
console.log('mnemonic phrase', mnemonic);

const publicKey = ExtendedKey.fromMnemonic(mnemonic).neutered();

console.log('Extended Public Key', publicKey.toString());
```

On a hot machine generate a unique address by deriving the key with a unique index. Save the index to later sign the transaction on the secure computer.

```javascript
import {ExtendedKey} from '@zen/zenjs'
import {post} from 'axios'

const publicKey = ExtendedKey.fromString(encodedString);
const address = publicKey.derive(uniqueIndex).toAddress();

// import the address to zen node
post('http://127.0.0.1/:31567/wallet/importwatchonlyaddress',address,{ headers: { 'Content-Type': 'application/json' }});
```

Share the address with the user and track the address for income payments the same as for the hot wallet, by calling `wallet/receivedbyaddress`

To make a payment you will to get the outputs from the zen-node and assemble the transaction on the secure computer. Retrieve the available outputs by calling `wallet/addressoutputs` for each address.

Example of assembling and publishing  transaction:

```javascript
import {TransactionBuilder,ExtendedKey} from '@zen/zenjs'
import {post} from 'axios'

const tb = new TransactionBuilder('main');

// Get the private key by matching the unique index for the input address
const privateKey = ExtendedKey.fromMnemonic(mnemonic).derive(inputAddressIndex).getPrivateKey();

// An example input, use one you retrieved by calling `wallet/addressoutputs`
tb.addInput('0000000000000000000000000000000000000000000000000000000000000000',0, privateKey);

// Address, amount and token (Zen)
tb.addOutput('tp1qfyplhxql09lvvg53dxg7t77tkkxhsp3l6q8xjjpj85hvqlw0ttqswjdapx', 100, '00');

const tx = tb.sign();

// You can take the hex to an hot computer
const hex = tx.toHex();

// Transaction is ready to be published
post('http://127.0.0.1/:31567/blockchain/publishpublishtransaction',hex,{ headers: { 'Content-Type': 'application/json' }});

```


# Oracle

We are developing a standard for data providers to supply information on what happened in the world so smart contracts can act on that information.

Learn more about our approach towards oracles in this [blog post](https://blog.zenprotocol.com/oracles-and-zen-1596c6ba6df8).

Our oracle solution is still a work in progress. If you would like to follow development you can follow the progress on the following repositories

<https://gitlab.com/zenprotocol/zen-oracle>

## Oracle Service

{% content-ref url="/pages/-MRFu8aUNh6X\_-Yun77Q" %}
[Oracle Service](/apps/oracle/oracle-service)
{% endcontent-ref %}

## API Methods

{% content-ref url="/pages/-MRFuMv7UCMKrpDG8AAH" %}
[Oracle's API](/apps/oracle/oracles-api)
{% endcontent-ref %}


# Oracle GUI

The list represent the commitments done by the oracle provider using the Oracle Contract.

{% hint style="success" %}
Available at <https://oracle.zp.io>
{% endhint %}

The oracle uses the [Oracle Service](/apps/oracle/oracle-service) implementation to commit data to the Zen Protocol Network.


# Oracle Service

## Commands

### Usage

```javascript
USAGE: zen-oracle.exe [--help] [<subcommand> [<options>]]

SUBCOMMANDS:

    commit, c <options>   commit an item or a data set
    query, q <options>    query for committed data
    attest, a <options>   attest on committed data
    audit, p <options>    get the audit path for a committed item
    server, s <options>   create a web server

    Use 'zen-oracle.exe <subcommand> --help' for additional information.

OPTIONS:

    --help                display this list of options.
```

### Environmental Variables

1. Make sure all the environment variables are provided and correct
   * `zen_path` : path of the oracle committer
   * `zen_wallet_password`: password of the f# wallet
   * `zen_node_uri`: uri of the node
   * `oracle_api`: `uri:port` api port for oracle requests
   * `mongo_connection`: MongoDB (optional. defaults to "mongodb://127.0.0.1:27017")

### Commit

To commit use the command:

```bash
zen-oracle.exe commit [--timestamp <timestamp>] [--notx] [--stdin] [<file>]
```

or the shorthand

```bash
zen-oracle.exe c [--timestamp <timestamp>] [--notx] [--stdin] [<file>]
```

This command has a parameter `<file>` and the following flags:

* **`--timestamp`**, **`-t`** `<timestamp>`

  Time of the committed data (in milliseconds since the Unix epoch - 00:00:00 UTC on 1 January 1970).
* **`--notx`**, **`-x`**

  Don't create a commitment transaction, just return the message body.
* **`--stdin`**, **`-i`**

  When this flag is used - get JSON string from standard input (can't be used along with `-f`).

For the `<file>` parameter use the name of a JSON data file you want to commit.

The JSON file should be a record with names and values, like this:

```bash
{ "APPL" : 10 , "ABCD" : 12 , "WXYZ" : 123 , "XYXY" : 6456 }
```

### Attest

To attest use the command:

```bash
zen-oracle.exe attest [--root <root>] [--timestamp <timestamp>] [--commit <commit>] [--publickey <pk>] [--contract <cid>] [--notx]
```

or the shorthand

```bash
zen-oracle.exe a [--root <root>] [--timestamp <timestamp>] [--commit <commit>] [--publickey <pk>] [--contract <cid>] [--notx]
```

This command has the following flags:

* **`--root`**, **`-r`** `<root>`

  Root of the committed Merkle tree.
* **`--timestamp`**, **`-t`** `<timestamp>` Time of the committed data (in milliseconds since the Unix epoch - 00:00:00 UTC on 1 January 1970).
* **`--commit`**, **`-c`** `<commit>`

  Commit ID of the committed data.
* **`--publickey`**, **`-p`** `<pk>`

  Public key of the recipient address.
* **`--contract`**, **`-d`** `<cid>`

  Contract ID of the recipient contract.
* **`--notx`**, **`-x`**

  Don't create an attestation transaction, just return the message body.
* **`--address,`**&#x20;

  Address of the recipient (either a contract address or a public key hash address)

You have to use either **`--commit`** or both **`--root`** and **`--timestamp`**.

You can only have at most 1 recipient (either **`publickey`** or **`contract`**).

If you don't provide a recipient the attestation token will be sent to the sender.

### Query

To query use the command:

```bash
zen-oracle.exe query
```

or the shorthand

```bash
zen-oracle.exe q
```

There are 2 things you can query for - the **oracle public key** or information about **committed data**.

#### Oracle Public Key

To get the public key of the oracle run:

```javascript
zen-oracle.exe q p
```

#### Committed Data

To get information about committed data run:

```javascript
zen-oracle.exe q t [--low <low>] [--high <high>] --key <key>
```

This command has the following flags:

* **`--low`**, **`-l`** `<low>`

  Lower time bound.
* **`--high`**, **`-h`** `<high>`

  Upper time bound.
* **`--key`**, **`-k`** `<key>`

  Key to search the value for.
* **`--skip`**, **`-s`** *`<n>`*

  Skip the first *\<n>* items.
* **`--take`**, **`-t`** *`<n>`*

  Take only the first items (after the skip if there is one).
* **`--count`**, **`-c`**

  Return the total amount of items satisfying the query.

It will provide you information about all the values committed by the server for the given keys within the given time bounds.

If no key is provided it will provide information about all the values within the time bounds regardless of keys.

If no time bounds are provided it will provide information about all the values committed by the server for the given keys, regardless of time bounds.

### Audit Path

To get an audit path in the Merkle tree of a committed data set use the command:

```bash
zen-oracle.exe audit [--commit <commit>] [--root <root>] [--stdin] [<item>]
```

or the shorthand

```bash
zen-oracle.exe p [--commit <commit>] [--root <root>] [--stdin] [<item>]
```

This command has a parameter `<item>` and the following flags:

* **`--commit`**, **`-c`** `<commit>`

  Commit hash.
* **`--root`**, **`-r`** `<root>`

  Root hash.
* **`--stdin`**, **`-i`**

  When this flag is used - get item's JSON string from standard input.

For the  parameter use the name of a JSON file which contains items for which you want to get audit paths in the given commit.

The JSON file should be a record with names and values, like this:

```bash
{ "APPL" : 10 , "ABCD" : 12 , "WXYZ" : 123 , "XYXY" : 6456 }
```

### Server

To run the server use the command:

```bash
zen-oracle.exe server
```

or the shorthand

```bash
zen-oracle.exe s
```

The server will run on a port specified with the `zen_api` environment variable.

### Database Structure&#x20;

The `server` command supports the following flags:

#### Collections

* `--bind`, `-b` `<address>`&#x20;

  API port
* `--chain`, **`-c`** `<chain>`&#x20;

  Node chain
* `--origin`, `-o` `<origin>`&#x20;

  CORS origin
* `--maxtake`, `-l` *`<n>`*&#x20;

  Maximum size of take (default: `1000`)
* `--maxbodysize`, `-s` *`<n>`*&#x20;

  Maximum size of body for the `getValues` endpoint (default: `1000`)

The oracle service uses the following MongoDB collections, within the `oracle` database:

#### `Commits`

The commits the server have made, sorted by `commitId`.

fields:

* `commitId` - commit ID of the commit
* `timestamp` - (in milliseconds since the Unix epoch - 00:00:00 UTC on 1 January 1970)
* `root` - hash of the root of the committed Merkle tree
* `items` - list of committed items

#### `Items`

The committed items, sorted by `name`.

fields:

* `name` - name of the item
* `root` - hash of the root of the Merkle tree this item was committed in
* `commitId` - commit ID of the commit
* `timestamp` - (in milliseconds since the Unix epoch - 00:00:00 UTC on 1 January 1970)
* `item` - serialization of item
* `proof` - proof of inclusion of the item in the committed Merkle tree, which contains:
  * `index` - index of the item in the Merkle tree
  * `path` - audit path of the item in the Merkle tree

#### `TimeCommits`

The commits (given by root and commit ID) sorted by `timestamp`.

This collection purpose is to make fast querying by timestamp.

fields:

* `timestamp` - (in milliseconds since the Unix epoch - 00:00:00 UTC on 1 January 1970)
* `root` - hash of the root of the committed Merkle tree
* `commitId` - commit ID of the commit

#### `PublicKey`

The public key of the oracle in the blockchain.

fields:

* `pk` - the public key of the oracle in the blockchain

For the api follow the link here.

{% content-ref url="/pages/-MRFuMv7UCMKrpDG8AAH" %}
[Oracle's API](/apps/oracle/oracles-api)
{% endcontent-ref %}


# Oracle's API

## Attest with Commit

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:8585/attest`

Request an attestation message body

#### Query Parameters

| Name    | Type   | Description                                                                        |
| ------- | ------ | ---------------------------------------------------------------------------------- |
| commit  | string | Commit ID of the committed data                                                    |
| cid     | string | ContractId of the recipient address                                                |
| pk      | string | Public key of the recipient address                                                |
| address | String | Address of the recipient (either a contract address or a public key hash address). |

{% tabs %}
{% tab title="200 Commit found" %}

```
{
    "root": "3e47241505bca37f3356fd8dda544c2a3c9c043601f147ea0c6da1362c85a472",
    "timestamp": "1600785099516",
    "commit": "2d1719fa333e615636dc074cb6ad03813a57c56cd91b73bffd7c12dd62fdb0d3",
    "tx": "No TX",
    "messageBody": "{\n  \"dict\": [\n    [\n      \"Commit\",\n      {\n        \"hash\": \"2d1719fa333e615636dc074cb6ad03813a57c56cd91b73bffd7c12dd62fdb0d3\"\n      }\n    ],\n    [\n      \"OraclePubKey\",\n      {\n        \"pk\": \"02ad784974b3f86ad97e008e20d2c107429041ed2d991ada2a1461b5077c11944c\"\n      }\n    ]\n  ]\n}",
    "messageBodyEncoded": "0c0206436f6d6d6974072d1719fa333e615636dc074cb6ad03813a57c56cd91b73bffd7c12dd62fdb0d30c4f7261636c655075624b65790a02ad784974b3f86ad97e008e20d2c107429041ed2d991ada2a1461b5077c11944c"
}
`
```

{% endtab %}
{% endtabs %}

## Attest with Root and Timestamp

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:8585/attest`

Request an attestation message body

#### Query Parameters

| Name      | Type   | Description                                                                        |
| --------- | ------ | ---------------------------------------------------------------------------------- |
| root      | string | Root of the Merkle Tree                                                            |
| timestamp | string | Time of the committed data (in millisecond in epoch format)                        |
| cid       | string | Contract ID of the recipient address                                               |
| pk        | string | ContractId of the Recipient address                                                |
| address   | String | Address of the recipient (either a contract address or a public key hash address). |

{% tabs %}
{% tab title="200 " %}

```
{
    "root": "3e47241505bca37f3356fd8dda544c2a3c9c043601f147ea0c6da1362c85a472",
    "timestamp": "1600785099516",
    "commit": "2d1719fa333e615636dc074cb6ad03813a57c56cd91b73bffd7c12dd62fdb0d3",
    "tx": "No TX",
    "messageBody": "{\n  \"dict\": [\n    [\n      \"Commit\",\n      {\n        \"hash\": \"2d1719fa333e615636dc074cb6ad03813a57c56cd91b73bffd7c12dd62fdb0d3\"\n      }\n    ],\n    [\n      \"OraclePubKey\",\n      {\n        \"pk\": \"02ad784974b3f86ad97e008e20d2c107429041ed2d991ada2a1461b5077c11944c\"\n      }\n    ]\n  ]\n}",
    "messageBodyEncoded": "0c0206436f6d6d6974072d1719fa333e615636dc074cb6ad03813a57c56cd91b73bffd7c12dd62fdb0d30c4f7261636c655075624b65790a02ad784974b3f86ad97e008e20d2c107429041ed2d991ada2a1461b5077c11944c"
}
`
```

{% endtab %}
{% endtabs %}

## Query the Oracle

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:8585/query`

Filter the commited data to find the commitment.

#### Query Parameters

| Name                                   | Type   | Description                                                         |
| -------------------------------------- | ------ | ------------------------------------------------------------------- |
| high                                   | string | filter the data with the higher timestamp bond                      |
| low                                    | string | Filter the data with the lower timestamp bond                       |
| key                                    | string | Filter by this ticker                                               |
| take<mark style="color:red;">\*</mark> | String | Take only the first  *\<n>* items (after the skip if there is one). |
| skip                                   | String | Skip the first *\<n>* items.                                        |

{% tabs %}
{% tab title="200 " %}

```
[{
    "item": {
        "APPL": "10"
    },
    "timestamp": "1600785099516",
    "commit": "2d1719fa333e615636dc074cb6ad03813a57c56cd91b73bffd7c12dd62fdb0d3",
    "hash": "0ecb254e1ff36f9b6a09f35926041a01a955171a29d8500775fb58a0acbff54c"
}]
```

{% endtab %}
{% endtabs %}

## Count commits

<mark style="color:blue;">`GET`</mark> `http://127.0.0.1:8585/count/`&#x20;

Count the number of items committed by the service.

#### Query Parameters

| Name | Type   | Description                                    |
| ---- | ------ | ---------------------------------------------- |
| high | String | filter the data with the higher timestamp bond |
| low  | String | Filter the data with the lower timestamp bond  |
| key  | String | Filter by this ticker                          |

{% tabs %}
{% tab title="200: OK " %}

```javascript
{
    // Response
}
```

{% endtab %}
{% endtabs %}

## Get the values&#x20;

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:8585/getValues` &#x20;

#### Query Parameters

| Name | Type   | Description                                    |
| ---- | ------ | ---------------------------------------------- |
| key  | String | Filter by this ticker                          |
| high | String | filter the data with the higher timestamp bond |
| low  | String | Filter the data with the lower timestamp bond  |

{% tabs %}
{% tab title="200: OK " %}

```javascript
{
    // Response
}
```

{% endtab %}
{% endtabs %}


# Deploy

### Via Systemd

{% content-ref url="/pages/-MRFAP\_Mas\_kFYQjXvZb" %}
[Systemd](/apps/oracle/deploy/deployment-on-ubuntu)
{% endcontent-ref %}

### Via Docker

{% content-ref url="/pages/G3HQIag6IPLwohsXHtlw" %}
[Docker](/apps/oracle/deploy/docker)
{% endcontent-ref %}


# Systemd

{% hint style="warning" %}
&#x20;This document assumes `/home/ubuntu` is the server user home directory, make sure to change it to fit the directory of your choice.
{% endhint %}

Prerequisites:

* Install [Git](https://www.atlassian.com/git/tutorials/install-git?linuxc#linux) to clone the zen-oracle repository
* Install [mono-devel](http://www.mono-project.com/download). If you choose to install via a package manager, add Mono's own repository first.
* Install the Headless Node and import a funded account
* Cron **(Optional)**
* Install [MongoDB](https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/)

## Oracle Service File&#x20;

#### `Save it in path: /etc/systemd/system/zen-oracle.service`

```bash
[Unit]
Description=Oracle
After=network.target

[Service]
Type=simple
EnvironmentFile=/home/ubuntu/services/scripts/env
WorkingDirectory=/home/ubuntu/services/zen-oracle/src/Oracle/bin/Release
ExecStart=/usr/bin/mono /home/ubuntu/services/zen-oracle/src/Oracle/bin/Release/zen-oracle.exe s
Restart=on-failure

[Install]
WantedBy=multi-user.target
```

## Oracle Service

1. Get the oracle service (from GitLab)

   ```bash
    mkdir /home/ubuntu/services
    cd /home/ubuntu/services
    git clone https://gitlab.com/zenprotocol/zen-oracle.git
   ```
2. Build the oracle service

   ```bash
    cd /home/ubuntu/services/zen-oracle
    ./paket restore
    msbuild src/zen-oracle.sln /p:Configuration=Release
   ```
3. Create `/etc/systemd/system/zen-oracle.service` service file as mentioned above
4. Put all the environment variables assignments in the file `/home/ubuntu/services/scripts/env`
5. Follow node deployment instructions and be sure to have the zen-node service enabled
6. Enable Zen-Oracle

   ```bash
   sudo systemctl enable zen-oracle
   ```
7. Start MongoDB

   ```bash
    sudo systemctl start mongodb
   ```
8. Start Zen-Oracle Server

   ```bash
   sudo systemctl start zen-oracle
   ```

## Execution Scripts

1. Make sure all the environment variables are provided and correct
   * zen\_path : path of the oracle committer
   * zen\_wallet\_password: password of the F# wallet
   * zen\_node\_uri: uri of the node
   * oracle\_api: `uri:port` api port for oracle requests

## Cron job

* In order to commit at a precise time we suggest to use a script in a cron job to take care of the commitment.


# Docker

#### Docker File

```
FROM mono

ENV zen_path=""
ENV zen_wallet_password=""
ENV zen_node_uri=""
ENV oracle_api=""
ENV mongo_connection=""

EXPOSE 5050

RUN apt-get update && apt-get install -y apt-utils procps iptables git
RUN mkdir services

WORKDIR services

RUN git clone https://gitlab.com/zenprotocol/zen-oracle.git
WORKDIR zen-oracle
RUN ./paket restore
RUN msbuild src/zen-oracle.sln /p:Configuration=Release -m
```


# How the Oracle contract works

## Verify/Build

To verify/record hints, run `zebra e Oracle.fst`.

The elaborated source file will be created in the `output` directory.

To build, run `zebra c Oracle.fst`.

Both the elaborated source file and the compiled binary (`.dll`) file will be created in the `output` directory.

## How it works

The *oracle contract* allows a *data provider* to make a *commitment* (with the `"Commit"` command) in the form of a hash, which will be recorded on the blockchain, and can provide *attestation* tokens (with the `"Attest"` command) to prove that a commitment was recorded on the blockchain.

The *commitment token* is minted by the *contract using a signed transaction (the contract witness is signed by the data provider)* and is derived from the committed hash and the *public key* of the *provider* who sent the data.

The *token* is then locked to the *oracle contract* and stays in the possession of the *contract* indefinitely.

Whenever a proof of a commitment is needed, an attestation token can be minted (with the `"Attest"` command) by providing the committed hash and the *public key* of the *data provider*, from which the *contract* derives once again a *commitment token* which is taken from the *contract wallet* and then locked back to the *contract*, then mints from the same data an *attestation token* which is sent to the *recipient* specified by the *sender*.

Since the *contract* tries to take the *commitment token* from its *wallet* and lock it to itself - the only way for the *attestation transaction* to be valid is if the *contract* has the *commitment token* to begin with (otherwise it would create an invalid execution), meaning that the data provider must have first executed the contract with the `"Commit"` command.

## Usage

The Oracle contract has 2 commands:

1. `"Commit"`
2. `"Attest"`

### `"Commit"`

To commit a hash execute the Oracle contract with the `"Commit"` command and provide the hash in the message body as a dictionary with the field name `"Commit"`. **Note:** The transaction must be signed, the provider who executed this command **must authenticate the transaction**.

| Field Name | Type   | Description        |
| ---------- | ------ | ------------------ |
| `"Commit"` | `hash` | The committed hash |

The contract will then take the *public key* of the *provider*, concatenate it to the provided hash, mint a *commitment token* from the hash of the concatenation, and lock it to itself.

```
                       commitment token = [[ Commit ; public key ]]
Contract |------------------------------------------------------------> Contract
```

From now on the contract will hold the *commitment token* indefinitely.

### `"Attest"`

To ask for an *attestation* on a committed hash by a specific *provider* execute the contract with the `"Attest"` command and provide a message body as a dictionary with the following data:

| Field Name       | Type        | Description                                 |
| ---------------- | ----------- | ------------------------------------------- |
| `"Commit"`       | `hash`      | The committed hash                          |
| `"OraclePubKey"` | `publicKey` | The public key of the provider              |
| `"Recipient"`    | `lock`      | The recipient lock of the attestation token |

To ensure that the specified hash was indeed committed the contract will take the *public key* of the *provider*, concatenate it to the provided hash, look up in its *wallet* for a *commitment token* derived from the hash of the concatenation, and lock it to itself.

The contract will also take the **double hash** (the hash of the hash) of the concatenation, mint an *attestation token* out of it, and lock it to the *recipient* - this will provide the *recipient* with a concrete and exchangeable evidence that the specified hash was indeed committed to.

```
                       commitment token = [[ Commit ; public key ]]
Contract ------------------------------------------------------------> Contract

                       attestation token = [[[ Commit ; public key ]]]
Contract |------------------------------------------------------------> Recipient
```

## Generated Assets

### Commitment Token

```
[[ hash ; oraclePublicKey ]]
```

### Attestation Token

```
[[[ hash ; oraclePublicKey ]]]
```


# How to create an Attestation token

In order to create an Attestation token the contract needs to be executed with the command "Attest" and the message body according to the rule.

| Key          | Value   | Type       |
| ------------ | ------- | ---------- |
| OraclePubKey | !pk     | public key |
| Recipient    | address | string     |
| Commit       | hash    | string     |

## Step by step Guide

* Open your Zen Wallet and go to the 'Send' page under 'My Wallet' tab and click the 'Paste' button
* Add the command "Attest"
* Add OraclePubKey, Recipient and Commit in the message body field
* Click the 'Execute' button to continue
* &#x20;Review your "Execution Summary" and click 'Continue'
* Enter your password to sign the transaction and click 'Continue
* Confirm your contract execution transaction and click ‘Publish’
* After publishing your transaction a success message will appear

View your transaction on the ‘Transaction History’ page. You might first see the transaction on pending status till it will get its first confirmation.


# Dex

### Dex User Guide <a href="#messagebody-generator" id="messagebody-generator"></a>

{% content-ref url="/pages/-MRtck5gVWzv8CYXa7\_t" %}
[Dex User Guide](/apps/dex/dex-user-guide)
{% endcontent-ref %}

### How it works? <a href="#how-it-works" id="how-it-works"></a>

{% content-ref url="/pages/-MRPJiU\_V4VnVUsacbqe" %}
[How DEX contract works](/apps/dex/how-it-works)
{% endcontent-ref %}

​<br>


# Dex User Guide

{% hint style="success" %}
Available at <https://dex.zp.io>
{% endhint %}

ZenDex is a true and user-friendly decentralized exchange enables token holder to securely execute p2p orders on-chain (Zen Protocol network), with no operators or fees. ZenDex stores orders as UTXOs that locks to itself.

In order to execute transactions on the ZenDex, a wallet must be connected. If a wallet is not connected you will be able to view all traded pairs or search for a specific one.

Here you can learn about the basic features and different aspects of the ZenDex application.

{% content-ref url="/pages/-Mj9578D80vfyobtIvyb" %}
[Traded Pairs](/apps/dex/dex-user-guide/traded-pairs)
{% endcontent-ref %}

{% content-ref url="/pages/-Mj95AAIHVjnWKWIGX4n" %}
[Search Pairs](/apps/dex/dex-user-guide/search-pairs)
{% endcontent-ref %}

{% content-ref url="/pages/-Mj95DYg5Ta9GZmviwRw" %}
[Order Book](/apps/dex/dex-user-guide/order-book)
{% endcontent-ref %}

{% content-ref url="/pages/-Mj95I5Jw49uWr8IP0ji" %}
[Operations](/apps/dex/dex-user-guide/operations)
{% endcontent-ref %}

{% content-ref url="/pages/-Mj94y4hGyBo\_QnMJmJv" %}
[My Wallet](/apps/dex/dex-user-guide/my-wallet)
{% endcontent-ref %}

{% content-ref url="/pages/-Mj95S\_J3JhFCDN-8rik" %}
[Settings](/apps/dex/dex-user-guide/settings)
{% endcontent-ref %}


# Traded Pairs

This list represents all traded pairs sorted by total orders on the ZenDex platform.

{% hint style="info" %}
&#x20;This data is available to watch even if no wallet is connected.

The uniqueness of a pair is represented in lexicographic order based on the asset identifiers. This means for example pair A/B and pair B/A will be represented as pair A/B.

When the ZP asset is part of the pair, it will be used as the quote.
{% endhint %}

![](/files/-Mj96HiOfe9vwPSbodhE)


# Search Pairs

To view the orderbook of a specific pair you can use the search pair component that can be found in the traded pairs and orderbook page.

![](/files/-Mj97KnZ0_P5Fi1BG_I9)

## Step By Step Guide

1. Enter *base* asset identifier.
2. Enter *quote* asset identifier.
3. Click the switch icon to invert the order of the base and quote assets, if needed.
4. Click on the search button to view the assets market.
5. To re-open the search bar click the pairs you are currently viewing.

![](/files/-Mj97Z39H7gh5IAcmuM9)


# Order Book

The order book represents all the available orders to buy or sell asset of a specific market.

{% hint style="info" %}
&#x20;In the form you will be able to interact with the order book as long as a wallet is connected.
{% endhint %}

![](/files/-Mj97wd9Fp8gb7CMlskD)

## Take an order

Step By Step Guide

1. Click the 'Take' button next to the order you wish to take.

{% hint style="info" %}
In mobile click on the order row to start the take process.
{% endhint %}

![](/files/-Mj97wd0BfdxYptYY-FL)

&#x20; 2\. Choose how much of that order you wish to take and click 'Continue'.

![](/files/-Mj97wd1faWAdhAFuy_f)

When a partial order is taken, a new order (less the amount that was taken) will be propagated.

* Confirm your 'Take' order by reviewing the order summary and click ' Continue'.
* Note that the order quantity or total price will be adjusted according to the contract rules:
* The DEX contract always favorites the maker of the order.
* The minimum price of an order is 1 Kalapa.
* The amount of an asset can not be smaller than 1 Kalapa.

![](/files/-Mj97wd22UWvjL6Bp-Aq)

3\. Enter your password and click 'Take Order' button to execute your order.

![](/files/-Mj97wd3FQ5WF6itvrMo)

## Create a buy/sell order

Step By Step Guide

1. Choose between the buy or sell tab.

![](/files/-Mj97wd4a2sfJ8Rhiolo)

2\. Fill in the form with the desired values.

After you enter 2 of the values the 3rd will be automatically computed:

* Enter p**rice per unit** and **quantity** and the *total price* will be automatically computed.
* Enter **quantity** and **total price** and the *price per unit* will be automatically computed.
* Enter **price per unit** and **total price** and the *quantity* will be automatically computed.

3\. Click on the Make Buy/Sell Order button to continue.

4\. Confirm your 'Make' order by reviewing the order summary and click 'Continue'.

* Note that the order quantity or total price will be adjusted according to the contract rules:
* The DEX contract always favorites the maker of the order.
* The minimum price of an order is 1 Kalapa.
* The amount of an asset can not be smaller than 1 Kalapa.

![](/files/-Mj97wd552KNZGToCUkT)

5\. Enter your password to continue.

![](/files/-Mj97wd6CPi574SDLQl5)

6\. Verify your 'Make' order was successfully propagated and check up on its status.

![](/files/-Mj97wd7leQN--O69dN2)

Once your order is created it will appear as 'Pending' on the pair's order book until the transaction is added to a block, only then will it be available for trade.

## Verify your order was successfully propagated and check up on its status.

When you publish a new order a 'Pending' indication will appear in your Operations tab until it gets its first confirmation (added to a block).

![](/files/-Mj97wd86WK233xp3yoR)


# Operations

This list aggregates your operations in the Zen Protocol Network: all your orders and the wallet's transactions

Click the 'Operations' tab in the main navigation bar.

![](/files/-Mj9AvYws8QoBR6-rSNf)

* **Pair/Asset :** The pair **r**epresents the asset identifier (A) and a quote asset identifier (B) ⇒ A/B if a single asset is shown the corrisponding row represent a wallet transaction.
* **Tx Hash:** A unique identifier of any transaction recorded on the Zen Protocol networ&#x6B;**.** Clicking on the TX Hash will redirect to the transaction page in the Block Explorer.
* **Type:** Quickly *\*\**&#x69;dentify the type of any operation.
* **Status:** Indicates the status of each operation.

  The status ‘Pending’ indicates that a transaction has yet to be added to a block.

## Order informations

To get more information about an order in the table, click the arrow to view the expanded mode.

![](/files/-Mj9LhebeQ8IBjQP3oi-)

## Cancelling an order

![](/files/-Mj9Lph2-icgvJEIpu9x)

Only your open orders can be canceled.

Step By Step Guide

1\. Go the 'Operations' tab in the main navigation.

2\. Click the 'Cancel' button next to the open order you wish to permanently remove from the ZenDex order book.

3\. Verify cancelling your open order and click 'Continue'.

![](/files/-Mj9LzMH9Ab08th7R9tX)

4.Enter your password to execute the transaction and click 'Cancel Order'.

![](/files/-Mj9MI2iR9ipjaN3UHiC)

5\. Once your order is canceled a 'Pending' indication will appear until it gets its first confirmation (added to a block).


# My Wallet

{% content-ref url="/pages/-MRtNFcKq2CaNhXXnlRs" %}
[Connect a Wallet](/apps/wallet/wallet-structure/onboarding)
{% endcontent-ref %}

## Balances

View the ‘Balances’ page to see a full list of your assets and their amount stored in your account.

Assets which were generated by the [Fixed Payout Contract](/apps/fixed-payout) can be redeemed or destroyed according to the event data.

![](/files/-Mj9Pqlc3-_nt-ClHkS4)

Column Descriptions:

* Asset: Asset identifier or asset name.
* Contract of : indicates which contract generated the asset.
* Worth column: indicates the collateralized value.
* Actions: only after the oracle commited on the position asset event, an exercise button will be available in order to redeem or destroy the asset.

![](/files/-Mj9PyT8lXeSUdTsX2rX)

**Exercise Redeem**

In order to redeem your asset, click the exercise button to execute the FPC.

{% hint style="info" %}
&#x20;When the asset match the winning position, the worth data will be represented in green.
{% endhint %}

1\) Choose the amount you wish to redeem and click the "Execute" button.

![](/files/-Mj9Q6fWp1UH-MT1iyJE)

2\) Review the FPC execution summary.

![](/files/-Mj9QvXOswD5dxBXe7JM)

3\) Enter your password to continue.

![](/files/-Mj9Qxqa7AUwLQdOWrlE)

4\) Confirm execution before publishing and click the "Publish" button.

![](/files/-Mj9R-D6f0ILa5DSIGFN)

**Exercise Destroy**

In order to destroy your asset, click the exercise button to execute the FPC.

{% hint style="info" %}
When the asset does not match the winning position, the worth data will be represented in red.
{% endhint %}

1\) Check the information of the asset that will be destroyed and click the "Destroy" button.

![](/files/-Mj9R8Erri-jjuKIGqBT)

2\) Enter your password to continue.

![](/files/-Mj9RBDC6RU_yRJKi8cF)

3\) Confirm execution before publishing and click the "Publish" button.

![](/files/-Mj9RE79SBB3N0AUg21R)

Verify  'Exercise' (Redeem/Destroy) transaction was successfully propagated and check up on its status.

When you publish a new transaction a 'Pending' indication will appear in your Operations tab until it gets its first confirmation (added to a block).

### Deposit

Use your main address to receive ZP token or any other compatible tokens to your wallet.

**Step 1:** Go to the ‘deposit’ tab under “My wallet” in the top up navigation bar.

**Step 2**: Copy your public address and send it to the sender.

![](/files/-Mj9RITyiE6wa8qsr3qx)

* Receive using your QR code
  * If the Sender uses a mobile app, he can quickly scan the QR code to get the recipient address.
  * Click on the QR code to expand it.

### Withdraw

Use the withdraw form in order to send ZP token or any other compatible token to a valid address.

![](/files/-Mj9ROgr0YP50ChAW9vC)

**Step 1**: Go to the’ Withdraw’ tab under “My wallet” in the top up navigation bar.

**Step 2:** Enter a valid destination address.

**Step 3:** Choose the asset you want to send using the drop down assets list. The list is constructed of your portfolio’s assets.

**Step 4:** Enter the amount you would like to send (note the amount will be converted to Kalapas).

**Step 5:** Click the ‘Send’ button to create your transaction.

**Step 6:** Verify your transaction by reviewing the transaction summary.

![](/files/-Mj9RSOYeT6FNlVS4m9H)

**Step 7**: Enter your password to continue.

![](/files/-Mj9RXx0hVafVX2H8QRk)

**Step 8:** Confirm transaction by clicking the ‘Publish’ button and when the process is complete a successful message will appear.

![](/files/-Mj9RcD0ZD4QBA2amXpv)

* You can NOT cancel a transaction after publishing it.

## Send multiple assets

If you wish to send more than one asset to one recipient address, then click ‘Add asset & Amount’.

## Sending using QR code

Filling the destination address is also possible by scanning a QR code with an encoded address. The QR code will be found in the ‘Deposit’ page of the recipient wallet account, under ‘My Wallet’.

## Verify your transaction was successfully propagated and check up on it’s status

Check your Transaction in the Operations page, there you will be able to see the status of your transaction. The transaction will be indicted as ‘pending’ till it gets its first confirmation. Only after the first confirmation you will be able to see it in the Block Explorer.


# Settings

To control your account settings and in order to reset the ZenDex database click the 'Settings’ icon on the top right corner of your screen. (on mobile, it will be found in the side menu).

![](/files/-Mj9S9KI6f829F-28teO)

### Account Settings

Under ‘Account Setting’ tab you will be able to configure your wallet settings.

**Auto logout**

Enter the number of minutes to set the inactivity timeout. After this time you will need to login again&#x20;

![](https://lh3.googleusercontent.com/MG13VGvH_RMJg1egR3LtLTw00ChNcPkbRdlO7FzqwyKlhpq0H1AK55NEIFVtTZsjgSMcx-sPXGQuH3iN1mo5VrDFPL6GXycQ3atEMKCmIZBnZiKtKxsv32R8Kd4S2i8BrWb3vlsU)

**Login Password**

**Step 1**: Click the “Change’ button to change your current password to a different one.

![](https://lh6.googleusercontent.com/pi3-zcfFOL_4_jn5RBCmgCoioJZ2y-WRmXl13zhz8BQ_Ke7surjbLVdX5RGP8xylhGn5A7xrxJxG0k_0DoBm9dm6LHJU8bTusfOKoDdfRNOaux5ww8-sHqLT1vSKrlpV_Atpxh9j)

**Step 2**: Enter a new secure password and click ‘Save Changes’

* When changing your password remember to:

**Step 3**: Choose password

![](https://lh5.googleusercontent.com/vCTvTpUxIU1_6YvkOJYrlWE8jb0REKEUhXrFnpxzrNwXYCFJ8i6VwA4Zxlz3eIwl73o8tlKs8qqPh7JHLM4bpQLoVRkIIwU0wpJ14d8tCzxt1hQGySROB29pIODtpwtyYpKpOBoZ)

**Backup Wallet**

{% hint style="warning" %}
Security notice

Showing your mnemonic phrase on a digital platform can put your funds at risk. Make sure the device you are using is secured.&#x20;
{% endhint %}

Under the backup wallet dialog you will be able to view your wallet’s private info by providing the wallet password:

**Step 1**: Click the ‘Show’’ button to view your wallet’s private info.

![](https://lh3.googleusercontent.com/-iENCM5p14KpNOKuPINTHR-I7V50EtS0s90Q4QVF-FBt1DetcQ_JuQjRhtqkeR_zbM-4qMl7FYnOLck-ee1UdMuVBJ7ZaB7tqfO-AHGr7nQIoqgQ1yKB4g0bbycnbuDGv6A4Lfnd)

**Step 2**: Read the security warning and confirm to continue.

![](https://lh4.googleusercontent.com/PTeYaqvYVQ3u5xNhZmLjYAZN0QKjgQ907uUw-1PmUho2nz4BBuJgBX4bFsPBr65dy2SRvYGrnuiuIvfUG6TzN4XjqXvMpQVOqje-ECJ9oAyhFVYkEst0SG-esWm616hBrV3hyr0Z)

**Step 3**: Enter your password to continue.

**Step 4**: View your private infos

* **PK hash:** The decoded address used to lock the UTXO to
* **XPUB KEY**:  Public key of the main account derived from the mnemonic phrase
* **Menominic**: A valid BIP39 24 words phrase used to derive public and private keys
* **XPRIV KEY**: Private key of the main account derived from the mnemonic phrase

![](https://lh5.googleusercontent.com/FhiHlj_Js9V1o6yXNnV_5VYKZiQIULMDVwkzqQYHWUoGyXg57mgyEYaSf9j81a4Ed3Fq23ff5RG0X-YM39aitDQP9yVS6BGif3lIcs_t-_o5BzE0PuzxTCV6Bu06ur72XVHB1WhV)

**Wipe Wallet**&#x20;

Wipe the wallet secured mnemonic to import a new one.

**Step 1**: Click the “Wipe’ button to delete your wallet

![](https://lh6.googleusercontent.com/hg5neqFP3MyHM_96PXYwsA2SfVUdZV2atCZR-Q3jnk8aI5pszVeKS1PqXyZocgAGO9i2fO8_3SF-hnI8Uev4LUCiBdeyPIIigKtLJ5Szx45fTfKtXBlD9KXRynH0M8Fls9jjDrKC)

**Step 2**: Choose between:

* &#x20;‘Wipe’ in order to erase your wallet
  1. Provide the wallet password to continue
* &#x20; “Backup Wallet’
  1. Provide the wallet password to see your wallet’s private info.
  2. Confirm deleting your wallet  by clicking the ‘Wipe’ button.

![](https://lh5.googleusercontent.com/bDPiKTGBBF-vUIZg6fTE3j5R9GC7fwOb3FcIt-RP4K_rOIgVimDdqiMp3BYqvhXM_jqzMbUU_4XD2ft64BKaw19qXANwwx_iX5teAAvXa9HL_B-gMdMzq_DBHVp30I2lgRn5zIpw)

## Database

**Delete Storage**

The desktop version uses a local database to create the orderbook, in the event of loading issue you can erase the ZenDex Database and it will be rebuilt.

![](/files/-Mj9S42SDLthdXKM4xYd)


# How DEX contract works

ZenDex is a true decentralised exchange, with no operator or fees.

ZenDex stores orders as utxos that it locks to itself. In this manner, we avoid having a shared state, allowing great parallelism.

When an order is made, the order parameters are hashed together. ZenDex mints a single token with that hash as it’s sub-identifier (the ‘*order asset*’), and locks that to itself.

When an order is taken or cancelled, that token is destroyed. In the case of a partial fill, ZenDex will create a new order with reduced quantities of the underlying and order total. The previous order is still destroyed.

When cancelling or taking an order, one must supply all of the order parameters directly to ZenDex in the messageBody, because ZenDex does not store this information, and only possesses a hash of the order.

Order books can be constructed by folding over the blockchain, and looking for transactions involving ZenDex.

### Usage

ZenDex accepts three commands: `"Make"`, `"Cancel"`, and `"Take"`.

#### Making an order

Use the command `"Make"`. You must sign with a public key - if the sender is `Anonymous` or `Contract contractID`, then the transaction will fail.

The messageBody must consist of a dictionary which includes the following fields:

|      Field Name      |     Type    | Description                                               |
| :------------------: | :---------: | --------------------------------------------------------- |
|  `"UnderlyingAsset"` |   `String`  | The identifier of the underlying asset                    |
| `"UnderlyingAmount"` |   `UInt64`  | The amount of the underlying asset used to make the order |
|     `"PairAsset"`    |   `String`  | The identifier of the pair asset                          |
|    `"OrderTotal"`    |   `UInt64`  | The total amount of the pair being ordered                |
|    `"MakerPubKey"`   | `PublicKey` | The public key of the order maker                         |

The amount of the underlying made available to ZenDex in the transaction must be equal to `"UnderlyingAmount"`. The public key used to sign the transaction must be the same as `"MakerPubKey"`.

#### Cancelling an order

Use the command `"Cancel"`. You must sign with the public key that was used to create the order.

The messageBody must consist of a dictionary which includes the following fields:

|      Field Name      |     Type    | Description                                               |
| :------------------: | :---------: | --------------------------------------------------------- |
|  `"UnderlyingAsset"` |   `String`  | The identifier of the underlying asset of the order       |
| `"UnderlyingAmount"` |   `UInt64`  | The amount of the underlying asset used to make the order |
|     `"PairAsset"`    |   `String`  | The identifier of the pair asset in the order             |
|    `"OrderTotal"`    |   `UInt64`  | The total amount of the pair that was ordered             |
|    `"MakerPubKey"`   | `PublicKey` | The public key of the order maker                         |

The transaction must place the order asset in ZenDex’s contract wallet, as well as a sufficient quantity of the underlying.

#### Taking an order

Use the command `"Take"`.

The messageBody must consist of a dictionary which includes the following fields:

|      Field Name      |     Type    | Description                                                            |
| :------------------: | :---------: | ---------------------------------------------------------------------- |
|  `"UnderlyingAsset"` |   `String`  | The identifier of the underlying asset of the order                    |
| `"UnderlyingAmount"` |   `UInt64`  | The amount of the underlying asset used to make the order              |
|     `"PairAsset"`    |   `String`  | The identifier of the pair asset in the order                          |
|    `"OrderTotal"`    |   `UInt64`  | The total amount of the pair that was ordered in the order being taken |
|    `"MakerPubKey"`   | `PublicKey` | The public key of the order maker                                      |
|  `"RequestedPayout"` |   `UInt64`  | The amount of the underlying to pay out                                |
|  `"ProvidedAmount"`  |   `UInt64`  | The amount of the pair supplied                                        |

The transaction must place the order asset being taken and a sufficient amount of the underlying in ZenDex’s contract wallet, and must lock an amount α of the order’s pair asset to the contract, where &#x20;

![](/files/-MRPMG7sz4Mw68id22tn)

### Notes

Orders are expressed in terms of underlying amount and pair amount to allow for rational price ratios - eg. a trade of 5α for 7β, or 13β for 11γ. This is not easily expressed as a ‘price per’ with only integer arithmetic. The payout for a partial fill should, assuming arbitrarily divisible assets, be calculated as &#x20;

![](/files/-MRPMG7sz4Mw68id22tn)

However, since we do not have arbitrarily divisible assets, we denote orders in the smallest unit of each asset and compute the floor, so that

![](/files/-MRPMg9Aa591_lN9FK7F)

The underlying amount, order total, and payment amount are all 64 bit unsigned integers. Version 0 ZF\* contracts lack integer representations larger than this, and so we are tasked with implementing double-word arithmetic in order to calculate the payoff. In order to avoid the complexity and potential for error in implementing double-word division, we instead ask the user to provide the payoff, and validate that it is correct. Validating that a user’s `RequestedPayout` is correct is simpler than computing the payout, and requires only double-word multiplication and comparison, both relatively simple compared to double-word division.

Note that

![](/files/-MRPMrv8plYLrAq5AbgK)

## Generated Assets

### Order Token

Each parameter is hashed separately and then aggregated to a single hash with `updateHash`

```fsharp
[[ [[ underlyingAsset ]] ; [[ underlyingAmount ]] ; [[ pairAsset ]] ; [[ orderTotal ]] ; [[ makerPubKey ]] ]]
```


# Fixed Payout

### MessageBody Generator

{% content-ref url="/pages/-MRPNh4FFR6bCsUndVG0" %}
[Fixed Payout Generator User Guide](/apps/fixed-payout/fixed-payout-generator)
{% endcontent-ref %}

### How it works?

{% content-ref url="/pages/-MVMV6kL23d3-ppEPvpI" %}
[How the FP Contract works](/apps/fixed-payout/how-the-fp-contract-works)
{% endcontent-ref %}


# Fixed Payout Generator User Guide

&#x20;The FP Generator is a tool that assists token holders to generate a *Message Body* to be used while executing the FP contract with different commands.

{% hint style="success" %}
Available at <https://fp.zp.io/>
{% endhint %}

{% hint style="info" %}
Using the FP generator does not require connecting a wallet
{% endhint %}

**The Fix Payout Contract can be executed using 4 different commands.**

{% content-ref url="/pages/-Mj9\_7TsFl\_Ums6FEU\_S" %}
[Issue](/apps/fixed-payout/fixed-payout-generator/issue)
{% endcontent-ref %}

{% content-ref url="/pages/-Mj9c7\_sLNhXcjgDWbbn" %}
[Redeem](/apps/fixed-payout/fixed-payout-generator/redeem)
{% endcontent-ref %}

{% content-ref url="/pages/-Mj9eAHHsNLXkvc\_2Gxl" %}
[Cancel](/apps/fixed-payout/fixed-payout-generator/cancel)
{% endcontent-ref %}

{% content-ref url="/pages/-Mj9iCQtvapIIIW44iy6" %}
[Verify](/apps/fixed-payout/fixed-payout-generator/verify)
{% endcontent-ref %}

{% content-ref url="/pages/-Mj9iqmWmRkw108InvOD" %}
[Settings](/apps/fixed-payout/fixed-payout-generator/settings)
{% endcontent-ref %}


# Issue

In order to issue position tokens (Bull/Bear), the contract needs to be executed with the command "Issue" and the generated message body according to the *rule.* It must include authentication to sign your execution.

## Step by step Guide

* Go to the 'Issue' tab
* Enter a Collateral Asset and amount
* Choose a Ticker using the drop down menu
* Provide the Strike Price
* Provide the Expiry date
* Click the "Generate" button to continue

![](/files/-Mj9_c_t_WIHv1p6X6eU)

1\) Review your event data summary and click the 'Copy All' button

![](/files/-Mj9_rbNiD1420ZViql8)

2\) Open your Zen Wallet and go to the 'Send' page under 'My Wallet' tab and click the 'Paste' button. Pasting the data is also possible using the QR code. Scan the QR code to copy the generated data.

![](/files/-Mj9_w88bjp2a742vnR3)

3\) Click the 'Execute' button to continue

4\) Review your "Execution Summary" and click 'Continue'

![](/files/-Mj9a5Me8kR4ZhazR9a2)

5\) Enter your password to sign the transaction and click 'Continue'

![](/files/-Mj9a83FEdHZe_gn3iQg)

6\) Confirm your contract execution transaction and click ‘Publish’

![](/files/-Mj9bFi5dJO-30ST1xB8)

7\) After publishing your transaction a success message will appear.

{% hint style="info" %}
You can NOT cancel a transaction after publishing it.
{% endhint %}

View your transaction on the ‘Transaction History’ page. You might first see the transaction on pending status till it will get its first confirmation.

![](/files/-Mj9bLdwAkb3J_sOXn2_)


# Redeem

In order to redeem position tokens (Bull/Bear), the contract needs to be executed with the command "Redeem" and the generated message body according to the *rule.*

Note:: A position can be redeemed only after an oracle attest the issued event

## Step by Step Guide

1\) Go to the 'Redeem' page

2\) Enter your Asset ID (Bull/Bear)

3\) Enter the exact amount you wish to redeem

4\) Click  the "Generate" button

![](/files/-Mj9cRq2Q1VPKjRTDHp4)

5\) Review your redeem  summary and click the 'Copy' button

![](/files/-Mj9cVAfydDOm4miasfG)

6\) Open your Zen Wallet and go to the 'Send' page under 'My Wallet' tab and click the 'Paste' button. Pasting the data is also possible using the QR code. Scan the QR code to copy the generated data.

7\) Click the Execute button to continue

![](/files/-Mj9cf_LKQDOe3PZZ7x1)

8\) Review your "Execution Summary" and click 'Continue'

![](/files/-Mj9cmP0nf5U3ukxswSo)

9\) Enter your password to sign the transaction and click 'Continue'

![](/files/-Mj9cov0g4l-efC5QS5o)

10\) Confirm your contract execution transaction and click ‘Publish

![](/files/-Mj9crvHtHQEwyMt9tCL)

After publishing your transaction a success message will appear.

View your transaction on the ‘Transaction History’ page. You might first see the transaction on pending status till it will get its first confirmation.

![](/files/-Mj9curc7tCjOg_f6eQE)


# Cancel

In order to cancel position tokens (Bull/Bear), the contract needs to be executed with the command "Cancel" and the generated message body according to the *rule.* It must include authentication to sign your execution.

Canceling a position is only possible while holding the same amount of position tokens from the same event data.

## Step by step Guide

1\) Go to the 'Cancel' page&#x20;

2\) Fill in the form with the event data \
The amount of the Bull and Bear tokens is defined by the amount of Collateral asset you wish to send back to the contract.

![](/files/-Mj9hLrTr6pzGXbsu7bF)

3\) Click the "Generate" button to continue

4\) Verify your cancel data summary and click the 'Copy all' button

![](/files/-Mj9hPR7eVQQDD2QvnG-)

5\) Open your Zen Wallet and go to the 'Send' page under 'My Wallet' tab and click the 'Paste' button. Pasting the data is also possible using the QR code. Scan the QR code to copy the generated data.

![](/files/-Mj9hUm-u0LwTTW-D1I3)

6\) Click the 'Execute' button to continue

![](/files/-Mj9h_2RNXixiPCcSRzz)

7\) Review your "Execution Summary" and click 'Continue'

![](/files/-Mj9hdB53cJiVghvdIvt)

8\) Enter your password to sign the transaction and click 'Continue'

![](/files/-Mj9hhMLHVPw_EuAerQC)

9\) Confirm your contract execution transaction and click ‘Publish’

![](/files/-Mj9hjY6zg5bJAQsouIN)

10\) After publishing your transaction a success message will appear

11\) View your transaction on the ‘Transaction History’ page You might first see the transaction on pending status, till it will get its first confirmation.

![](/files/-Mj9hsIfYUSgJ-iYI62_)


# Verify

This tool enable token holders to retrieve and verify the event information of a position asset.

{% hint style="info" %}
A position can be verified only if the asset was minted in the blockchain.
{% endhint %}

Verifying is possible in two ways:

* By 'Asset'  - Provide a valid asset ID to retrieve its event data and to indicate its position.
* By "Event" - Provide the event data to compute its position token.

## Step by step Guide

**By Asset:**

1\) Go to the ' By Asset' page under 'Verify' tab

2\) Enter the asset identifier of a position token and click 'Continue'

![](/files/-Mj9iRxz8VuwflW9ukav)

3\) Verify the retrieved 'event data' and the token position

![](/files/-Mj9iZ3LLSc6YtxQOHe4)

**By Event:**

1\) Go to the ' By Event' page under 'Verify' tab

2\) Fill the form with the event data and click  the "Verify" button

![](/files/-Mj9igZmSqS2H9lTuJTS)

3\) Verify the position token asset identifier.<br>

![](/files/-Mj9imoVDaeD4r8uzSw3)


# Settings

## **Node Connectivity**

{% hint style="info" %}
By default the FP Generator is connected to the Mainnet network
{% endhint %}

1. Click the 'Setting' icon on the top right corner of your screen&#x20;
2. Choose between the available networks

![](/files/-Mj9izGlSTg1Z9nCHsJZ)

## Contract Version

{% hint style="info" %}
By default the FP Generator is connected to the most recent contract version
{% endhint %}

1. Click the 'Setting' icon on the top right corner of your screen&#x20;
2. Choose between the available contract versions
3. Perfect, the current session now uses the new contract version

## **All Nodes**

* Mainnet | Remote Node | [mainnet-nodes.zp.io](https://mainnet-nodes.zp.io)
* Testnet | Remote Node | [testnet-nodes.zp.io](https://testnet-nodes.zp.io)


# How the FP Contract works

This contract assumes there is a working oracle service and an oracle contract which commits on a data set of `<asset, value>` pairs on different times.

The Fixed Payout contract can issue Bull and Bear positions on one of the tickers on which the oracle commits for a future event, and provides the winner with the collateral payed by the issuer.

First - the issuer issues **position tokens** for both positions, derived from the public key of the oracle service, the contract ID of the oracle contract, the name of the forex ticker, the time frame in which the event will take place, the price on which the positions diverge, and the position name.

The contract issues two position tokens, according to the possible positions:

1. Bull - which believes the price will be **above** or **equal to** the specified price during the specified time frame.
2. Bear - which believes the price will be **below** the specified price during the specified time frame.

Both of the tokens (issued by the same amount as the collateral) are sent to the issuer at the time of the issuing.

The issuer will hold the position they believe in and sell the other tokens, the buyers will hold the opposite position, then they will both wait until the event date will occur.

Once the event for which the position was issued has occurred, and the oracle has committed on the event data, the rightful redeemers must ask the oracle service to provide the proof data (which contains the timestamp, the value of the asset at the time of the commitment, the root of the Merkle tree of the committed data set, the audit path of the `<asset, value>` pair within the Merkle tree, the index of the `<asset, value>` within the leaves array of the Merkle tree, and the parameters of the Merkle tree), and the oracle contract has to attest for the global proof data (the timestamp, the root of the Merkle tree, and the oracle service public key), which would send the Fixed Payout contract an **attestation token** which will give the redeemer the right for the collateral when found in the wallet of the Fixed Payout contract, since the attestation token is the embodiment of the attestation of the oracle on the occurrence and details of the event.

If the specified redemption data fits both the given attestation token (which guarantees the occurrence of the event) and the position of the given position token (which guarantees the right of the redeemer for the collateral) - the contract will send the redeemer a portion of the collateral equal to the number of winning position tokens provided.

## Usage

The Fixed Payout contract accepts 3 commands:

1. `"Issue"`
2. `"Redeem"`
3. `"Cancel"`

### `"Issue"`

To issue new position tokens - execute the contract with the `"Issue"` command while providing it with a dictionary in the message body which contains the following data:

|      Field Name      |     Type     | Description                                                              |
| :------------------: | :----------: | ------------------------------------------------------------------------ |
|   `"OraclePubKey"`   |  `publicKey` | Public key of the oracle service                                         |
| `"OracleContractId"` | `contractId` | Contract ID of the oracle contract                                       |
|      `"Ticker"`      |   `String`   | Name of the forex ticker                                                 |
|       `"Price"`      |   `UInt64`   | Lowest price for the Bull position and the highest for the Bear position |
|       `"Start"`      |   `UInt64`   | Beginning of the time frame in which the event will take place           |
|      `"Expiry"`      |   `UInt64`   | End of the time frame in which the event will take place (optional)      |
|    `"Collateral"`    |   `String`   | Collateral asset (as an asset string)                                    |

The contract will lock to itself all the collateral tokens (of the asset defined in the `"Collateral"` field in the message body) which were provided to it in the TX by the issuer, and will mint and lock to the issuer the same amount of position tokens of both kinds (so if the issuer supplies the contract with `m` collateral tokens - the contract will mint and lock to the issuer `m` Bear tokens and `m` Bull tokens based on the event).

Diagrammatically it looks like this:

![](/files/-MVMVNOQvKBiJ8lsWjyq)

### `"Redeem"`

To redeem a position token - execute the contract with the `"Redeem"` command while providing it with a dictionary in the message body which contains the following data:

|      Field Name      |     Type     | Description                                                                                             |
| :------------------: | :----------: | ------------------------------------------------------------------------------------------------------- |
|   `"OraclePubKey"`   |  `publicKey` | Public key of the oracle service                                                                        |
| `"OracleContractId"` | `contractId` | Contract ID of the oracle contract                                                                      |
|      `"Ticker"`      |   `String`   | Name of the forex ticker                                                                                |
|       `"Price"`      |   `UInt64`   | Lowest price for the Bull position and the highest for the Bear position                                |
|       `"Start"`      |   `UInt64`   | Beginning of the time frame in which the event will take place                                          |
|      `"Expiry"`      |   `UInt64`   | End of the time frame in which the event will take place (optional)                                     |
|     `"Timestamp"`    |   `UInt64`   | Time of the commitment made by the oracle (in milliseconds since Epoch - 00:00:00 UTC, January 1, 1970) |
|       `"Root"`       |    `Hash`    | Root hash of the Merkle tree on which the oracle has committed                                          |
|       `"Value"`      |   `UInt64`   | Commited value of the asset (attested by the oracle)                                                    |
|     `"AuditPath"`    |  `list Hash` | Audit path on the Merkle tree from the leaf of the `<asset, value>` pair to the root of the tree        |
|       `"Index"`      |   `UInt64`   | Index of the `<asset, value>` pair in the Merkle tree                                                   |
|     `"Position"`     |   `String`   | Position of the redeemer - can be either `"Bull"` or `"Bear"`                                           |
|    `"Collateral"`    |   `String`   | Collateral asset (as an asset string)                                                                   |

You'll have to ensure the Fixed Payout contract has an attestation token from the oracle contract specified in `"OracleContractId"` which commits to the data specified in `"Root"`, `"Timestamp"`, and `"OraclePubKey"`.

You'll also have to provide the contract with the position tokens according to the position specified in `"Position"` - to redeem a Bull position provide the contract with Bull tokens, and make sure the attested value is above the price specified in `"Price"` or equal to it; to redeem a Bear position provide the contract with Bear tokens, and make sure the attested value is below the price specified in `"Price"`.

For both positions you'll also have to make sure that all of the following conditions hold:

1. The specified `"Timestamp"` is within the time bounds specified in `"Start"` and `"Expiry"`.
2. The specified `"AuditPath"` is valid for the Merkle root specified in `"Root"` for the leaf given by the `"Ticker"` key with the specified `"Value"` in the specified `"Index"`.
3. The data hashed in the position tokens is according to the specified `"OraclePubKey"`, `"OracleContractId"`, `"Ticker"`, `"Price"`, `"Start"`, `"Expiry"`, and `"Collateral"`.

When all of the conditions hold (including the conditions which are specific for the position) the contract will destroy the provided tokens and will lock to the redeemer collateral tokens of the same amount as the provided position tokens of the specified position.

Diagrammatically it looks like this:

![](/files/-MVMVST5kNj7eo9T9Rp9)

The only way for the resulting transaction to be valid is if: `Position Token` = `[[event data ; position]]`

### `"Cancel"`

To cancel some or all of the issued position tokens you execute the contract with the `"Cancel"` command and send the contract an equal amount of both position tokens, the same amount of collateral will be sent back to you and the given position tokens will be destroyed.

You'll also need to put in the message body the exact same data that was given at the issuance of the given tokens.

Diagrammatically:

![](/files/-MVMVdb3n2GR9S6PLw23)

As you can see this is the exact dual situation to the `"Issue"` command.

## Problems

If the time frame is too narrow there's a chance the oracle will not commit on the event during that time frame; if the time frame is too wide there's a chance the oracle will commit and attest for both the Bull and the Bear positions, so the collateral will go to whoever redeems it first ("the early bird gets the worm").

## Generated Assets

### Attestation Token

Generated by the **Oracle** contract.

```fsharp
[[[ [[ root ; timestamp ]] ; oraclePublicKey ]]]
```

### Position Token

Generated by the **Fixed Payout** contract.

```fsharp
[[ oracleContractId ; ticker ; price ; start ; expiry ; collateral ; position ]]
```


# How are the asset named?

Asset Name Server

## Why?

Using an asset identifier, its secure as it's unique, but it's not memorable, so it was used a similar principle to the DNS to create an ANS (Asset Name System)\
We develop an external actor which reads over the blockchain data and provides a simple API\
For each Fixed Payout asset the pre-image of the asset identifier is taken from the message body.

## How?

Asset: "00000000a16a47c2640e5a3b40a50cbbaca19ac6c9a57666cf1d298c1ddf0049469a05a17b1077bde2c9548c651675353a320690f54c9d30e9797edd25e4fdcb2c351d09"\
has a long name GOOGL240122Bear261500 and a short name GOOGLBear261500.

The addressDB allows us to request the mint information of an asset by using \
`/addressdb/contract/mint :`

```
{
    "executionBlock": 470957,
    "sender": "0278e2befe3063f02b01d1f7c08abae7d0669b58be6691baac94e67ad52c540f22",
    "command": "Issue",
    "messageBody": {
        "dict": [
            [
                "Price",
                {
                    "u64": 261500
                }
            ],
            [
                "Start",
                {
                    "u64": 1643058000000
                }
            ],
            [
                "Expiry",
                {
                    "u64": 1643058000000
                }
            ],
            [
                "Ticker",
                {
                    "string": "GOOGL"
                }
            ],
            [
                "Collateral",
                {
                    "string": "000000000000000000000000000000000000000000000000000000000000000000000000"
                }
            ],
            [
                "OraclePubKey",
                {
                    "pk": "020dc7cad106e9284be13576f5271c4f694da464076d2eb44fd5c74265316f70a3"
                }
            ],
            [
                "OracleContractId",
                {
                    "string": "00000000065ee39e9f6af7d6e185f5b72eace28cc48bba05969742f0f9066519f3452369"
                }
            ]
        ]
    }
```

This infos are then formatted to take for the short name: Ticker-Start-Position-Price


# Contract Structure

## Contract Structure

Each contract must contain 2 functions: main and cf.

The main function is run whenever a contract is used within a transaction.

The function will run both at the validation and at the generation of the transaction.

The structure of the main function is:

```
main
    ( txSkel      : Zen.Types.txSkeleton  )
    ( context     : Zen.Types.context     )
    ( contractId  : Zen.Types.contractId  )
    ( command     : string                )
    ( sender      : Zen.Types.sender      )
    ( messageBody : option Zen.Types.data )
    ( wallet      : Zen.Types.wallet      )
    ( state       : option Zen.Types.data )
    : Zen.Types.contractResult `Zen.Cost.t` n
```

where n must be an expression which evaluates to a natural number (nat).

## Parameters

* txSkel : Zen.Types.txSkeleton : The partial transaction supplied as input to the contract.
* context : Zen.Types.context : The blockchain context of the transaction, given by blockNumber (unsigned 32 bit integer), and timestamp - which is the UNIX Epoch time (unsigned 64 bit integer) of the block creation.
* contractId : Zen.Types.contractId : The contract identifier. (version, hash)
* command : string : String that the contract may use. Contains a command which tells the contract what to do. For example:

```
match command with
| "redeem" -> redeem txSkeleton contractId returnAddress wallet
| "buy"    -> buy txSkeleton contractId returnAddress
```

* sender : Zen.Types.sender : The sender identity. Can be any of the following:
  * Contract of Zen.Types.contractId: a contract, given by its ID
  * PK of Zen.Types.publicKey: a Public key
  * Anonymous: an anonymous sender
* messageBody : option Zen.Types.data : The transaction may carry a message which can be any of the following:
  * Byte: of FStar.UInt8.t: 8 bit unsigned integer
  * U32 of FStar.UInt32.t: 32 bit unsigned integer
  * U64 of FStar.UInt64.t: 64 bit unsigned integer
  * I64 of FStar.Int64.t: 64 bit signed integer
  * ByteArray of Zen.Array.t FStar.UInt8.t: array of 8 bit unsigned integer
  * String of string: FStar.prims
  * Hash of Zen.Types.hash: 256-bit hash value
  * Lock of Zen.Types.lock: Lock
  * Signature of Zen.Types.signature: Signature
  * PublicKey of Zen.Types.publicKey: Public key
  * Collection of Zen.Types.dataCollection: Data collection
* wallet : Zen.Types.wallet : Contains all the transaction inputs that were previously locked to the contract. In order for a contract to spend its own funds they need to come from contract wallet.
* state : option Zen.Types.data : The contract current state. Can be either Some data (as the message body) or None.

## Output

The output of the contract is of the record type Zen.Types.contractReturn which has 3 fields:

* state : Zen.Types.stateUpdate State update. Can be any of the following:
  * Delete - Delete the current state, resetting it to `None`
  * NoChange - Keeping the current state as it is, with no change.
  * Update of Zen.Types.data - Change the state to be the new given data.
* tx : Zen.Types.txSkeleton The generated transaction structure.
* message : option Zen.Types.message An optional message for invoking another contract. This is a record type which has 3 fields:
  * recipient: Zen.Types.contractId - The recipient contract.
  * command: string - The command given to the recipient contract.
  * body: option Zen.Types.data - The message body of given to the recipient contract.


# Contract Cost

## The Cost Model

Central to the analysis of contracts cost is the notion of a *cost model*.

A *cost model* for a language assigns a natural number to each closed term in the language in such a way that the term should take **at most** this number of "abstract steps" to evaluate, this natural number is called *the cost* of that term (relative to that cost model).

The abstract steps could be, for example, beta-reductions, so if the cost of a term M is n it would take at most n beta-reductions to reduce M to a normal form with the chosen evaluation strategy of the language.

The cost is defined **recursively** on the structure of the term, and it could depend on the **values** of some of its subterms, so we can think of the cost as a term in the language which **evalutes** to a natural number.

We use the notation $$c\left(M\right)$$ for the cost of the term M.

![](/files/-MQvV5jIfEOPaOpNjEKN)

Notice how the cost of both **function abstraction** and **applied let clause** is **0** - that's because function abstraction is in a **weak head normal form** - it's not evaluated further until it is applied on an argument, so as far as the execution environment is concerned it is **already a value**, so it won't be evaluated further; The cost of applied let clause is **0** as well, since an applied let expression if equivalent to a beta redex where the argument is itself a lambda ($$\textbf{let} : f : x = N : \textbf{in} : M$$ is equivalent to $$\left(\lambda f.M\right) : \left(\lambda x.N\right)$$ ), so it is considered the same; In both cases the cost of the body of the function is **internalized**, through the use of inc (which would be explained later).

In practice the actual cost (relative to the cost model) is **not computed directly**, instead - the cost is decomposed into 2 components:

> 1. **Compositional Cost** - which is **declared** by the
>
>    **developer** and **verified** by the **type system**
> 2. **Syntactic Cost** - which is **computed** by the **elaborator**

$$\textbf{total cost}=\textbf{compositional cost}+\textbf{syntactic cost}$$&#x20;

In fact - given general recursion it is **impossible** to automatically compute the cost of any arbitrary term in the language.

Another deviation from the cost model is that the cost we give in practice is an **upper bound** on the cost given by the cost model, because it is easier to compute, but since the cost model itself is an upper bound on the number of steps the approximation we use in practice still gives a valid upper bound.

The **syntactic cost** is given to terms **by virtue of their form**, and acts as a **seed** which the **compositional cost** later **propogates** into the program through the **type system**.

## The Cost Type

Given a cost model we define a special type constructor `cost` to indicate that a term of type *`cost`*` ``A m`, where `A` is a type and `m` is a natural number, would take at most `m` steps to produce a **value** of type `A`.

Dually - we use the type `cost A m` to indicate that a term of this type **represents a value** of type A which **has taken** at most `m` steps to evaluate.

When a **term** `M` has the type `cost A m` we say that M is a *costed term*, with a *cost* of m.

When a **function** `f` has the type `A -> cost B m` we say that `f` is a *costed function*, with a *cost* of `m`, which means that when given an input of type `A` it takes `f` at most `m` steps to produce an output of type `B`.

## Compositional Cost

The `cost` type constructor behaves as a an **indexed monad**, indexed over the additive monoid of the natural numbers, so whenever you compose (using Kleisli composition) 2 costed functions `f : B -> cost C n` and `g : A -> cost B m` you get a function of type `A -> cost C (m + n)` where the cost is the sum of the costs of `f` and `g`.

The **bind** operator (`>>=`) has the type signature:

&#x20;`bind: cost a m -> (a -> cost b n) -> cost b (m+n)`

In practice - the `cost` monad in *ZF\* is implemented as **the identity monad,** where the index could be set arbitrarily, so as far as* ZF\* *is concerned - **it is up to the developer to honestly declare the costs of terms***.

**The validity of the cost of a term is not fully enforced by the compiler!**

The compiler only makes sure that the costs are **composed correctly**.

To enforce the validity of the costs we combine the compiler with an **elaborator**, which would be explained in detail later on.

To lift a term into the monad we use the `ret` function, which is the unit of the monad and has the type `ret : a -> cost a 0`. Since the `ret` function gives a term a cost of `0`, we use the function `inc : (m:nat) -> cost a n -> cost a (n+m)` to increase the declared cost of a term.

## Syntactic Cost

The cost monad can only ensure that costs are composed correctly, but it cannot enforce the declared costs to conform to the cost model - it completely trusts the developer to declare costs honestly.

In order to actually **enforce** the cost model, we use a device called *the elaborator*.

The elaborator scans the syntax trees of the terms and recursively sums up the cost of each branch, adding additional constant cost with each clause and primitive operation.

Eventually, when the elaborator reaches either a **lambda expression**, or a **let expression** (which could be a **top-level let**) - it embeds the accumulated cost of the body of the expression into the body, by replacing it with an application of the inc function, along with the accumulated cost, on the body; this ensures 2 things:

> 1. That the term returns an output which is wrapped in the cost
>
>    monad.
> 2. That all the syntactic cost is accounted for.

![](/files/-MQvY0PfbHLMe4g82b8r)

![](/files/-MQvXlVo832J1PMc0N2t)

![](/files/-MQvXuiC3Du6eUGV5OMx)


# Contract Activation

A contract needs to be activated on the blockchain in order to be executed.\
When a contract mints token, the assets can be transfered without the need of the contract to be active.

A contract can be activated using:

### Desktop Wallet connected with Local Node

Check how to connect Local Node

Once you are connected with the local node, you will see in the Active Contract Page a new button to Activate a contract.

![](/files/-MRGPy15ZR9H9uwfLw5D)

Click on the button, a popup will open up and you can drop the .fst file, choose the number of blocks for which the contract will be in the ACS.\
For advance contract which require a higher rlimit you can choose a higher then the default rlimt. Note: the activation fee is proportional to the rlimit.&#x20;

![](/files/-MRGQGCO2i9YEnuSTaZh)

### API

## Activate Contract

<mark style="color:green;">`POST`</mark> `http://127.0.0.1:31567/wallet/contract/activate`

#### Request Body

| Name | Type   | Description |
| ---- | ------ | ----------- |
| code | string |             |

{% tabs %}
{% tab title="200 " %}

```
```

{% endtab %}
{% endtabs %}

### CLI

#### Activate Contract

```
> zen-cli activate path_to_.fst_file number_of_blocks rlimit

```


# Contract Examples

## Preliminary Notes

To **verify** the following examples use:

```
zebra -v Filename.fst
```

To **elaborate** and verify the elaborated result use:

```
zebra -e Filename.fst
```

The elaborated file will appear within the `output` subdirectory of your current directory.

In order for most of the examples to work you need to add the following lines at the beginning of your code:

```
open Zen.Cost

let main txSkeleton _ _ _ _ _ _ _ = Zen.ContractResult.ofTxSkel txSkeleton

let cf _ _ _ _ _ _ _ = ret #nat 4
```

## Simple Example

Let's create a simple function which takes a function and an argument and applies the function on the argument:

```
val applyOnce (#a #b:Type): (a -> b) -> a -> b
let applyOnce #_ #_ f x = f x
```

Elaborating the function will yield the following:

```
val applyOnce: #a: Type -> #b: Type -> (a -> b) -> a -> b
let applyOnce #_ #_ f x = inc 1 (f x)
```

That's because function application (`f x`) has a cost of 1, which is embedded into the let-expression with `inc`.

However - trying to compile this function will result in a typing error

* because you can only apply `inc` on a value of a

  `cost` type.

To fix it we modify the function to use `ret` on the result, to lift it into the `cost` monad, and we change the type signature to return a `cost` type (with a cost of 0 since that is the cost `ret` gives):

```
val applyOnce (#a #b:Type): (a -> b) -> a -> cost b 0
let applyOnce #_ #_ f x = ret (f x)
```

Now elaborating the function will yield the following:

```
val applyOnce (#a #b:Type): (a -> b) -> a -> cost b 0
let applyOnce #_ #_ f x = inc 2 (ret (f x))
```

That's because now we have **2 applications**, one of `f` on `x`, and the other of `ret` on the result.

Now the compilation would **still fail** with a typing error:

```
Subtyping check failed; expected type Zen.Cost.Realized.cost _ 0; got type Zen.Cost.Realized.cost _ (0 + 2)
```

That's because while the declared cost is 0, the **inferred** cost (due to the addition of `inc 2`) is 2.

To fix that we now have to declare the **correct** cost within the type, to account for the increment, so `cost b 0` becomes `cost b 2`:

```
val applyOnce (#a #b:Type): (a -> b) -> a -> cost b 2
let applyOnce #_ #_ f x = inc 2 (ret (f x))
```

Now that the syntactic cost is accounted for the program will compile.

## Aggregated Syntactic Cost

The following function takes a function `f` and an argument `x` and applies `f` on `x` and then applies it again on the result:

```
val applyTwice (#a:Type): (a -> a) -> a -> a
let applyTwice #_ f x = f (f x)
```

Elaborating this function will yield the following:

```
val applyTwice (#a:Type): (a -> a) -> a -> a
let applyTwice #_ f x = inc 2 (f (f x))
```

The increment by 2 is due to the fact there are 2 applications.

Again - this format won't do, and to be able to compile the elaborated program we have to lift the result into the cost monad and account for the additional costs:

```
val applyTwice (#a:Type): (a -> a) -> a -> cost a 3
let applyTwice #_ f x = ret (f (f x))
```

which will be elaborated as:

```
val applyTwice: #a: Type -> (a -> a) -> a -> cost a 3
let applyTwice #_ f x = inc 3 (ret (f (f x)))
```

Notice that this time we've predicted the increased elaborated cost in advance, so the original code won't compile (since `ret` gives a cost of 0) while the elaborated code will (since it will add `inc 3` to account for the costs of all the function applications).

In practice - **you won't be able to modify the elaborated code**, since the elaboration is done automatically when activating a contract, so instead you need to elaborate it locally, look at the result, and then modify the **original code** so it would compile right after the elaboration.

## Multiple Clauses

Now let's create another function - which takes a boolean `b`, a function `f`, and another argument `x`, and applies `f` on `x` **once** if `b` is `true` or **twice** if `b` is `false`.

We'll use the previously defined functions to do so:

```
val onceOrTwice (#a:Type): bool -> (a -> a) -> a -> cost a ?
let onceOrTwice #_ b f x = if b then applyOnce f x else applyTwice f x
```

What should be the declared cost of this function?

`applyOnce` gives a cost of **2**, while `applyTwice` gives a cost of **3**, so we have a **collision of costs**.

To reconcile the collision we manually insert `inc 1` to the `applyOnce f x` clasue to account for the difference between the costs, which would give both clauses of the `if-then-else` a cost of **3**:

```
val onceOrTwice (#a:Type): bool -> (a -> a) -> a -> cost a 3
let onceOrTwice #_ b f x = if b then inc 1 (applyOnce f x) else applyTwice f x
```

However - we still need to account for the syntactic cost of the `onceOrTwice` function itself - to do so we first elaborate the function, which gives us:

```
val onceOrTwice (#a:Type): bool -> (a -> a) -> a -> cost a 3
let onceOrTwice #_ b f x = inc 7 (if b then inc 1 (applyOnce f x) else applyTwice f x)
```

That is beacuse the `then` clause has **4 applications**, while the `else` clause has **3**, and since the syntactic cost of an `if-then-else` is defined as **3** + the maximal syntactic cost out of both clauses, which is **4** in this case, we get a total syntactic cost of **7**, which is embedded with an `inc 7` into the let-expression.

Now to account for the additional cost of **7** we change the declared cost of the function to **10**:

```
val onceOrTwice (#a:Type): bool -> (a -> a) -> a -> cost a 10
let onceOrTwice #_ b f x = inc 7 (if b then inc 1 (applyOnce f x) else applyTwice f x)
```

The elaborated code will now compile.

## Composition

Let's define 2 simple functions on the natural numbers - a function which takes a number and doubles it and a function which adds 7 to a number:

```
val double : nat -> nat
let double x = 2 * x

val add7 : nat -> nat
let add7 x = x + 7
```

We'll also define a function `foo` which would first double a number and then add 7 to the result, by composing the above functions:

```
val foo : nat -> nat
let foo x = add7 (double x)
```

The code will compile just fine, but not the elaboration.

To pass the elaboration we need to make sure all the functions are costed by lifting the results into the `cost` monad:

```
val double : nat -> cost nat 0
let double x = ret (2 * x)

val add7 : nat -> cost nat 0
let add7 x = ret (x + 7)
```

What about `foo`? trying to simply compose `add7` and `double` and lifting the result will now fail to typecheck:

```
val foo : nat -> cost nat 0
let foo x = ret (add7 (double x))
```

That's because we've changed the return type of the functions, so to compose them we have to use the **bind operator** (`>>=`):

```
val foo : nat -> cost nat 0
let foo x = ret x >>= double >>= add7
```

Now elaboration would still fail, so we have to account for the syntactic cost as well - let's look at the elaborated code:

```
val double: nat -> cost nat 0
let double x = (inc 3 (ret (2 * x)))

val add7: nat -> cost nat 0
let add7 x = (inc 3 (ret (x + 7)))

val foo: nat -> cost nat 0
let foo x = (inc 5 (ret x >>= double >>= add7))
```

By looking at the `inc`s we know that the cost of both `double` and `add7` is 3, so we modify their types in the original code:

```
val double : nat -> cost nat 3
let double x = ret (2 * x)

val add7 : nat -> cost nat 3
let add7 x = ret (x + 7)
```

What is the cost of `foo`? trying to simply give it a cost of 5 will **fail**:

```
val foo: nat -> cost nat 5
let foo x = (inc 5 (ret x >>= double >>= add7))
```

That's because we now have to take the costs of `double` and `add7` into account as well.

Recall that the type of the bind operator is: `cost a m -> (a -> cost b n) -> cost b (m+n)`, so it sums up the costs, which means that's exactly what we have to do.

Since the cost of `double` is **3**, the cost of `add7` is **3**, and the syntactic cost of `foo` is **5**, adding them all together gives us a cost of **11**:

```
val foo: nat -> cost nat 11
let foo x = (inc 5 (ret x >>= double >>= add7))
```

Now the elaborated code will compile.

## Recursion

The cost analysis becomes more complex once you introduce recursion.

The following function computes the factorial of a natural number:

```
val fact: nat -> int
let rec fact m =
    match m with
    | 0 -> 1
    | _ -> m * fact (m - 1)
```

Trying to elaborate this function will fail, since it doesn't return a `cost` type.

```
val fact: nat -> int
let rec fact m =
  inc 7
      (match m with
        | 0 -> 1
        | _ -> m * fact (m - 1))
```

To make sure the result is of a `cost` type - we apply `ret` on the base case, and bind the recursion step:

```
let rec fact m =
    match m with
    | 0 -> ret 1
    | _ -> fact (m - 1) >>= (fun r -> ret (m * r))
```

We might prefer to use some syntactic sugar to make the code look nicer:

```
let rec fact m =
    match m with
    | 0 -> ret 1
    | _ -> let! r = fact (m - 1)
           in ret (m * r)
```

What should be the return type of the new function? we can start with `cost int 0`:

```
val fact: nat -> cost int 0
let rec fact m =
    match m with
    | 0 -> ret 1
    | _ -> let! r = fact (m - 1)
           in ret (m * r)
```

Now the elaborated code will not compile, but it will give us some hints on how to specify the cost correctly:

```
val fact: nat -> cost int 0
let rec fact m =
  inc 10
      (match m with
        | 0 -> ret 1
        | _ -> let! r = fact (m - 1)
               in ret (m * r))
```

We might be tempted to assign a cost of **10** to the function, but that won't do - if the cost of `fact` is **10** then `fact (m - 1)` will have a cost of **10** and after accounting for the incremented syntactic cost (which is added by `inc 10`) we'll get that the **actual** cost of the function is **20**.

In fact - assuming **any** constant cost will yield a **contradiction**, since we'll always get another 10 steps added to what we've started with, which indicates that it is impossible to assign a constant cost to the function.

How do we resolve it? by making the cost **parametric** in the size of the input, by using **dependent types**.

First we explicitly declare the **name** of the input parameter **in the type**:

```
val fact: (m:nat) -> cost int 0
```

Then we can use this name within the cost expression, for example like this:

```
val fact: (m:nat) -> cost int m
```

But this won't do - we have to figure out the actual dependency of the cost on the parameter.

Let's assume for now the cost is some function `fact_c` on `m`:

```
val fact: (m:nat) -> cost int (fact_c m)
```

Looking at the definition of `fact` again - we immediately see a problem - the cost of `ret 1` is always **0**, while the cost of `fact (m-1)` is `fact_c (m-1)`, which **can't be 0**, so we have 2 pattern matching clauses with different costs.

This will result in a typing error when we try to compile the code, since all clauses of a `match-with` must return a result of the same type.

To fix that we need to add the difference to the first clause, like this (notice this is a modification of the original code, **not** the elaborated code):

```
val fact: (m:nat) -> cost int (fact_c m)
let rec fact m =
    match m with
    | 0 -> inc (fact_c (m-1)) (ret 1)
    | _ -> let! r = fact (m-1)
           in ret (m * r)
```

Instead of using `ret` and then `inc` we can just use `incRet`, which combines the 2:

```
val fact: (m:nat) -> cost int (fact_c m)
let rec fact m =
    match m with
    | 0 -> incRet (fact_c (m-1)) 1
    | _ -> let! r = fact (m-1)
           in ret (m * r)
```

Now we have to figure out what `fact_c` is.

Since the elaborator adds **10** to the cost, and this value didn't change with the addition of the `incRet` to the first clause (since the total syntactic cost for a `match-with` is determined only by the syntactically heaviest clause, which is still the second clause), we get **10** added to the cost **with each call to the function**, which means that the **base case** has **at least** a cost of **10**, and with each **recursion step** another **10** is added, so we get the following recurrence relation:

```
fact_c m = 10 + fact_c (m - 1)
```

What is the base case (for `m = 0`)?

Since we know it is **at least 10** (since the cost is increased by 10 and it can never be decreased), we can try assigning it to be 10, which gives us the solution:

```
fact_c m = 10 * (m + 1)
```

So let's try it:

```
val fact: (m:nat) -> cost int (10 * (m+1))
let rec fact m =
    match m with
    | 0 -> incRet (10 * m) 1
    | _ -> let! r = fact (m-1)
           in ret (m * r)
```

Now the function is elaborated to:

```
val fact: m: nat -> cost int (10 * (m + 1))
let rec fact m =
    inc 10
      (match m with
        | 0 -> incRet (10 * m) 1
        | _ -> let! r = fact (m - 1) in ret (m * r))
```

The program now compiles successfully, which indicates that the cost is now correct.

The keen-sighted reader will notice that the first clause `incRet (10 * m) 1` is operationally equivalent to `ret 1`, since the only case in which this clause is executed is when `m = 0`, but since all clauses must return a result of the same type, no matter if they are executed or not, the only way to pass the type checker is by explicitly handling the cost for all possible values of `m`.


# Smart Contracts SDK

Learn how to use the ZP Smart Contract SDK to write, compile and test smart contracts in the ZF\* language.

Zen-SDK Repo -> <https://github.com/zenprotocol/ZFS-SDK>

## Installation

### From Source

You will need to have mono installed. Instructions for your OS can be found [here](http://www.mono-project.com/download/). For Linux, you will need either the `mono-devel` or `mono-complete` package. Do not install mono from your package manager - follow the instructions on the mono website.

#### Linux

* Clone this repo
* Run the following commands. Note that this could take a few minutes.
* `cd ZFS-SDK`
* `./paket restore`
* `./build.sh`

#### OSX

* Clone this repo
* Run the following commands. Note that this could take a few minutes.
* `cd ZFS-SDK`
* `mono paket restore`
* `./build.sh`

### From NPM

#### OSX

1. Install [mono-devel](http://www.mono-project.com/download). If you choose to install via a package manager, add Mono's own repository first.
2. [Install Nodejs](https://nodejs.org/en/download/)
   1. Recommended to install using [NVM](https://github.com/creationix/nvm#installation)
   2. Recommended to install Node LTS `nvm install 8.9.4`

### Windows

1. Install [.NET Framework 4.7](https://www.microsoft.com/en-us/download/details.aspx?id=55167).
2. [Install Nodejs](https://nodejs.org/en/download/) (LTS version recommended)
3. Open the [Command Prompt](https://www.lifewire.com/how-to-open-command-prompt-2618089)

### Linux

1. Install [mono-devel](http://www.mono-project.com/download). If you choose to install via a package manager, add Mono's own repository first.
2. Install Nodejs (Version >= 6)
   1. Recommended to install using [NVM](https://github.com/creationix/nvm#installation)
   2. Recommended to install Node LTS (8.9.4) `nvm install --lts`

### Point your npm directory to our repository

Run the following commands in the Terminal / Command Prompt:

```
npm config set @zen:registry https://www.myget.org/F/zenprotocol/npm/
```

### Installing / Updating

Run the following commands in the Terminal / Command Prompt:

```
npm install @zen/zebra -g
```

## Usage

```bash
USAGE: zebra [--help] [<subcommand> [<options>]]

SUBCOMMANDS:

    create <options>      Create a new template contract
    elaborate, e <options>
                          Elaborate the source File and verify
    verify, v <options>   Verify the source file
    extract, x <options>  Extract the source file
    compile, c <options>  Compile from source file
    pack, p <options>     Pack the contract to be activated on zen blockchain
    generate-fsx, g <options>
                          Generate a .fsx file to test the contract with
    run-fsx, r <options>  Run the given .fsx file, automatically loading Zen dlls.
    contractid, cid <options>
                          Compute contract ID.
    acost, ac <options>   Compute activation cost.
    info, i <options>     Get contract information

    Use 'zebra <subcommand> --help' for additional information.

OPTIONS:

    --help                display this list of options.
```

### create

```bash
USAGE: zebra create [--help] <filename>

FILENAME:

    <filename>            File name of the generated contract

OPTIONS:

    --help                display this list of options.
```

### elaborate

```bash
USAGE: zebra elaborate [--help] [--z3rlimit <rlimit>] [--log-types] <filename>

FILENAME:

    <filename>            File name of the contract to elaborate

OPTIONS:

    --z3rlimit, -z <rlimit>
                          Z3 rlimit
    --log-types, -t       Log types
    --help                display this list of options.
```

### verify

```bash
USAGE: zebra verify [--help] [--z3rlimit <rlimit>] [--log-types] <filename>

FILENAME:

    <filename>            File name of the contract to verify

OPTIONS:

    --z3rlimit, -z <rlimit>
                          Z3 rlimit
    --log-types, -t       Log types
    --help                display this list of options.
```

### extract

```bash
USAGE: zebra extract [--help] [--z3rlimit <rlimit>] [--log-types] <filename>

FILENAME:

    <filename>            File name of the contract to extract

OPTIONS:

    --z3rlimit, -z <rlimit>
                          Z3 rlimit
    --log-types, -t       Log types
    --help                display this list of options.
```

### compile

```bash
USAGE: zebra compile [--help] [--z3rlimit <rlimit>] [--log-types] <filename>

FILENAME:

    <filename>            File name of the contract to compile

OPTIONS:

    --z3rlimit, -z <rlimit>
                          Z3 rlimit
    --log-types, -t       Log types
    --help                display this list of options.
```

### pack

```bash
USAGE: zebra pack [--help] <filename>

FILENAME:

    <filename>            File name of the contract to pack

OPTIONS:

    --help                display this list of options.
```

### generate-fsx

```bash
USAGE: zebra generate-fsx [--help] <filename>

FILENAME:

    <filename>            File name of the source contract to generate FSX script from

OPTIONS:

    --help                display this list of options.
```

### run-fsx

```bash
USAGE: zebra run-fsx [--help] <filename>

FILENAME:

    <filename>            File name of the FSX script

OPTIONS:

    --help                display this list of options.
```

### contractid

```bash
USAGE: zebra contractid [--help] <filename>

FILENAME:

    <filename>            File name of the contract

OPTIONS:

    --help                display this list of options.
```

### acost

```bash
USAGE: zebra acost [--help] [--numofblocks <uint>] [--z3rlimit <rlimit>] <filename>

FILENAME:

    <filename>            File name of the contract

OPTIONS:

    --numofblocks, -n <uint>
                          Number of blocks
    --z3rlimit, -z <rlimit>
                          Z3 rlimit
    --help                display this list of options.
```

### info

```bash
USAGE: zebra info [--help] [--z3rlimit <rlimit>] <filename>

FILENAME:

    <filename>            File name of the contract

OPTIONS:

    --z3rlimit, -z <rlimit>
                          Z3 rlimit
    --help                display this list of options.
```


# Contracts Language ZF\*

Documentation for the ZF\* (pronounced "Z-F-Star") dialect of F\*

ZF\* is the smart contracting language for the Zen Protocol.\
ZF\* is a dialect of the [F\* language](https://www.fstar-lang.org/).

### Prerequisites

Before beginning to develop with ZF\*, it is worth developing familiarity with a statically typed functional language, such as [F#](https://fsharp.org/), [OCaml](https://ocaml.org/), or [Haskell](https://www.haskell.org/).\
\
It's worth skimming through the [F\* tutorial](https://www.fstar-lang.org/tutorial/). Note that the F\* tutorial also assumes familiarity with F#, OCaml, or Haskell.

#### Recommended resources

F# ( Online )\
&#x20; \* [F# Programming WikiBook](https://en.wikibooks.org/wiki/F_Sharp_Programming)\
&#x20; \* [F# for C#, Java or Python developers](https://fsharpforfunandprofit.com/)\
&#x20; \* [F# Cheat Sheet\
&#x20;](http://dungpa.github.io/fsharp-cheatsheet/) \* [Learn F# in Y Minutes](https://learnxinyminutes.com/docs/fsharp/)\
\
F# ( Books )\
&#x20; \* [Real-World Functional Programming](https://www.amazon.com/Real-World-Functional-Programming-Tomas-Petricek/dp/1933988924)\
&#x20; \* [Expert F# 4.0](https://www.amazon.com/Expert-F-4-0-Don-Syme/dp/1484207416)\
\
OCaml ( Online )\
&#x20; \* [OCaml Tutorials](https://ocaml.org/learn/tutorials/)\
&#x20; \* [Real World OCaml](http://dev.realworldocaml.org/) (Dev version)\
\
OCaml ( Books )\
&#x20; \* [Real World OCaml](https://www.amazon.com/Real-World-OCaml-Functional-programming/dp/144932391X) (Slightly out of date. Use the online dev version for more up-to-date information)\
\
Haskell ( Online )\
&#x20; \* [Learn You a Haskell for Great Good!](http://learnyouahaskell.com/chapters)\
\
Haskell ( Books )\
&#x20; \* [Learn You a Haskell for Great Good!](http://learnyouahaskell.com/chapters)


# Named Token Tutorial

## Named Token

First we'll learn how to write a very simple contract, called the "Named Token" contract. The contract simply mints a token with an identifier specified by the issuer, and locks the specified amount of the token to the specified return address.

Let's specify the contract.

First - the issuer executes the contract, giving it the following data:

1. **name** `: string` The name of the issued token
2. **amount**`: uint64`: The issued amount of the token
3. **returnAddress**`: Zen.Types.lock`: The recipient of the token

Then - the contract mints the specified amount of the token using the given name as a subidentifier, and locks it to the specified return address.

The whole process looks like this:

![](/files/-MQve9fqACZW_2CcVaWZ)

Let's write the contract.

Create a text file called *"NamedToken.fst"*, the *"fst"* suffix is the standard suffix for **F\*** files.

At the top of the file put the module name - it should be identical to the file name (excluding the suffix):

```
module NamedToken
```

We should also load (using the `open` directive) a couple of useful modules (`Zen.Base`, `Zen.Cost`, and `Zen.Data`) into the namespace, which we'll use later on.

The file should now look like this:

```
module NamedToken

open Zen.Base
open Zen.Cost
open Zen.Data
```

Each contract should have at least 2 top-level functions: `main`, and `cf`.

The `main` function is the function which runs with each execution of the contract, and `cf` function is the function which describes the cost of the `main` function.

Let's write the `main` function, it should always have the following type signature:

```
main
    ( txSkel      : Zen.Types.txSkeleton  )
    ( context     : Zen.Types.context     )
    ( contractId  : Zen.Types.contractId  )
    ( command     : string                )
    ( sender      : Zen.Types.sender      )
    ( messageBody : option Zen.Types.data )
    ( wallet      : Zen.Types.wallet      )
    ( state       : option Zen.Types.data )
    : Zen.Types.contractResult `Zen.Cost.t` n
```

where `n` is the cost of the function and equal to `cf txSkel context command sender messageBody wallet state` \
(notice that `cf` doesn't take the `contractId` as an argument, since the cost shouldn't depend on it).

In practice we usually don't actually have to specify the types of the parameters, as they would be inferred by the compiler.

It should look like this:

```
let main txSkel context contractId command sender messageBody wallet state =
    ...
```

We haven't supplied the body of the function yet, which should go below that line (instead of the ellipsis).

The first thing we need to do is to parse the data - to extract the name, amount, and return address out of it.

The data should be sent to the contract through the `messageBody` parameter, in the form of a dictionary, which will contain the specified data as *(key, value)* pairs, where each key corresponds to one of the specified fields (**"name"**, **"amount"**, and **"returnAddress"**).

Since we assume `messageBody` is a dictionary, we need to try to extract a dictionary out of it - this is is done with the `tryDict` function, defined in `Zen.Data`.

The `tryDict` function has the following type signature:

```
tryDict: data -> option (Dict.t data) `cost` 4
```

Recall that the `data` type is a discriminated union of the following:

```
type data =
    | I64 of I64.t
    | Byte of U8.t
    | ByteArray: A.t U8.t -> data
    | U32 of U32.t
    | U64 of U64.t
    | String of string
    | Hash of hash
    | Lock of lock
    | Signature of signature
    | PublicKey of publicKey
    | Collection of dataCollection

and dataCollection =
    | Array of A.t data
    | Dict of dictionary data
    | List of list data
```

So what `tryDict` does, is taking a value of type `data`, and if that value is a `Collection(Dict(d))` - it returns `Some d`, and otherwise it returns `None`.

Now - since the `messageBody` is already an `option data`, we can't apply `tryDict` on it directly (since it expects a `data`), so instead we use the `(>!=)` operator from `Zen.Data` which have the following type signature:

```
(>!=) : option a -> (a -> cost (option b) n) -> cost (option b) n
```

The dictionary extraction should look like this:

```
messageBody >!= tryDict
```

Let's name the result as `dict`, using a `let` expression, so the `main` function should now look like this:

```
let main txSkel context contractId command sender messageBody wallet state =

    let dict = messageBody >!= tryDict in

    ...
```

`dict` will either contain a `Some d` (where `d` is a dictionary) or `None`.

Now that we have the dictionary, let's extract the required fields out of it, using the `tryFind` function (from `Zen.Dictionary`).

The `tryFind` function has the following type signature:

```
tryFind : string -> dictionary a -> option a `cost` 64
```

It takes a key name as an argument, and a dictionary, and if that dictionary has a value with the specified key name it returns it (within a `Some`), and otherwise returns `None`.

Since `dict` is an ``option (dictionary data) `cost` 64`` we can't use `tryFind` on it directly, so we'll use the `(>?=)` operator (defined in `Zen.Data`) instead.

The `(>?=)` operator has the following type signature:

```
(>?=) : option a `cost` m -> (a -> option b `cost` n) -> option b `cost` (m+n)
```

To extract the value of the **"returnAddress"** key, we'll do:

```
dict
>?= Zen.Dictionary.tryFind "returnAddress"
```

(notice we use the full qualified name here, since we didn't load the `Zen.Dictionary` module into the namespace with the `open` directive)

This will give us a (costed) `option data` value; to extract an actual lock out of that value we'll use the `tryLock` function (defined in `Zen.Data`):

```
dict
>?= Zen.Dictionary.tryFind "returnAddress"
>?= tryLock
```

Let's give a name to the extracted lock, using a `let!` expression.

```
let! returnAddress =
    dict
    >?= Zen.Dictionary.tryFind "returnAddress"
    >?= tryLock
in
```

The `let!` usage strips the cost out of the declared variable (using the cost monad), so it would be easier to work with - the type of `returnAddress` will be `option lock`, instead of ``option lock `cost` m``.

Now the whole `main` function should look like this:

```
let main txSkel context contractId command sender messageBody wallet state =

    let dict = messageBody >!= tryDict in

    let! returnAddress =
        dict
        >?= Zen.Dictionary.tryFind "returnAddress"
        >?= tryLock
    in

    ...
```

To extract the **"amount"** and **"name"** keys we'll do something similar (using `tryU64` and `tryString`, respectively, instead of `tryLock`):

```
let main txSkel context contractId command sender messageBody wallet state =

    let dict = messageBody >!= tryDict in

    let! returnAddress =
        dict
        >?= Zen.Dictionary.tryFind "returnAddress"
        >?= tryLock
    in

    let! amount =
        dict
        >?= Zen.Dictionary.tryFind "amount"
        >?= tryU64
    in

    let! name =
        dict
        >?= Zen.Dictionary.tryFind "name"
        >?= tryString
    in

    ...
```

Now that we have all of the data, we can use it assuming everything was provided by the issuer.

To consider both the case where the issuer has provided everything and the case where there is missing information, we pattern match on the data, like this:

```
match returnAddress,amount,name with
| Some returnAddress, Some amount, Some name ->
    ...
| _ ->
    ...
```

The 1st case will be executed when all the data was provided, and the 2nd case will be executed if any of the required parameters wasn't provided.

Let's throw an error when some of the parameters are missing.

```
match returnAddress,amount,name with
| Some returnAddress, Some amount, Some name ->
    ...
| _ ->
    Zen.ResultT.autoFailw "parameters are missing"
```

The function `autoFailw` in `Zen.ResultT` throws an error (within a `ResultT`) and infers the cost automatically.

If all the parameters were provided - we need to check that the provided name of the token is at most 32 characters, because that's the maximum size an asset subidentifier can have.

If the name is longer than 32 characters - we throw an error:

```
match returnAddress,amount,name with
| Some returnAddress, Some amount, Some name ->
    if FStar.String.length name <= 32 then
        ...
    else
        Zen.ResultT.autoFailw "name is too long"
| _ ->
    Zen.ResultT.autoFailw "parameters are missing"
```

In Zen Protocol assets are defined by 2 parts:

1. Main Identifier - The contract ID of the contract which have minted the asset.
2. Subidentifier - The unique ID of the asset, given by 32 bytes.

If the name is short enough to fit as an asset subidentifier - we can define a token with the given name as the subidentifier and the contract ID of this contract as the main identifier (using the `fromSubtypeString` function from `Zen.Asset`):

```
match returnAddress,amount,name with
| Some returnAddress, Some amount, Some name ->
    if FStar.String.length name <= 32 then
        begin
          let! token = Zen.Asset.fromSubtypeString contractId name in
          ...
        end
    else
        Zen.ResultT.autoFailw "name is too long"
| _ ->
    Zen.ResultT.autoFailw "parameters are missing"
```

(Notice that we're using `begin` and `end` here instead of parentheses, to make the code cleaner)

Now that we have defined the named token - we **mint** the specified amount of it, and then **lock** the minted tokens to the specified return address - this is done by modifying the supplied transaction (`txSkel`) with `mint`, and then modifying the result with `lockToAddress` (both are defined in `Zen.TxSkeleton`):

```
match returnAddress,amount,name with
| Some returnAddress, Some amount, Some name ->
    if FStar.String.length name <= 32 then
        begin
          let! token = Zen.Asset.fromSubtypeString contractId name in

          let! txSkel =
            Zen.TxSkeleton.mint amount token txSkel
            >>= Zen.TxSkeleton.lockToAddress token amount returnAddress in

          ...
        end
    else
        Zen.ResultT.autoFailw "name is too long"
| _ ->
    Zen.ResultT.autoFailw "parameters are missing"
```

Notice the syntax we're using here - both `mint` and `lockToAddress` return a costed `txSkeleton`, so to chain them we're using the `(>>=)` operator (bind) of the cost monad, and then we name the result using a `let!` so we can use it as a "pure" `txSkeleton` (instead of a **costed** `txSkeleton`).

Now that we've prepared the transaction - all that is left is to return it (using `ofTxSkel` from `Zen.ContractResult`), and the contract is done:

```
match returnAddress,amount,name with
| Some returnAddress, Some amount, Some name ->
    if FStar.String.length name <= 32 then
        begin
          let! token = Zen.Asset.fromSubtypeString contractId name in

          let! txSkel =
            Zen.TxSkeleton.mint amount token txSkel
            >>= Zen.TxSkeleton.lockToAddress token amount returnAddress in

          Zen.ContractResult.ofTxSkel txSkel
        end
    else
        Zen.ResultT.autoFailw "name is too long"
| _ ->
    Zen.ResultT.autoFailw "parameters are missing"
```

The whole file should now look like this:

```
module NamedToken

open Zen.Base
open Zen.Cost
open Zen.Data

let main txSkel context contractId command sender messageBody wallet state =

    let dict = messageBody >!= tryDict in

    let! returnAddress =
        dict
        >?= Zen.Dictionary.tryFind "returnAddress"
        >?= tryLock
    in

    let! amount =
        dict
        >?= Zen.Dictionary.tryFind "amount"
        >?= tryU64
    in

    let! name =
        dict
        >?= Zen.Dictionary.tryFind "name"
        >?= tryString
    in

    match returnAddress,amount,name with
    | Some returnAddress, Some amount, Some name ->
        if FStar.String.length name <= 32 then
            begin
              let! token = Zen.Asset.fromSubtypeString contractId name in

              let! txSkel =
                Zen.TxSkeleton.mint amount token txSkel
                >>= Zen.TxSkeleton.lockToAddress token amount returnAddress in

              Zen.ContractResult.ofTxSkel txSkel
            end
        else
            Zen.ResultT.autoFailw "name is too long"
    | _ ->
        Zen.ResultT.autoFailw "parameters are missing"
```

Now we can verify the validity of this file with:

```
zebra -v NamedToken.fst
```

It should verify successfully, returning:

```
zebra -v NamedToken.fst SDK: Verified
```

But hold on - **we aren't done yet!**

We have finished with the `main` function, but we still need to define the `cf` function.

The type signature of `cf` is:

```
cf
    ( txSkel      : Zen.Types.txSkeleton  )
    ( context     : Zen.Types.context     )
    ( command     : string                )
    ( sender      : Zen.Types.sender      )
    ( messageBody : option Zen.Types.data )
    ( wallet      : Zen.Types.wallet      )
    ( state       : option Zen.Types.data )
    : nat `cost` n
```

So we should add the `cf` function to the end of the file, like this:

```
let cf txSkel context command sender messageBody wallet state =
```

To start - let's give it to the value of `0` and then lift it into the cost monad with `Zen.Cost.ret`:

```
let cf txSkel context command sender messageBody wallet state =
    0
    |> Zen.Cost.ret
```

Let's try to **elaborate** the contract, to make sure the cost is correct.

```
zebra -e NamedToken.fst
```

You should get the following error:

```
(Error 19) Subtyping check failed; expected type
_: Zen.Types.Realized.txSkeleton ->
context: Zen.Types.Main.context ->
command: Prims.string ->
_: Zen.Types.Main.sender ->
messageBody: FStar.Pervasives.Native.option Zen.Types.Data.data ->
_: Zen.Types.Realized.wallet ->
state: FStar.Pervasives.Native.option Zen.Types.Data.data ->
Prims.Tot (Zen.Cost.Realized.cost Prims.nat (0 + 2)); got type
txSkel: Zen.Types.Realized.txSkeleton ->
context: Zen.Types.Main.context ->
command: Prims.string ->
sender: Zen.Types.Main.sender ->
messageBody: FStar.Pervasives.Native.option Zen.Types.Data.data ->
wallet: Zen.Types.Realized.wallet ->
state: FStar.Pervasives.Native.option Zen.Types.Data.data ->
Prims.Tot (Zen.Cost.Realized.cost Prims.int (0 + 2))
```

Notice how it infers that `cf` returns an `int`, while it should return a `nat`.

To solve it we need to **cast** the value of `cf` into a `nat`, using the `cast` function:

```
let cf txSkel context command sender messageBody wallet state =
    0
    |> cast nat
    |> Zen.Cost.ret
```

Let's elaborate it again, now we get the following error:

```
(Error 19) Subtyping check failed; expected type
txSkel: Zen.Types.Realized.txSkeleton ->
context: Zen.Types.Main.context ->
_: Zen.Types.Extracted.contractId ->
command: Prims.string ->
sender: Zen.Types.Main.sender ->
messageBody: FStar.Pervasives.Native.option Zen.Types.Data.data ->
wallet: Zen.Types.Realized.wallet ->
state: FStar.Pervasives.Native.option Zen.Types.Data.data ->
Prims.Tot
(Zen.Cost.Realized.cost Zen.Types.Main.contractResult
  (Zen.Cost.Realized.force (CostFunc?.f (Zen.Types.Main.CostFunc NamedToken.cf)
          txSkel
          context
          command
          sender
          messageBody
          wallet
          state))); got type
txSkel: Zen.Types.Realized.txSkeleton ->
context: Zen.Types.Main.context ->
contractId: Zen.Types.Extracted.contractId ->
command: Prims.string ->
sender: Zen.Types.Main.sender ->
messageBody: FStar.Pervasives.Native.option Zen.Types.Data.data ->
wallet: Zen.Types.Realized.wallet ->
state: FStar.Pervasives.Native.option Zen.Types.Data.data ->
Prims.Tot
(Zen.Cost.Realized.cost Zen.Types.Main.contractResult
  (4 + 64 + 2 + (4 + 64 + 2 + (4 + 64 + 2 + (64 + (64 + 64 + 3)))) + 54))
```

Look at the number at the bottom - this is the cost that was **inferred** by the compiler, so let's try to paste it into the function:

```
let cf txSkel context command sender messageBody wallet state =
    (4 + 64 + 2 + (4 + 64 + 2 + (4 + 64 + 2 + (64 + (64 + 64 + 3)))) + 54)
    |> cast nat
    |> Zen.Cost.ret
```

Let's try to elaborate again:

```
zebra -e NamedToken.fst SDK: Elaborating NamedToken.fst ... 
SDK: Wrote elaborated source to NamedToken.fst SDK: Verified
```

**Congratulations!**

You have written, elaborated, and verified your very first contract.

This time we were lucky - we didn't have to explicitly type our terms and the code was simple enough for the compiler to infer its cost.

With more complex contracts it might not be so easy - in many cases you'll have to explicitly type your terms to convince the compiler that the cost of the contract is what you claim it is.


# Common Goods Pool

This protocol upgrade creates a '**Common Goods Pool**' (or '**CGP**'), which would hold assets, and distribute its funds according to an on-chain vote open to ZP holders.

The CGP contract is a custodian contract which can unlock ('**pay out**') some of its available assets to a specified recipient - a PK address or a contract.

For each block - some portion of the coinbase transaction (called "**allocation**") will be locked to the CGP contract instead of the miner.

Since the CGP is a contract, users would also be able to **donate** any amount of any asset they own to the CGP, allowing the CGP to hold tokens of any kind of Zen Protocol asset.

Users will be able to vote on the portion of the coinbase outputs locked to the CGP contract ("**allocation**" vote), and on the recipient and spends (assets and amounts) of each payout ("**payout**" vote).

Voting for allocation could be done anytime during the voting phase, however - voting for payout is split into 2 phases - nomination phase and voting phase.

1. The **Nomination Phase** - in which payout contestants are trying to become valid payout **nominees**.
2. The **Voting Phase** - in which valid payout nominees are trying to get the payout.

### Interval blocks

* **Blockchain Interval:**

  From `10,000 * (N-1) + 1` to `10,000 * N` (including boundaries)

  The whole process takes places in intervals of `10,000` blocks starting from the genesis.
* **Voting Interval:**

  From `10,000 * (N-1) + 9,001` to `10,000 * N` (including boundaries)

  The actual voting takes place here.

  Split into 2 **phases**:

  1. **Nomination Phase:**

     From `10,000 * (N-1) + 9,001` to `10,000 * (N-1) + 9,500` (including boundaries)

     Nominating contestants for the payout
  2. **Voting Phase:**

     From `10,000 * (N-1) + 9,501` to `10,000 * N` (including boundaries)

     Voting on which nominee gets the payout
* **Snapshot Block:**

  `10,000 * (N-1) + 9,000`

  All the votes are weighted and validated by using the state of the UTXOs set at this block.
* **Payout Block:**

  `10,000 * N + 100`

  The payout and allocation change takes place at this block.

## Payout

The **CGP Contract** execution will return a valid transaction only if the following conditions hold:

1. There are sufficient funds for the CGP contract to cover all the outputs of the payout transaction.
2. The payout transaction contains at least 1 output and no more than 100 outputs.

## Allocation

With each mined block, in the coinbase transaction, a percentage of the reward of that block will be sent by the miner to the CGP contract.

This percentage is called “**The Coinbase Allocation**”.

## Voting

Users cast a ballot by sending the voting data (using the contract message body) to the Voting contract.

The Tally will count the votes, and determine the winner.

Users may vote for 2 independent items:

* `Allocation`: Users vote on the % of the block reward to be allocated to the CGP each block. (Nodes will not build on top of a block that does not contain a coinbase transaction with sufficient allocation output)
* `Payout`: Each voting interval users can vote on the recipient and the list of assets & amounts the recipient will receive

### Tally Calculation

At the end of the voting interval the tally will calculate the votes.

The Tally will only count the 1st vote for each PK, and only when it is executed within the voting interval. The vote also has to have a valid ballot to count.

### Allocation Ballot Validation

An allocation ballot is considered as valid as long as the following conditions hold:

1. It doesn’t exceed the upper allocation bound (`90%`).
2. It is no bigger and no smaller than the allocation correction cap (`15%`) relative (proportional) to the allocation of the last block.

### Payout Ballot Validation

Voting on payout is done in 2 phases, each with its own validity rules:

1. **Nomination Phase:**

   A payout ballot will become a valid nominee if the following conditions hold:

   a. At the snapshot the CGP contract has enough funds to cover it

   b. The spend list length is between 1 and 100 elements

   c. The spend list must be sorted in lexicographical order (over the asset ids) and the assets must to be unique

   d. The aggregated vote weight of the contestant is at least 3% of the total issued ZP at the snapshot block
2. **Voting Phase:**

   During the voting phase payout votes can only be made for a valid nominee.

   There is a special nominee which is always valid as long as there are sufficient funds in the CGP regardless of the results of the nomination, which is a payout of 1 kalapa to the CGP itself - this is the **default** vote which a user can vote on to effectively prevent a payout.


# Block Validation

The following validation rule has been added in the Common Goods Pool Update:

* The **coinbase transaction** may now contain an output with a **contract lock**, along with the usual **coinbase** output.
* To be sure that the CGP contract can always be executed we increase the upper limit of the block weight.

### Block Rewards

The previous implementation invalidates a coinbase transaction if it locks an output to anything besides the Coinbase lock.

We relax this restriction and consider a coinbase transaction valid if its outputs are locked to either a Coinbase lock or a Contract lock.

Whereas currently there is a fixed amount paid entirely to the miner who mines a block (using a Coinbase lock), this proposal would allow users to accept a block as valid only if the correct amount of ZP is locked to the CGP contract.

It will be possible to vote during a voting interval for a particular distribution of the block reward between the miner and the CGP.

The distribution of the block reward between the miner and CGP in a particular block will be determined by the vote in the previous voting interval.

The allocation winner resulting from votes in a particular voting interval will be the weighted median of votes for the allocation in that voting interval.

There will be a limit as to the largest possible percentage change in block reward distribution resulting from a vote in a single voting interval.

This proposal sets the bounds to the largest possible percentage change in the block reward distribution (% to miner's income) resulting from a vote in a single voting interval at `15%`.

The winning allocation % comes into effect 100 blocks (the size of the coinbase maturity) after the voting interval finishes.

## Connection

When extending the local blockchain we check:

1. The correct distribution of the block reward + fees, according to the allocations declared by the allocation tally winner.
2. The contract lock output is locked to the CGP contract, and the amount matches the payout tally winner.

The CGP contract must be executed one block before and added to the payout block.

For the payout block - the node checks that the following conditions hold:

1. If there is a payout winner for the tally of the previous interval - there must also be a payout in the payout block after that interval.
2. There is at most one payout transaction per payout block.
3. The payout transaction matches the payout winner of the tally.


# Transaction Validation

A description of how transactions are validated.

## Basic validation (pre-validation)

Each transaction has a non-empty list of inputs and a list of outputs. Each input is either

1. The unspent output of some other transaction
2. A **mint**, that is, a source of newly created tokens.

A transaction output becomes **spent** when used as the input to another transaction.

Each transaction input has a **spend**. A spend comprises an asset and an amount. The asset may refer either to a contract, or to the native Zen token. If it refers to a contract, it further identifies *which* of the contract’s assets is present. (A contract is free to create any of 2^256 assets, identified by a 256-bit value – the *subtype*.)

#### Rule: Inputs equal outputs

For each type of asset, the sum of the amounts of that asset in the inputs of a transaction must equal the sum of the asset’s amounts in the transaction outputs.

> For instance, suppose a transaction has three inputs: the first contains a spend of 10 Zen, the second a mint of 500 tokens from contract A, of subtype X, and the third a spend of 100 tokens from contract B, of subtype Y.\
> Then the transaction’s outputs with the Zen type must have amounts summing to 10, those with the A:X type must sum to 500, and those with the B:Y type must sum to 100. No other assets can be present in the outputs of the transaction.

#### Rule: No spendable zero-value outputs

Output locks are regarded as spendable if their outputs enter the UTXO pool. All other outputs, including *Destroy*, *Fee* and *Sacrifice* outputs, are regarded as unspendable. Spendable outputs must have an amount strictly greater than zero.

#### Spendable and Unspendable output locks

An output lock is spendable if its identifier is even. Odd identifiers denote unspendable output locks.

## Coinbase validation

A coinbase transaction is the first transaction in a block. It has special validation rules:

1. No inputs must be mints
2. All outputs must have **Coinbase** locks, or **Contracts** lock to the CGP address
3. The usual rules about validating a transaction are noy applied. In addition, contracts  cannot be  activated

The amount of tokens of any given type that may be minted in a coinbase transaction are bounded above by the sum of the *block reward* allocated to the miner and the *CGP a*llocation properly given too, the *claimable sacrifice*, and the total fees paid.

## Normal validation

Each transaction is validated *per-input*. For each input, zero or more witnesses provide information sufficient to prove that the input can be spent. The rules for validating this can refer to the whole transaction, or even to other parts of the blockchain (e.g. to UTXOs not spent in the transaction being verified, to the last block’s timestamp, etc.).

Transaction validation also keeps some state between validating each input. This is defined specifically for inputs with version-0 contract locks: each contract version will track intra-transaction state particular to that version. It is possible that a general state-passing mechanism for different lock-types to communicate will be available (via soft-fork) at some point.

In general, any input with an unknown type of lock can be spent with any number of witnesses, including zero, and any unknown type of witness can apply to any number of inputs (whether known or unknown), including zero.

A mint input implicitly has a contract lock, where the contract is given by the first part of its spend’s asset identifier. Mint inputs also have a version, defining the contract lock’s version. This is also given by the first part of the spend’s asset identifier.

> Note: The `ContractLock` defined below applies to **version-0 contracts**. Although high version mint inputs implicitly have high version contract locks, the release version does **not** define anything about a high version contract lock – neither its serialization nor its semantics.

Three types of spendable input lock are defined, along with a catch-all case for undefined spendable input locks:

### Unidentified lock

Inputs with these locks are validated. Advance the input index by one, without advancing the witness index.

> High version contract locks are validated like any other unidentified lock type. The only difference of any significance is that they are the kind of lock which mint inputs implicitly possess.

### PKLock

Read the next recognized witness. It must be of type PK. Further, the public key it contains must hash to the value in the PKLock. Then the signature must sign the transaction, as masked by the sighash. Advance the witness index by one.

### CoinbaseLock

If maturity is 100 or more, validated according to its nested lock. Otherwise fails. Advance the witness index by one.

### ContractLock (Version 0)

This is the tricky one. ContractLock’s require a version 0 contract witness to unlock. The same witness can unlock several successive inputs. Contract lock validation is stateful: a small amount of state can be written to and read from while validating a contract lock.

Contract locks validate roughly as follows:

* If the transaction validation state indicates that the input is already unlocked, skip further validation for this input.
* Read the contract witness.
* Get a truncated version of the transaction, by applying the lower limits of a “transaction mask” contained in the witness.
* Pass this truncated transaction to the contract function, a black-box that generates a new transaction.
* Check that this return transaction is *also* a prefix of the transaction being validated.
* Check that the return transaction matches the upper limits of the transaction mask.
* Update the state of transaction validation to record the bounds of this return transaction.
* Optionally, leave a message. This message can and must be consumed by *another*contract running to validate the next locked input of the tranasaction.

This mechanism allows the contract programmer to chain together multiple contracts, passing messages between them in sequence.

In detail, version 0 contract locks are validated as follows:

1. If the input’s index is less than the “inputBounds” parameter of the txvalidation state, the input is *inside* the validated result of running a contract. No more validation is done on the input.
2. Otherwise, check the message parameter of the txvalidation state. If the message is not `None`, then require that the lock’s contract hash is the same as the “recipient” parameter of the message. Then read the current witness and require that:
   * it be a contract witness, version 0, with contract hash matching the lock.
   * the transaction mask’s lower bounds (both for inputs and for outputs) match the bounds in the txvalidation state,
   * that the message matches the message in the txvalidation state.
3. If the message is `None`, then check only for a contract witness, version 0, with contract hash matching the lock.
4. Obtain an input transaction skeleton, by applying the lower transaction mask bounds to the transaction.
5. Run the contract function on this input transaction, the message, and other parameters, obtaining a transaction skeleton as a return, along with an optional message.
6. Check the return transaction skeleton matches the upper limits of the mask. Check that it matches the current transaction.
7. Update the state to set “sender” to the current transaction, “inputBounds” to the length of the return transaction’s input list, “outputBounds” to the length of the return transaction’s output list, and “message” to the message returned by the contract function.
8. Advance the witness index by one.

### End-of-transaction validation (post-validation)

After each input has been validated, check the transaction’s state. The message it contains must be “None”.

> Note: if a contract returns a message, and the next input does not have a contract lock, then at the latest, validation will fail here. This prevents a chain of contracts from being broken.

### Rule: No all-mint input lists

Non-coinbase transactions, all of whose inputs are mints, are invalid. This restriction ensures that all transactions have unique identifiers. (Coinbase transactions, which do have all-mint input lists, are identified by their blocks, so are uniquely identified in any case).


# Serialization

Serialization of consensus-relevant data types

## Amounts

&#x20;Amounts may take any integral value between 0 and 2^64 - 1. Amount serialization takes into account the fact that assets are often manipulated in quantities that are multiples of powers of ten.

Amount serialization has the following properties:

* Every value with 3 or fewer significant decimal figures has a two-byte representation.
* Every value with 8 or fewer significant decimal figures has a four-byte representation.
* Every value less than 2^56 has an eight-byte representation.
* Every value up to 2^64 - 1 has a nine-byte representation.

This compares to an uncompressed uint64 occupying eight bytes.

### Two byte/16 bit representation: up to 3 significant figures

| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Value                           | Notes                                                                                               |
| -- | -- | -- | -- | -- | -- | - | - | - | - | - | - | - | - | - | - | ------------------------------- | --------------------------------------------------------------------------------------------------- |
| 0  | 1  | 1  | 1  | 1  | 1  | 0 | x | x | x | x | x | x | x | x | x | NaN                             | "quiet" NaN                                                                                         |
| 0  | 1  | 1  | 1  | 1  | 0  | x | x | x | x | x | x | x | x | x | x | Infinity                        | Or overflow, underflow. Causes deserialization failure.                                             |
| 0  | a  | b  | e  | e  | e  | t | t | t | t | t | t | t | t | t | t | tttttttttt\_2 \* 10^(abeee\_2)  | Subject to ab != 11 (base 2)                                                                        |
| 0  | 1  | 1  | a  | b  | e  | e | e | t | t | t | t | t | t | t | t | 100tttttttt\_2 \* 10^(abeee\_2) | Subject to ab != 11 (base 2). This is a non-canonical representation (the client will not make it). |

### Four byte/32 bit representation: up to 8 significant figures

| 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | Value                                | Notes                                                                                               |
| -- | -- | -- | -- | -- | -- | -- | -- | ------------------------------------ | --------------------------------------------------------------------------------------------------- |
| 1  | 1  | 1  | 1  | 1  | 1  | 0  | x  | NaN                                  | quiet NaN                                                                                           |
| 1  | 1  | 1  | 1  | 1  | 0  | x  | x  | Infinity                             | Or overflow/underflow. Deserialization error.                                                       |
| 1  | 0  | e  | e  | e  | e  | t  | t  | ((tt\_2)\*2^24 + L) \* 10^(eeee\_2)  | 'L' is the unsigned big-endian value of the next 3 bytes.                                           |
| 1  | 1  | 1  | a  | b  | e  | e  | t  | ((10t\_2)\*2^24 + L) \* 10^(abee\_2) | Subject to ab != 11 (base 2). This is a non-canonical representation (the client will not make it). |
| 1  | 1  | 0  | e  | e  | e  | e  | t  | ((10t\_2)\*2^24 + L) \* 10^(eeee\_2) | Canonical representation of values with large significands (>= 2^26 and less than 10^8).            |

### Eight byte/64 bit representation: up to 2^56 - 1

| Highest byte | Seven lower bytes | Value | Notes                                     |
| ------------ | ----------------- | ----- | ----------------------------------------- |
| 0x7E/0x7F    | L                 | L     | 'L' is a 7-byte unsigned big-endian value |

### Nine byte/72 bit representation: at least 2^56

| Highest byte | Eight lower bytes | Value | Notes                                      |
| ------------ | ----------------- | ----- | ------------------------------------------ |
| 0xFE/0xFF    | L                 | L     | 'L' is an 8-byte unsigned big-endian value |

### Examples

```
Amount                  | Serialization
----------------------------------------------
0                       | 0x0000
1                       | 0x0001
5                       | 0x0005
10                      | 0x0401
20                      | 0x0402
100                     | 0x0801
200                     | 0x0802
1000                    | 0x0C01
1001                    | 0x800003E9
1999                    | 0x800007CF
2000                    | 0x0C02
1000000                 | 0x1801
1000001                 | 0x800F4241
1500000                 | 0x140F
74230000                | 0x90001CFF
1000000000              | 0x2401
1000000001              | 0x7E0000003B9ACA01
1000000000000           | 0x3001
10760000000000000000UL  | 0xB0A42F40
18446744073709551615UL  | 0xFEFFFFFFFFFFFFFFFF
```

## Assets

Assets have a **version,** a **contract hash** and a **subtype.** The version and contract hash together form the **contract id.** The version may take any uint32 value, the contract hash any 32-byte array value, and the subtype any 32-byte array value.

As a special case, the Zen native token has version 0, contract hash with all bytes set to zero, and subtype with all bytes set to zero.

Asset serialization is optimized to represent the Zen native token efficiently, as well as to efficiently represent assets with low version numbers and with subtypes that have many trailing zero bytes. As the subtype is under the control of the contract generating the asset, contract writers can gain some efficiency for the assets their contracts make, by giving them short subtypes.

Serialized assets use between one and 65 bytes. The first byte uses two bits for signalling, and six to encode the version. Between zero and four more bytes encode the rest of the version, followed by either zero or 32 bytes to represent the contract hash, followed by between zero and 32 bytes to represent the subtype.

### First byte

| 7                            | 6                | Rest of byte                     |
| ---------------------------- | ---------------- | -------------------------------- |
| Uncompressed representation? | Subtype present? | Version or upper part of version |

| First byte (base 2) | Version        | Contract Hash | Subtype  | More bytes?                 | Notes                                                                                                         |
| ------------------- | -------------- | ------------- | -------- | --------------------------- | ------------------------------------------------------------------------------------------------------------- |
| 00000000            | Zero           | Zero          | Zero     | No                          | Zen native token                                                                                              |
| 10000000            | Zero           | Non-zero      | Zero     | Yes, 32 more                | Contract's default asset                                                                                      |
| 11000000            | Zero           | Any           | Non-zero | Yes, 64 more                | Uncompressed subtype (32 bytes). Canonical iff the uncompressed subtype has 0 or 1 trailing zero bytes.       |
| 01000000            | Zero           | Any           | Non-zero | Yes, between 34 and 63 more | Compressed subtype (< 32 bytes). Canonical iff the uncompressed subtype has at least two trailing zero bytes. |
| xy0abcde            | abcde (base 2) | As above      | As above | Only if x <> 0 or y <> 0    | Represents versions between 0 and 31.                                                                         |
| xy1abcde            | >=32           | As above      | As above | Yes                         | Represents versions greater than or equal to 32. See below.                                                   |

### Version bytes

If the version is between 0 and 31, inclusive, there are no additional version bytes. The third most significant bit of the first byte is set to 0, and the lower five bits represent the version.

Versions are serialized by an algorithm similar to that used for protocol buffers' `varint` type. Between one and five bytes are used to represent the 32-bit version, including the first byte described above.

#### Bit patterns

| Version range    | Big-endian uncompressed version     | Bytes                                        |
| ---------------- | ----------------------------------- | -------------------------------------------- |
| 0 <= v < 32      | 000xxxxx                            | ??0xxxxx                                     |
| 32 <= v < 2^12   | 0000xxxx xyyyyyyy                   | ??1xxxxx 0yyyyyyy                            |
| 2^12 <= v < 2^19 | 00000xxx xxyyyyyy yzzzzzzz          | ??1xxxxx 1yyyyyyy 0zzzzzzz                   |
| 2^19 <= v < 2^26 | 000000xx xxxyyyyy yyzzzzzz zwwwwwww | ??1xxxxx 1yyyyyyy 1zzzzzzz 1wwwwwww          |
| 2^26 <= v        | xxxxyyyy yyyzzzzz zzwwwwww wvvvvvvv | ??10xxxx 1yyyyyyy 1zzzzzzz 1wwwwwww 1vvvvvvv |

The two most significant bits of the first byte, marked above as `??`, signal the type of compression used for the contract hash and subtype.

### Remaining bytes

#### Zen native asset – contract hash and subtype both zero

There are no further bytes. The top two bits of the first byte are set to zero.

#### Default contract asset – subtype is zero

The two first bits of the first (version) byte are set to `10`. After the version bytes, the next 32 bytes encode the contract hash.

#### Uncompressed subtype – subtype has at most one trailing zero byte

The first two bits of the first byte are set to `11`. After the version bytes, the next 32 bytes encode the contract hash, and a further 32 bytes encode the subtype.

#### Compressed subtype – subtype has at least two trailing zero bytes.

The first two bits of the first byte are set to `01`. After the version bytes, the next 32 bytes encode the contract hash. One byte encodes the 'size' of the subtype – i.e., 32 minus the number of trailing zero bytes. A further `size` bytes encode the leading bytes of the subtype.

### Examples

Versions are written as integers (decimal). The contract hash and subtype are written as arrays of bytes, of length 32.

```
Version: 0u
Hash:0x0000000000000000000000000000000000000000000000000000000000000000
Subtype:0x0000000000000000000000000000000000000000000000000000000000000000
==> 0x00

Version: 0u
Hash:0x1BFA2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B9C
Subtype:0x0000000000000000000000000000000000000000000000000000000000000000
==> 0x801BFA2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B9C

Version: 0u
Hash:0x1BFA2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B9C
Subtype:0x0000000000000000000000000000000000000000000000000000000000000000
==> 0xC01BFA2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B9CA42B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2BCB2C

Version: 0u
Hash:0x1BFA2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B9C
Subtype:0x1B2A000000000000000000000000000000000000000000000000000000000000
==> 0x401BFA2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B9C021B2A

Version: 7u
Hash:0x1BFA2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B9C
Subtype:0x0000000000000000000000000000000000000000000000000000000000000000
==> 0x871BFA2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B9C

Version: 31u
Hash:0x1BFA2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B9C
Subtype:0x0000000000000000000000000000000000000000000000000000000000000000
==> 0x9F1BFA2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B9C

Version: 32u
Hash:0x1BFA2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B9C
Subtype:
0x0000000000000000000000000000000000000000000000000000000000000000
==> 0xA0201BFA2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B9C

Version: 170u
Hash:0x1BFA2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B9C
Subtype:0x0000000000000000000000000000000000000000000000000000000000000000
==> 0xA12A1BFA2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B9C

Version: 4096u
Hash:0x1BFA2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B9C
Subtype:0x0000000000000000000000000000000000000000000000000000000000000000
==> 0xB4001BFA2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B9C

Version: 4096u
Hash:0x1BFA2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B9C
Subtype:0x1B2A000000000000000000000000000000000000000000000000000000000000
==> 0x74001BFA2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B9C021B2A
```


# Create Unsigned Transaction

Create your unsigned transaction using Zen Wallet in Watch Mode

{% hint style="info" %}
Only available in Watch Mode&#x20;
{% endhint %}

Watch Mode allows users to import public addresses or a public key, facilitating direct observation of wallet activity without the need to expose private keys.

**Access Watch Mode:** Connect in Watch Mode within the Zen Protocol Wallet.

**Create Unsigned Transactions:** Enter the transaction details, including the recipient's address, the amount of assets to send, and any additional parameters. It will generate an unsigned transaction  in hex format to copy.

**Review and Verification:** reviews the unsigned transaction details.

**Create Unsigned Transactions:** inputs the transaction details, including the recipient's address, the amount of cryptocurrency to send, and any additional parameters. It will generate a Raw Transaction  in Hex format to copy.

**Copying the Unsigned Transaction:** You have the option to send it to another party for their signature or sign it yourself.

**Signing and Publishing :** After confirming the signing process, click "Publish" to securely broadcast the signed transaction to the network

\ <br>


# Secure Sign Transaction

Secure, sign, and publish transactions using Zen Wallet Signer.

{% hint style="info" %}
Only Available on the PWA

Here the link: [Run Locally](/apps/wallet/web-wallet/run-locally)
{% endhint %}

The Signer component in the Zen Protocol PWA wallet enables users to both sign and publish unsigned transactions.\
The Watch Wallet mode allows the creation of unsigned transactions. \
The signer page allows the user to check the transaction before signing and publishing.&#x20;

1. **Paste the Unsigned Transaction created in the Watch Mode**

{% content-ref url="/pages/MKfE1sVUMkSrJncOfOam" %}
[Create Unsigned Transaction](/use-cases/create-unsigned-transaction)
{% endcontent-ref %}

2. **Prepare to Sign the Transaction**

* In the Signer section of the PWA Wallet paste the unsigned transaction.
* Review your unsigned transaction before signing.&#x20;
* Click "Sign" to securely sign the transaction.

3. **Publish Signed Transaction**

* Once signed successfully, verify the transaction and then click "Publish" to securely publish the signed transaction.


# Cold Storage using Full Node

## Cold Storage

The Zen-node supports cold storage out of the box.

To start, install the zen-node on a secure computer, run it and then create a wallet and export the public key:

```bash
# Create a new wallet
zen-cli wallet-create PASSWORD

# Backup the mnemonic phrase
zen-cli mnemonicphrase PASSWORD

# Export the zen public key to the hot-readonly machine
zen-cli exportzenpublickey
```

Now on the read-only machine (which is connected to the internet) run:

```bash
# Replace the public key with the one you got from the secure machine
zen-cli importzenpublickey xpub6BfTT2Gufvz2h7j8kPXRNcyTio4RMNx1LAt9JN3SyQpmT8sBsnjLujXFqba97VEvNcipMpcPNp5P7bUroGdneVbCAXqSW787zHorRZ8e4K  

# To retrieve your balance
zen-cli balance

# To get an address
zen-cli address
```

You can also generate unique addresses from the read-only wallet, to do so make sure to read the [payment processing](/apps/zen_js/payment-processing#payment-processing) page.

To send assets from the cold storage you first have to create the raw transaction. On the read-only machine run the following:

```bash
# Create a raw transaction, a new file with the hash of the transaction will be created
# 00 is the Zen asset identifier
# 1 is the amount (one kalapa)
# Replace the address with your address
zen-cli rawtx-create 00 1 zen1q3rjsrsdmyy3lmqxg7az5yvmpffflygeguljulwu476frqlruycrq5tgw4t

# Copy the created file to the Secure machine, e.g "6f3728e7de74872bd69796dac8f9964bb08a1459960ff10c308c133dd6e2f4f4.raw"
```

Copy the TXHASH.raw file to the secure machine and sign the file by running:

```bash
# The raw file will get updated, now with the signatures, copy it back to the readonly machine
zen-cli rawtx-sign PASSWORD 6f3728e7de74872bd69796dac8f9964bb08a1459960ff10c308c133dd6e2f4f4.raw
```

Back in the read-only machine, publish the transaction:

```
zen-cli rawtx-publish 6f3728e7de74872bd69796dac8f9964bb08a1459960ff10c308c133dd6e2f4f4.raw
```

###


# Responsible Disclosure

Our preferred reporting procedure is as follows:\
**For vulnerabilities in public-access code, such as the Zen Protocol node:**

* Visit our Gitlab at <https://gitlab.com/zenprotocol>, and open the appropriate project. (For bugs in ZFStar or the SDK, you'll have to visit our Github at <https://github.com/zenprotocol>.)<br>
* Open a confidential issue. **Do not** leave any information in the issue which could reveal the exploit.<br>
* We'll confirm our receipt of the issue, and that it is tagged as confidential.<br>
* Edit the issue to leave details of the vulnerability.<br>

**For vulnerabilities in our website or other non-public code/services:**

* Email <info@zenprotocol.com> with notification of a vulnerability, including in what service it is present.
* We'll confirm receipt.
* Reply to your Zen Protocol contact with details of the vulnerability.&#x20;

\
Our programme awards between $300 and $50,000+, at our sole discretion, for the responsible disclosure of security vulnerabilities. Participation in the paid bounty programme is not mandatory to receive credit for responsible disclosure. The terms for participation are:\
**For credit as a security researcher**

* Agreement to 30-day embargo. You should not disclose any details of the vulnerability within this period.
* Co-ordinated disclosure within the embargo period. We will inform you in advance of when we intend to publicize the vulnerability, and we will give you the opportunity to write your own report, to be issued simultaneously. We would be happy to link to your own report.
* Full disclosure. You should inform us, to the best of your knowledge, of all details of the vulnerability. Should you discover additional information about or relating to the vulnerability, you should inform us as soon as possible.

**For eligibility to receive a bounty**

* **All the above terms**, as well as:
* Extension to 60-day embargo. We may request to extend the embargo to 60 days.
* Identification. We may require you identify yourself to us. We promise to keep this information confidential.
* Award at our discretion. We will evaluate the severity of the vulnerability and determine what bounty should be awarded. You agree that the evaluation and award are made at our sole discretion.

Additionally, if you wish to be eligible to receive a bounty, you should inform us at the start of the disclosure process.<br>


# Bug Bounty

Learn more about our bug bounty .

## Instructions

Please read the [troubleshooting](https://docs.zenprotocol.com/troubleshooting) section or the [known bugs Trello board](https://trello.com/b/lG3GaSM5/zen-protocol-bug-bounty). If you encounter a new bug please document it by filling out the form [here](https://docs.google.com/forms/d/e/1FAIpQLSd4IOHhzFvPEwNPFofMMSTq8A_smQRIBAx-gCtysKrkmCAWFw/viewform?usp=sf_link).

This form is used to gather feedback and bugs. We ask people to film the bug so we can efficiently review the error and make sure to fix it for future users.

A reward of 5 - 200 Zen Protocol tokens will be given per bug. For system critical issues, you can check our responsible [disclosure section](https://docs.zenprotocol.com/responsible-disclosure).

### Bug 1: Wallet not opening (error "address already in use")

This happens because the zen-node is still running in the background.

### Solution:

1. Look for all processes currently running using the name zen. Enter the command:\
   &#x20;    `ps aux | grep zen`
2. Stop these processes. Enter the command:\
   &#x20;    `pkill -f zen`OR `killall mono`
3. Open wallet (see [instructions](https://docs.zenprotocol.com/docs/~/edit/primary/desktop_wallet))

#### If that didn't work try:

1. Use `\netstat -tulpn`to find the process you need to terminate
2. Run `kill -9 PID`&#x20;


# Known Bugs

Some known issues and solutions to deal with them. Commands should be run from Terminal or Linux Command Line.

### Windows Errors: How to check logs:

In order to see the logs and help troubleshoot your error please use the commands below:\
Press the win + r buttons and then type `eventvwr`, go to applications and post any errors related to zen-node.

### Problem 1: I have ZENP tokens that I mined but cannot use them.

### Solution:

Mined tokens are not able to be used until 100 blocks after they have been mined. Please wait for these blocks to pass and then try again.&#x20;

## Want to report another bug?

* If you cannot find your issue in the section above please fill out the form here. Remember to include  pictures, copies of the log, and any other information you think is relevant and we will get back to you with a solution, and post it for others to learn from.


# Pools

* [ZenPool](https://miners.zp.io)
* [Leafpool](https://zp.leafpool.com/) (deprecated)
* [ZenProtocolPool](https://www.zenprotocolpool.com/) (deprecated)


# GPU Mining

## Nvidia/CUDA

Currently, the best option is Protovist's patch of ccminer on Ubuntu.

Instructions:

* Ubuntu 16.04 is known to work.
* Install the Zen Protocol wallet.
* Obtain the exact versions of CUDA (9.2.11-1) and openssl (1.1.1-pre8) needed:

```
sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub
sudo apt update
sudo apt dist-upgrade
sudo apt install build-essential automake
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-repo-ubuntu1604_9.2.88-1_amd64.deb
sudo dpkg -i cuda-repo-ubuntu1604_9.2.88-1_amd64.deb
sudo apt install libcurl4-openssl-dev 
sudo apt-get update
sudo apt-get install cuda
wget https://www.openssl.org/source/openssl-1.1.1-pre8.tar.gz
tar zxf openssl-1.1.1-pre8.tar.gz
cd openssl-1.1.1-pre8/
./config
make -j8
sudo make install
cd ..

```

* Get the right version of ccminer:

```
git clone https://github.com/protovist/ccminer.git
cd ccminer
git checkout zenprotocol
./build.sh
```

* Run the Zen Protocol client and create or import an account.
* Run ccminer, pointing it to the Zen Protocol client, like this:

```
./ccminer -a zenprotocol -o 127.0.0.1:11567
```

For a pool, change `127.0.0.1:11567` to the pool address.

## AMD

Proper AMD mining support is still in development. Right now you need to compile your own Zen Protocol node.

Instructions:

* Checkout or download the cgminer branch at [https://gitlab.com/zenprotocol/zenprotocol/tree/cgminer ](https://gitlab.com/zenprotocol/zenprotocol/tree/cgminer)
* Follow the instructions for building the Zen Protocol node.
* Get a patched cgminer from <https://github.com/A-Manning/cgminer_zp>
* Compile cgminer
* Run cgminer as follows:

```
cgminer --keccak -o http://127.0.0.1:11567
```




---

[Next Page](/llms-full.txt/1)

