# Planetmint

Meet Planetmint. The metadata blockchain.

It has some database characteristics and some blockchain `properties <properties.html>`\_, including decentralization, immutability and native support for assets.

At a high level, one can communicate with a Planetmint network (set of nodes) using the Planetmint HTTP API, or a wrapper for that API, such as the Planetmint Python Driver. Each Planetmint node runs Planetmint Server and various other software. The `terminology page <terminology.html>`\_ explains some of those terms in more detail.

### Table of Contents

* [Introduction](/introduction)
  * [What is Planetmint?](/introduction/about-planetmint)
    * [Basic Facts](/introduction/about-planetmint#basic-facts)
  * [Properties of Planetmint](/introduction/properties)
  * [Quickstart](/introduction/quickstart)
    * [IPDB Testnet- Sending Transactions](/introduction/quickstart#the-ipdb-testnet-sending-transactions)
    * [Installing Planetmint](/introduction/quickstart#install-planetmint)
* [Using Planetmint](/using-planetmint)
  * [Transactions in Planetmint](/using-planetmint#transactions-in-planetmint)
    * [CREATE Transactions](/using-planetmint#create-transactions)
    * [TRANSFER Transactions](/using-planetmint#transfer-transactions)
    * [Transaction Validity](/using-planetmint#transaction-validity)
  * [A Note on IPLD marshalling and CIDs](/using-planetmint#a-note-on-ipld-marshalling-and-cids)
  * [Contracts & Conditions](/using-planetmint#contracts--conditions)
  * [Zenroom Smart Contracts and Policies](/using-planetmint#zenroom-smart-contracts-and-policies)


# Introduction

Planetmint is a metadata blockchain. This introduction gives an overview of how to attest data to Planetmint. First, simple transaction creation and sending are shown. Thereafter, an introduction about how to set up a single node or a cluster is given.

In this section, we will take a deeper look at Planetmint, its properties and how you can get started with installation and setup.

### Table of Contents

* [What is Planetmint? ](/introduction/about-planetmint)
  * [Basic Facts](/introduction/about-planetmint#basic-facts)
  * [Planetmint for Asset Registration & Transfers](/introduction/about-planetmint#planetmint-for-asset-registrations-and-transfers)&#x20;
  * [Storing Private Data Off-Chain](/introduction/about-planetmint#storing-private-data-off-chain)
  * [Storing Private Data On-Chain, Encrypted](/introduction/about-planetmint#storing-private-data-on-chain-encrypted)
* [Properties of Planetmint](/introduction/properties)
  * [Decentralisation](/introduction/properties#decentralization)&#x20;
  * [Byzantine Fault Tolerance](/introduction/properties#byzantine-fault-tolerance)&#x20;
  * [Node Diversity](/introduction/properties#node-diversity)
  * [Immutability](/introduction/properties#immutability)
* [Quickstart](/introduction/quickstart)&#x20;
  * [IPDB Testnet- Sending Transactions](/introduction/quickstart#the-ipdb-testnet-sending-transactions)
  * [Installing Planetmint](/introduction/quickstart#install-planetmint)
    * [Local Node](/introduction/quickstart#local-node)
    * [Cluster of Nodes](/introduction/quickstart#cluster-of-nodes)
    * [Setup Instructions for Various Cases](/introduction/quickstart#setup-instructions-for-various-cases)
    * [Developing an App Test](/introduction/quickstart#develop-an-app-test)


# What is Planetmint?

## Basic Facts

1. One can store arbitrary data (including encrypted data) in a Planetmint network, within limits: there’s a maximum transaction size. Every transaction has a `metadata` section which can store almost any Unicode string (up to some maximum length). Similarly, every CREATE transaction has an `asset.data` section which can store almost any Unicode string.
2. The data stored in certain Planetmint transaction fields must not be encrypted, e.g. public keys and amounts. Planetmint doesn’t offer private transactions akin to Zcoin.
3. Once data has been stored in a Planetmint network, it’s best to assume it can’t be change or deleted.
4. Every node in a Planetmint network has a full copy of all the stored data.
5. Every node in a Planetmint network can read all the stored data.
6. Everyone with full access to a Planetmint node (e.g. the sysadmin of a node) can read all the data stored on that node.
7. Everyone given access to a node via the Planetmint HTTP API can find and read all the data stored by Planetmint. The list of people with access might be quite short.
8. If the connection between an external user and a Planetmint node isn’t encrypted (using HTTPS, for example), then a wiretapper can read all HTTP requests and responses in transit.
9. If someone gets access to plaintext (regardless of where they got it), then they can (in principle) share it with the whole world. One can make it difficult for them to do that, e.g. if it is a lot of data and they only get access inside a secure room where they are searched as they leave the room.

## Planetmint for Asset Registrations & Transfers

Planetmint can store data of any kind, but it’s designed to be particularly good for storing asset registrations and transfers:

* The fundamental thing that one sends to a Planetmint network, to be checked and stored (if valid), is a *transaction*, and there are two kinds: CREATE transactions and TRANSFER transactions.
* A CREATE transaction can be use to register any kind of asset (divisible or indivisible), along with arbitrary metadata.
* An asset can have zero, one, or several owners.
* The owners of an asset can specify (crypto-)conditions which must be satisfied by anyone wishing transfer the asset to new owners. For example, a condition might be that at least 3 of the 5 current owners must cryptographically sign a TRANSFER transaction.
* Planetmint verifies that the conditions have been satisfied as part of checking the validity of TRANSFER transactions. (Moreover, anyone can check that they were satisfied.)
* Planetmint prevents double-spending of an asset.
* Validated transactions are immutable.

**Note**

We used the word “owners” somewhat loosely above. A more accurate word might be fulfillers, signers, controllers, or transfer-enablers. See the section titled **A Note about Owners** in the relevant [Planetmint Transactions Spec](https://github.com/Planetmint/PRPs/tree/master/tx-specs/).

## Production-Ready?

Depending on your use case, Planetmint may or may not be production-ready. You should ask your service provider. If you want to go live (into production) with Planetmint, please consult with your service provider.

Note: Planetmint has an open source license with a “no warranty” section that is typical of open source licenses. This is standard in the software industry. For example, the Linux kernel is used in production by billions of machines even though its license includes a “no warranty” section. Warranties are usually provided above the level of the software license, by service providers.

## Storing Private Data Off-Chain

A system could store data off-chain, e.g. in a third-party database, document store, or content management system (CMS) and it could use Planetmint to:

* Keep track of who has read permissions (or other permissions) in a third-party system. An example of how this could be done is described below.
* Keep a permanent record of all requests made to the third-party system.
* Store hashes of documents-stored-elsewhere, so that a change in any document can be detected.
* Record all handshake-establishing requests and responses between two off-chain parties (e.g. a Diffie-Hellman key exchange), so as to prove that they established an encrypted tunnel (without giving readers access to that tunnel). There are more details about this idea in [the Privacy Protocols repository](https://github.com/Bigchaindb/privacy-protocols).

A simple way to record who has read permission on a particular document would be for the third-party system (“DocPile”) to store a CREATE transaction in a Planetmint network for every document+user pair, to indicate that that user has read permissions for that document. The transaction could be signed by DocPile (or maybe by a document owner, as a variation). The asset data field would contain 1) the unique ID of the user and 2) the unique ID of the document. The one output on the CREATE transaction would only be transferable/spendable by DocPile (or, again, a document owner).

To revoke the read permission, DocPile could create a TRANSFER transaction, to spend the one output on the original CREATE transaction, with a metadata field to say that the user in question no longer has read permission on that document.

This can be carried on indefinitely, i.e. another TRANSFER transaction could be created by DocPile to indicate that the user now has read permissions again.

DocPile can figure out if a given user has read permissions on a given document by reading the last transaction in the CREATE → TRANSFER → TRANSFER → etc. chain for that user+document pair.

There are other ways to accomplish the same thing. The above is just one example.

You might have noticed that the above example didn’t treat the “read permission” as an asset owned (controlled) by a user because if the permission asset is given to (transferred to or created by) the user then it cannot be controlled any further (by DocPile) until the user transfers it back to DocPile. Moreover, the user could transfer the asset to someone else, which might be problematic.

## Storing Private Data On-Chain, Encrypted

There are many ways to store private data on-chain, encrypted. Every use case has its own objectives and constraints, and the best solution depends on the use case. [The IPDB consulting team](mailto:contact%40ipdb.global) can help you design the best solution for your use case.

Below we describe some example system setups, using various crypto primitives, to give a sense of what’s possible.

Please note:

* Ed25519 keypairs are designed for signing and verifying cryptographic signatures, [not for encrypting and decrypting messages](https://crypto.stackexchange.com/questions/27866/why-curve25519-for-encryption-but-ed25519-for-signatures). For encryption, you should use keypairs designed for encryption, such as X25519.
* If someone (or some group) publishes how to decrypt some encrypted data on-chain, then anyone with access to that encrypted data will be able to get the plaintext. The data can’t be deleted.
* Encrypted data can’t be indexed or searched by MongoDB. (It can index and search the ciphertext, but that’s not very useful.) One might use homomorphic encryption to index and search encrypted data, but MongoDB doesn’t have any plans to support that any time soon. If there is indexing or keyword search needed, then some fields of the `asset.data` or `metadata` objects can be left as plain text and the sensitive information can be stored in an encrypted child-object.

## Examples

### System Example 1

Encrypt the data with a symmetric key and store the ciphertext on-chain (in `metadata` or `asset.data`). To communicate the key to a third party, use their public key to encrypt the symmetric key and send them that. They can decrypt the symmetric key with their private key, and then use that symmetric key to decrypt the on-chain ciphertext.

The reason for using a symmetric key along with public/private keypairs is so the ciphertext only has to be stored once.

### System Example 2

This example uses [proxy re-encryption](https://en.wikipedia.org/wiki/Proxy_re-encryption):

1. MegaCorp encrypts some data using its own public key, then stores that encrypted data (ciphertext 1) in a Planetmint network.
2. MegaCorp wants to let others read that encrypted data, but without ever sharing their private key and without having to re-encrypt themselves for every new recipient. Instead, they find a “proxy” named Moxie, to provide proxy re-encryption services.
3. Zorban contacts MegaCorp and asks for permission to read the data.
4. MegaCorp asks Zorban for his public key.
5. MegaCorp generates a “re-encryption key” and sends it to their proxy, Moxie.
6. Moxie (the proxy) uses the re-encryption key to encrypt ciphertext 1, creating ciphertext 2.
7. Moxie sends ciphertext 2 to Zorban (or to MegaCorp who forwards it to Zorban).
8. Zorban uses his private key to decrypt ciphertext 2, getting the original un-encrypted data.

**Note**

* The proxy only ever sees ciphertext. They never see any un-encrypted data.
* Zorban never got the ability to decrypt ciphertext 1, i.e. the on-chain data.
* There are variations on the above flow.

### System Example 3

This example uses [erasure coding](https://en.wikipedia.org/wiki/Erasure_code):

1. Erasure-code the data into n pieces.
2. Encrypt each of the n pieces with a different encryption key.
3. Store the n encrypted pieces on-chain, e.g. in n separate transactions.
4. Share each of the the n decryption keys with a different party.

If k < N of the key-holders gets and decrypts k of the pieces, they can reconstruct the original plaintext. Less than k would not be enough.

### System Example 4

This setup could be used in an enterprise blockchain scenario where a special node should be able to see parts of the data, but the others should not.

* The special node generates an X25519 keypair (or similar asymmetric *encryption* keypair).
* A Planetmint end user finds out the X25519 public key (encryption key) of the special node.
* The end user creates a valid Planetmint transaction, with either the asset.data or the metadata (or both) encrypted using the above-mentioned public key.
* This is only done for transactions where the contents of asset.data or metadata don’t matter for validation, so all node operators can validate the transaction.
* The special node is able to decrypt the encrypted data, but the other node operators can’t, and nor can any other end user.


# Properties of Planetmint

## Decentralization

Decentralization means that no one owns or controls everything, and there is no single point of failure.

Ideally, each node in a Planetmint network is owned and controlled by a different person or organization. Even if the network lives within one organization, it's still preferable to have each node controlled by a different person or subdivision.

We use the phrase "Planetmint consortium" (or just "consortium") to refer to the set of people and/or organizations who run the nodes of a Planetmint network. A consortium requires some form of governance to make decisions such as membership and policies. The exact details of the governance process are determined by each consortium, but it can be very decentralized.

A consortium can increase its decentralization (and its resilience) by increasing its jurisdictional diversity, geographic diversity, and other kinds of diversity.

There’s no node that has a long-term special position in the Planetmint network. All nodes run the same software and perform the same duties.

If someone has (or gets) admin access to a node, they can mess with that node (e.g. change or delete data stored on that node), but those changes should remain isolated to that node. The Planetmint network can only be compromised if more than one third of the nodes get compromised. See the [Tendermint documentation](https://docs.tendermint.com/v0.34/introduction/what-is-tendermint.html) for more details.

It’s worth noting that not even the admin or superuser of a node can transfer assets. The only way to create a valid transfer transaction is to fulfill the current crypto-conditions on the asset, and the admin/superuser can’t do that because the admin user doesn’t have the necessary information (e.g. private keys).

## Byzantine Fault Tolerance

[Tendermint](https://www.tendermint.com/) is used for consensus and transaction replication, and Tendermint is [Byzantine Fault Tolerant (BFT)](https://en.wikipedia.org/wiki/Byzantine_fault_tolerance).

## Node Diversity

Steps should be taken to make it difficult for any one actor or event to control or damage “enough” of the nodes. (Because Planetmint Server uses Tendermint, "enough" is ⅓.) There are many kinds of diversity to consider, listed below. It may be quite difficult to have high diversity of all kinds.

1. **Jurisdictional diversity.** The nodes should be controlled by entities within multiple legal jurisdictions, so that it becomes difficult to use legal means to compel enough of them to do something.
2. **Geographic diversity.** The servers should be physically located at multiple geographic locations, so that it becomes difficult for a natural disaster (such as a flood or earthquake) to damage enough of them to cause problems.
3. **Hosting diversity.** The servers should be hosted by multiple hosting providers (e.g. Amazon Web Services, Microsoft Azure, Digital Ocean, Rackspace), so that it becomes difficult for one hosting provider to influence enough of the nodes.
4. **Diversity in general.** In general, membership diversity (of all kinds) confers many advantages on a consortium. For example, it provides the consortium with a source of various ideas for addressing challenges.

**Note:** If all the nodes are running the same code, i.e. the same implementation of Planetmint, then a bug in that code could be used to compromise all of the nodes. Ideally, there would be several different, well-maintained implementations of Planetmint Server (e.g. one in Python, one in Go, etc.), so that a consortium could also have a diversity of server implementations. Similar remarks can be made about the operating system.

## Immutability

The blockchain community often describes blockchains as “immutable.” If we interpret that word literally, it means that blockchain data is unchangeable or permanent, which is absurd. The data *can* be changed. For example, a plague might drive humanity extinct; the data would then get corrupted over time due to water damage, thermal noise, and the general increase of entropy.

It’s true that blockchain data is more difficult to change (or delete) than usual. It's more than just "tamper-resistant" (which implies intent), blockchain data also resists random changes that can happen without any intent, such as data corruption on a hard drive. Therefore, in the context of blockchains, we interpret the word “immutable” to mean *practically* immutable, for all intents and purposes. (Linguists would say that the word “immutable” is a *term of art* in the blockchain community.)

Blockchain data can be made immutable in several ways:

1. **No APIs for changing or deleting data.** Blockchain software usually doesn't expose any APIs for changing or deleting the data stored in the blockchain. Planetmint has no such APIs. This doesn't prevent changes or deletions from happening in *other* ways; it's just one line of defense.
2. **Replication.** All data is replicated (copied) to several different places. The higher the replication factor, the more difficult it becomes to change or delete all replicas.
3. **Internal watchdogs.** All nodes monitor all changes and if some unallowed change happens, then appropriate action can be taken.
4. **External watchdogs.** A consortium may opt to have trusted third-parties to monitor and audit their data, looking for irregularities. For a consortium with publicly-readable data, the public can act as an auditor.
5. **Economic incentives.** Some blockchain systems make it very expensive to change old stored data. Examples include proof-of-work and proof-of-stake systems. Planetmint doesn't use explicit incentives like those.
6. Data can be stored using fancy techniques, such as error-correction codes, to make some kinds of changes easier to undo.
7. **Cryptographic signatures** are often used as a way to check if messages (e.g. transactions) have been tampered with enroute, and as a way to verify who signed the messages. In Planetmint, each transaction must be signed by one or more parties.
8. **Full or partial backups** may be recorded from time to time, possibly on magnetic tape storage, other blockchains, printouts, etc.
9. **Strong security.** Node owners can adopt and enforce strong security policies.


# Quickstart

Planetmint is a metadata blockchain. This introduction gives an overview about how to attest data to Planetmint. First, simple transaction creation and sending is shown. Thereafter, an introdcution about how to set up a single node or a cluster is given.

### The IPDB Testnet - sending transactions

The IPDB foundation hosts a testnet server that is reset every night at 4am UTC.

The following sequence shows a simple asset notarization / attestion on that testnet: Create a file named notarize.py

```python
from planetmint_driver import Planetmint
from planetmint_driver.crypto import generate_keypair
from ipld import marshal, multihash

plntmnt = Planetmint('https://test.ipdb.io')
alice = generate_keypair()
tx = plntmnt.transactions.prepare(
    operation='CREATE',
    signers=alice.public_key,
    assets=[
        {'data': 
            multihash(marshal({'message': 'Blockchain all the things!'}))
            }   
    ]
)
signed_tx = plntmnt.transactions.fulfill(tx, private_keys=alice.private_key)
print(plntmnt.transactions.send_commit(signed_tx))
```

install dependencies and execute it

```bash

$ pip install planetmint-driver>=0.14.0
$ python notarize.py
```

## Install Planetmint

### Local Node

Planetmint is a Tendermint application with an attached database. A basic installation setup installs the database, Tendermint and thereafter Planetmint.&#x20;

Planetmint currently supports Tarantool and MongoDB databases. The installation is as follows:

```bash
# Tarantool
$ curl -L https://tarantool.io/release/2/installer.sh | bash 
$ sudo apt-get -y install tarantool
```

*Caveat:* Tarantool versions before [2.4.2](https://www.tarantool.io/en/doc/latest/release/2.4.2/) automatically enable and start a demonstration instance that listens on port `3301` by default. Refer to the [Tarantool documentation](https://www.tarantool.io/en/doc/latest/getting_started/getting_started_db/#creating-db-locally) for more information.

```bash
# MongoDB
$ sudo apt install mongodb
```

Tendermint can be installed and started as follows

```bash
$ wget https://github.com/tendermint/tendermint/releases/download/v0.34.15/tendermint_0.34.15_linux_amd64.tar.gz
$ tar zxf tendermint_0.34.15_linux_amd64.tar.gz
$ ./tendermint init
$ ./tendermint node --proxy_app=tcp://localhost:26658
```

Planetmint installs and starts as described below

```bash
$ pip install planetmint
$ planetmint configure
$ planetmint start
```

### Cluster of nodes

Setting up a cluster of nodes comes down to set up a cluster of tendermint nodes as documented at [Tendermint](https://docs.tendermint.com/v0.35/introduction/quick-start.html#cluster-of-nodes). In addition to that, the database and Planetmint need to be installed on the servers as described above.

### Setup Instructions for Various Cases

Quickstart link below

* [Set up a local Planetmint node](/node-setup) for development, experimenting and testing&#x20;
* [Set up and run a Planetmint network](/network-setup)

### Develop an App Test

To develop an app that talks to a Planetmint network, you'll want a test network to test it against. You have a few options:

1. The IPDB Test Network (or "Testnet") is a free-to-use, publicly-available test network that you can test against. It is available at [IPDB testnet](https://test.ipdb.io/).
2. You could also run a Planetmint node on you local machine. One way is to use this node setup guide with a one-node "network" by using the all-in-one docker solution, or manual installation and configuration of the components. Another way is to use one of the deployment methods listed in the [network setup guide](/network-setup) or in the [the docs about contributing to Planetmint](https://github.com/planetmint/docs/blob/main/references/contributing/index/README.md).


# Using Planetmint

In this section, we will explore the different kinds of transactions available on Planetmint, as well as the role of cryptoconditions and contracts and its integration into Planetmint.

## Transactions in Planetmint

In Planetmint, *transactions* are used to register, issue, create or transfer things (e.g. assets). Transactions are the most basic kind of record stored by Planetmint.

There are two kinds:

* CREATE transactions, and
* TRANSFER transactions.

You can view the transaction specifications on [Github](https://github.com/bigchaindb/BEPs/tree/master/13/), which describe transaction components and the conditions they must fulfil to be valid.

### Transaction v3.0

Planetmint migrated to transaction scheme version 3.0. \
Details can be found at the [GitHub Transaction Repository](https://github.com/planetmint/transactions/tree/main/transactions/common/schema). The changes are as follows:<br>

* `asset` has been migrated to `assets`
* `assets` contains an array of asset descriptions instead of 1 asset description
* The `data` attribute of the an asset description contains a [CID](#a-note-on-ipld-marshalling-and-cids)
* `metadata` attribute of the transaction contains a [CID](#a-note-on-ipld-marshalling-and-cids)

Below is an tabular overview about the changes.<br>

|            | Version 2.0                                                                                                                       | Version 3.0                                                                                                                                                                                                                       |
| ---------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `assets`   | <p><code>asset</code> contains a data JSON object and/or an ID string.<br><code>"asset": { "data" : {...}, "id" : "" }</code></p> | <p><code>assets</code> contains a list of assets desriptons with each data attribute being a <a href="#a-note-on-ipld-marshalling-and-cids">CID</a>.<br><code>"assets": \[{ "data" : \<CID>, "id" : "" }, {...}, ... ]</code></p> |
| `metadata` | <p>Metadata contained a json object. <br><code>"metadata": {...}</code></p>                                                       | <p>Metadata contains a <a href="#a-note-on-ipld-marshalling-and-cids">CID</a><br><code>"metadata": \<CID></code></p>                                                                                                              |

### CREATE Transactions

A CREATE transaction can be used to register, issue, create or otherwise initiate the history of a single thing (or asset) in Planetmint. For example, one might register an identity or a creative work. The items are often called “assets”, but they might not be literal assets.

Planetmint supports divisible assets as of Planetmint Server v0.8.0. That means you can create/register an asset with an initial number of “shares.” For example, A CREATE transaction could register a truckload of 50 oak trees. Each share of a divisible asset must be interchangeable with each other share; the shares must be fungible.

A CREATE transaction can have one or more outputs. Each output has an associated amount: the number of shares tied to that output. For example, if the asset consists of 50 oak trees, one output might have 35 oak trees for one set of owners, and the other output might have 15 oak trees for another set of owners.

Each output also has an associated condition: the condition that must be met (by a TRANSFER transaction) to transfer/spend the output. Planetmint supports a variety of conditions. For details, see **Transaction Components: Conditions** in the relevant [Planetmint Transactions Spec](https://github.com/bigchaindb/BEPs/tree/master/13/).

![Example Planetmint CREATE transaction](https://github.com/planetmint/docs/blob/main/using-planetmint/_static/CREATE_example.png)

Above we see a diagram of an example Planetmint CREATE transaction. It has one output: Pam owns/controls three shares of the asset, and there are no other shares (because there are no other outputs).

Each output also has a list of all the public keys associated with the conditions on that output. That list might be interpreted as the list of “owners.” A more accurate word might be fulfillers, signers, controllers, or transfer enablers. See the section titled **A Note about Owners** in the relevant [Planetmint Transactions Spec](https://github.com/bigchaindb/BEPs/tree/master/13/).

A CREATE transaction must be signed by all the owners. (If you’re looking for that signature, it’s in the one “fulfilment” of the one input, albeit encoded.)

### TRANSFER Transactions

A TRANSFER transaction can transfer/spend one or more outputs on other transactions (CREATE transactions or other TRANSFER transactions). Those outputs must all be associated with the same asset; a TRANSFER transaction can only transfer shares of one asset at a time.

Each input on a TRANSFER transaction connects to one output on another transaction. Each input must satisfy the condition on the output it’s trying to transfer/spend.

A TRANSFER transaction can have one or more outputs, just like a CREATE transaction (described above). The total number of shares coming in on the inputs must equal the total number of shares going out on the outputs.

Above, we see a diagram of two example Planetmint transactions, a CREATE transaction and a TRANSFER transaction. The CREATE transaction is the same as in the earlier diagram. The TRANSFER transaction spends Pam’s output, so the input on that TRANSFER transaction must contain a valid signature from Pam (i.e. a valid fulfilment). The TRANSFER transaction has two outputs: Jim gets one share, and Pam gets the remaining two shares.

**Terminology**: The “Pam, 3” output is called a “spent transaction output”, and the “Jim, 1” and “Pam, 2” outputs are called “unspent transaction outputs” (UTXOs).

**Example 1:** Suppose a red car is owned and controlled by Joe. Suppose the current transfer condition on the vehicle says that any valid transfer must be signed by Joe. Joe could build a TRANSFER transaction containing an input with Joe’s signature (to fulfil the current output condition) plus a new output condition saying that any valid transfer must be signed by Rae.

**Example 2:** Someone might construct a TRANSFER transaction that fulfils the output conditions on four previously-untransferred assets of the same asset type, e.g. paperclips. The amounts might be 20, 10, 45 and 25, say, for a total of 100 paper clips. The TRANSFER transaction would also set up new transfer conditions. For example, maybe a set of 60 paperclips can only be transferred if Gertrude signs, and a separate set of 40 paperclips can only be transferred if both Jack and Kelly sign. Note how the sum of the incoming paper clips must equal the sum of the outgoing paperclips (100).

### Transaction Validity

When a node is asked to check if a transaction is valid, it checks several things. This got documented by a BigchainDB post (previous version of Planetmint) at*The BigchainDB Blog*: ["What is a Valid Transaction in BigchainDB?"](https://blog.bigchaindb.com/what-is-a-valid-transaction-in-planetmint-9a1a075a9598) (Note: That post was about Planetmint Server v1.0.0.)

## A Note on IPLD marshalling and CIDs

Planetmint utilizes IPLD (interplanetary linked data) marshalling and CIDs (content identifiers) to store and verify data. Before submitting a transaction to the network the data is marshalled using [py-ipld](https://github.com/planetmint/py-ipld) and instead of the raw data a CID is stored on chain.

The CID is a self describing data structure. It contains information about the encoding, cryptographic algorithm, length and the actual hashvalue. For example the CID `bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi` tells us the following:

```
Encoding: base32
Codec: dag-pb (MerkleDAG protobuf)
Hashing-Algorithm: sha2-256
Digest (Hex): C3C4733EC8AFFD06CF9E9FF50FFC6BCD2EC85A6170004BB709669C31DE94391A
```

With this information we can validate that information about an asset we've received is actually valid.

The changes from version v2.0 on are as follows:

### Example Transactions

There are example Planetmint transactions in [the HTTP API documentation](https://github.com/planetmint/docs/blob/main/using-planetmint/connecting/http-client-server-api/README.md) and [the Python Driver documentation](https://github.com/planetmint/planetmint-driver-python).

## Contracts & Conditions

Planetmint has been developed with simple logical gateways in mind. The logic got introduced by [cryptoconditions](https://github.com/planetmint/cryptoconditions). The cryptocondition documentation contains all details about how conditoins are defined and how they can be verified and fulfilled.

The integration of such into the transaction schema of Planetmint is shown below.


# Zenroom Smart Contracts & Policies

[Zenroom](https://zenroom.org/) contracts are part of Planetmint's transactions specification. They can be utilized to attest the computation of certain logic to the network. To do so, a [Zenroom](https://zenroom.org/) contract can be defined with given inputs and the expected outputs of the computation. This will then be submitted to the network, where a node can validate the logic execution and output.

Previously [Zenroom](https://zenroom.org/) was integrated into [cryptoconditions](https://github.com/planetmint/cryptoconditions) to allow for human-readable conditions and fulfilments. These contracts were stateless, which implies that the conditions and fulfilments need to be transacted in the same transaction. However, [PRP-10](https://github.com/planetmint/PRPs/tree/main/10) aims to make stateful smart contracts possible, enabling asynchronous and party-independent contract processing.

As for network-wide or asset-based policies, [PRP-11](https://github.com/planetmint/PRPs/tree/main/11) specifies how these can be implemented and how these can be used to verify a transaction state before it is committed to the network.


# Node Setup

This section is dedicated to node setup. You can use the all-in-one docker solution or install Tendermint, MongoDB, and Planetmint step by step.

## Deploy a Machine for Your Planetmint Node

The first step is to deploy a machine for your Planetmint node. It might be a virtual machine (VM) or a real machine, for example, an EC2 on AWS or a droplet on Digital Ocean. If you follow this simple deployment template, all your node’s software will run on that one machine. We don’t make any assumptions about where you run the machine. It might be in Azure, AWS, your data centre or a Raspberry Pi.

### IP Addresses

The following instructions assume that all the nodes in the network (including yours) have public IP addresses. A Planetmint network *can* be run inside a private network using private IP addresses, but we don’t cover that here. Refer to this section for information on private networks.

### Operating System

**Use Ubuntu 18.04 Server or above versions as the operating system.**&#x20;

Similar instructions will work on other versions of Ubuntu and other recent Debian-like Linux distros. You may have to change the names of the packages or install more packages.

### **Network Security Group**

Suppose your machine is in AWS or Azure, *and* you want users to connect to Planetmint via HTTPS. In this case, you should configure its network security group to allow all incoming and outgoing traffic for:

* TCP on port 22 (SSH)
* TCP on port 80 (HTTP)
* TCP on port 443 (HTTPS)
* Any protocol on port 26656 (Tendermint P2P)

If you don’t care about HTTPS, then forget about port 443, and replace port 80 with port 9984 (the default Planetmint HTTP port).

### Update Your System

SSH into your machine and update all its OS-level packages:&#x20;

`sudo apt update`&#x20;

`sudo apt full-upgrade`

### DNS Setup

* Register a domain name for your Planetmint node, such as `example.com`
* Pick a subdomain of that domain for your Planetmint node, such as `bnode.example.com`
* Create a DNS “A Record” pointing to your chosen subdomain (such as `bnode.example.com`) at your machine’s IP address.


# Basic AWS Setup

Before you can deploy anything on AWS, you must do a few things.

## Get an AWS Account

If you don't already have an AWS account, you can [sign up for one for free at aws.amazon.com](https://aws.amazon.com/).

## Install the AWS Command Line Interface

To install the AWS Command Line Interface (CLI), do the following:

```
pip install awscli
```

## Create an AWS Access Key

Next, you will need AWS access keys (access key ID and secret access key). If you don’t have those, see [the AWS documentation about access keys](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys).

You should also pick a default AWS region name (e.g. `eu-central-1`). The AWS documentation has [a list of them](http://docs.aws.amazon.com/general/latest/gr/rande.html#ec2_region).

Once you’ve got your AWS access key and you’ve picked a default AWS region name, go to a terminal session and enter:

```
aws configure
```

and answer the four questions. For example:

```
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: eu-central-1
Default output format [None]: [Press Enter]
```

This writes two files: `~/.aws/credentials` and `~/.aws/config`. AWS tools and packages look for those files.

## Generate an RSA Key Pair for SSH

Eventually, you’ll have one or more instances (virtual machines) running on AWS and want to SSH to them. To do that, you need a public/private key pair. The public key will be sent to AWS; you can tell AWS to put it in any instances you provision there. You will keep the private key on your local workstation.

See the appendix [page about how to generate a key pair for SSH](https://docs.planetmint.io/en/latest/appendices/generate-key-pair-for-ssh.html).

## Send the Public Key to AWS

To send the public key to AWS, use the AWS Command Line Interface:

```
aws ec2 import-key-pair \
--key-name "<key-name>" \
--public-key-material file://~/.ssh/<key-name>.pub
```

If you're curious why there's a `file://` in front of the path to the public key, see issue [aws/aws-cli#41 on GitHub](https://github.com/aws/aws-cli/issues/41).

If you want to verify that your key pair was imported by AWS, go to [the Amazon EC2 console](https://console.aws.amazon.com/ec2/v2/home), select the region you gave above when you did `aws configure` (e.g. eu-central-1), click on **Key Pairs** in the left sidebar, and check that `<key-name>` is listed.


# Run Planetmint with all-in-one Docker


# Networks & Federations

There are several ways to setup a network. You can use the Kubernetes deployment template in this section, or use the Ansible solution in the Contributing section. Also, you can setup a single node on your machine and connect to an existing network.


# How to Set Up a Planetmint Network

You can setup or connect to a network once you have a single node running. Until now, everything could be done by a node operator, by themselves. Now the node operators, also called **Members**, must share some information with each other, so they can form a network.

There is one special Member who helps coordinate everyone: the **Coordinator**.

## Member: Share hostname, pub\_key.value and node\_id

Each Planetmint node is identified by its:

* `hostname`, i.e. the node's DNS subdomain, such as `bnode.example.com`, or its IP address, such as `46.145.17.32`
* Tendermint `pub_key.value`
* Tendermint `node_id`

The Tendermint `pub_key.value` is stored in the file `$HOME/.tendermint/config/priv_validator.json`. That file should look like:

```json
{
  "address": "E22D4340E5A92E4A9AD7C62DA62888929B3921E9",
  "pub_key": {
    "type": "tendermint/PubKeyEd25519",
    "value": "P+aweH73Hii8RyCmNWbwPsa9o4inq3I+0fSfprVkZa0="
  },
  "last_height": "0",
  "last_round": "0",
  "last_step": 0,
  "priv_key": {
    "type": "tendermint/PrivKeyEd25519",
    "value": "AHBiZXdZhkVZoPUAiMzClxhl0VvUp7Xl3YT6GvCc93A/5rB4fvceKLxHIKY1ZvA+xr2jiKercj7R9J+mtWRlrQ=="
  }
}
```

To get your Tendermint `node_id`, run the command:

```
tendermint show_node_id
```

An example `node_id` is `9b989cd5ac65fec52652a457aed6f5fd200edc22`.

**Share your `hostname`, `pub_key.value` and `node_id` with all other Members.**

## Coordinator: Create & Share the genesis.json File

At this point the Coordinator should have received the data from all the Members, and should combine them in the file `$HOME/.tendermint/config/genesis.json`:

```json
{
   "genesis_time":"0001-01-01T00:00:00Z",
   "chain_id":"test-chain-la6HSr",
   "consensus_params":{
      "block_size_params":{
         "max_bytes":"22020096",
         "max_txs":"10000",
         "max_gas":"-1"
      },
      "tx_size_params":{
         "max_bytes":"10240",
         "max_gas":"-1"
      },
      "block_gossip_params":{
         "block_part_size_bytes":"65536"
      },
      "evidence_params":{
         "max_age":"100000"
      }
   },
   "validators":[
      {
         "pub_key":{
            "type":"tendermint/PubKeyEd25519",
            "value":"<Member 1 public key>"
         },
         "power":10,
         "name":"<Member 1 name>"
      },
      {
         "pub_key":{
            "type":"tendermint/PubKeyEd25519",
            "value":"<Member 2 public key>"
         },
         "power":10,
         "name":"<Member 2 name>"
      },
      {
         "...":{

         },

      },
      {
         "pub_key":{
            "type":"tendermint/PubKeyEd25519",
            "value":"<Member N public key>"
         },
         "power":10,
         "name":"<Member N name>"
      }
   ],
   "app_hash":""
}
```

**Note:** The above `consensus_params` in the `genesis.json` are default values.

The new `genesis.json` file contains the data that describes the Network. The key `name` is the Member's moniker; it can be any valid string, but put something human-readable like `"Alice's Node Shop"`.

At this point, the Coordinator must share the new `genesis.json` file with all Members.

## Member: Connect to the Other Members

At this point the Member should have received the `genesis.json` file.

The Member must copy the `genesis.json` file into their local `$HOME/.tendermint/config` directory. Every Member now shares the same `chain_id` and `genesis_time` (used to identify the Network), and the same list of `validators`.

Each Member must edit their `$HOME/.tendermint/config/config.toml` file and make the following changes:

```
moniker = "Name of our node"
create_empty_blocks = false
log_level = "main:info,state:info,*:error"

persistent_peers = "<Member 1 node id>@<Member 1 hostname>:26656,\
<Member 2 node id>@<Member 2 hostname>:26656,\
<Member N node id>@<Member N hostname>:26656,"

send_rate = 102400000
recv_rate = 102400000

recheck = false
```

Note: The list of `persistent_peers` doesn't have to include all nodes in the network.

## Member: Start Tarantool

You install Tarantool as described [here](https://www.tarantool.io/ru/download/os-installation/ubuntu/).

You can start it using the command `tarantool`.To run it in the background (so it will continue running after you logout), you can have to create a listener `box.cfg{listen=3301}`.

## Member: Start Planetmint and Tendermint Using Monit

This section describes how to manage the Planetmint and Tendermint processes using [Monit](https://www.mmonit.com/monit), a small open-source utility for managing and monitoring Unix processes. Planetmint and Tendermint are managed together, because if Planetmint is stopped (or crashes) and is restarted, *Tendermint won't try reconnecting to it*. (That's not a bug. It's just how Tendermint works.)

Install Monit:

```
sudo apt install monit
```

If you installed the `planetmint` Python package as above, you should have the `planetmint-monit-config` script in your `PATH` now. Run the script to build a configuration file for Monit:

```
planetmint-monit-config
```

Run Monit as a daemon, instructing it to wake up every second to check on processes:

```
monit -d 1
```

Monit will run the Planetmint and Tendermint processes and restart them when they crash. If the root `planetmint_` process crashes, Monit will also restart the Tendermint process.

You can check the status by running `monit status` or `monit summary`.

By default, it will collect program logs into the `~/.planetmint-monit/logs` folder.

To learn more about Monit, use `monit -h` (help) or read [the Monit documentation](https://mmonit.com/monit/documentation/monit.html).

Check `planetmint-monit-config -h` if you want to arrange a different folder for logs or some of the Monit internal artifacts.

If you want to start and manage the Planetmint and Tendermint processes yourself, then look inside the file [planetmint/pkg/scripts/planetmint-monit-config](https://github.com/planetmint/planetmint/blob/master/pkg/scripts/planetmint-monit-config) to see how *it* starts Planetmint and Tendermint.

## How Others Can Access Your Node

If you followed the above instructions, then your node should be publicly-accessible with Planetmint Root URL `https://hostname` or `http://hostname:9984`. That is, anyone can interact with your node using the [Planetmint HTTP API](https://github.com/planetmint/docs/blob/main/connecting/http-client-server-api/README.md) exposed at that address. The most common way to do that is to use one of the [Planetmint Drivers](https://github.com/planetmint/docs/blob/main/connecting/drivers/README.md).


# Planetmint Networks

A **Planetmint network** is a set of connected **Planetmint nodes**, managed by a **Planetmint consortium** (i.e. an organization). Those terms are defined in the [Planetmint Terminology page](https://docs.planetmint.io/en/latest/terminology.html).

## Consortium Structure & Governance

The consortium might be a company, a foundation, a cooperative, or [some other form of organization](https://en.wikipedia.org/wiki/Organizational_structure). It must make many decisions, e.g. How will new members be added? Who can read the stored data? What kind of data will be stored? A governance process is required to make those decisions, and therefore one of the first steps for any new consortium is to specify its governance process (if one doesn't already exist). This documentation doesn't explain how to create a consortium, nor does it outline the possible governance processes.

It's worth noting that the decentralization of a Planetmint network depends, to some extent, on the decentralization of the associated consortium. See the pages about [decentralization](https://docs.planetmint.io/en/latest/decentralized.html) and [node diversity](https://docs.planetmint.io/en/latest/diversity.html).

## DNS Records and SSL Certificates

We now describe how *we* set up the external (public-facing) DNS records for a Planetmint network. Your consortium may opt to do it differently. There were several goals:

* Allow external users/clients to connect directly to any Planetmint node in the network (over the internet), if they want.
* Each Planetmint node operator should get an SSL certificate for their Planetmint node, so that their Planetmint node can serve the [Planetmint HTTP API](https://github.com/planetmint/docs/blob/main/connecting/http-client-server-api/README.md) via HTTPS. (The same certificate might also be used to serve the [WebSocket API](https://github.com/planetmint/docs/blob/main/connecting/websocket-event-stream-api/README.md).)
* There should be no sharing of SSL certificates among Planetmint node operators.
* Optional: Allow clients to connect to a "random" Planetmint node in the network at one particular domain (or subdomain).

### Node Operator Responsibilities

1. Register a domain (or use one that you already have) for your Planetmint node. You can use a subdomain if you like. For example, you might opt to use `abc-org73.net`, `api.dynabob8.io` or `figmentdb3.ninja`.
2. Get an SSL certificate for your domain or subdomain, and properly install it in your node (e.g. in your NGINX instance).
3. Create a DNS A Record mapping your domain or subdomain to the public IP address of your node (i.e. the one that serves the Planetmint HTTP API).

### Consortium Responsibilities

Optional: The consortium managing the Planetmint network could register a domain name and set up CNAME records mapping that domain name (or one of its subdomains) to each of the nodes in the network. For example, if the consortium registered `bdbnetwork.io`, they could set up CNAME records like the following:

* CNAME record mapping `api.bdbnetwork.io` to `abc-org73.net`
* CNAME record mapping `api.bdbnetwork.io` to `api.dynabob8.io`
* CNAME record mapping `api.bdbnetwork.io` to `figmentdb3.ninja`


# Kubernetes Deployment Template

.. note::

A highly-available Kubernetes cluster requires at least five virtual machines (three for the master and two for your app's containers). Therefore we don't recommend using Kubernetes to run a Planetmint node if that's the only thing the Kubernetes cluster will be running. Instead, see our `Node Setup <../../node_setup>`\_. If your organization already *has* a big Kubernetes cluster running many containers, and your organization has people who know Kubernetes, then this Kubernetes deployment template might be helpful.

This section outlines a way to deploy a Planetmint node (or Planetmint network) on Microsoft Azure using Kubernetes. You may choose to use it as a template or reference for your own deployment, but *we make no claim that it is suitable for your purposes*. Feel free change things to suit your needs or preferences.


