Skip to content
Snippets Groups Projects
0005 Duniter Protocol Rework.md 7.01 KiB
Newer Older
nanocryk's avatar
nanocryk committed
# #5 Duniter Protocol Rework for version 11
nanocryk's avatar
nanocryk committed

```txt
RFC: 5
nanocryk's avatar
nanocryk committed
Title: Duniter Protocol Rework for version 11
nanocryk's avatar
nanocryk committed
Type: Hard-fork
Status: WIP
Author: nanocryk <nanocryk@duniter.org>
Created: 2018-01-29
nanocryk's avatar
nanocryk committed
Last edited: 2018-01-30
nanocryk's avatar
nanocryk committed
License: AGPL-3
```

This document provide specifications of a reworked protocol for the Duniter project.

It aims to provide an efficient and strong base for future developments by taking the actual
protocol (version 10), simplifying it and adding usefull elements to increase performance and
extensibility.

This document will be written as a set of chapters covering all protocol details, even existing ones.
nanocryk's avatar
nanocryk committed
If this RFC is accepted, this document could be used as documentation with no or small changes.

## Summary

1. [Conventions and common rules](#1-conventions-and-common-rules)
nanocryk's avatar
nanocryk committed
1. [General document format](#2-general-document-format)
1. [Transaction document](#3-transaction-document)
nanocryk's avatar
nanocryk committed
1. Identity, Membership and Certification documents
1. Block document

## 1. Conventions and common rules

### 1.1. Endianness

All data fields are big-endian unless otherwise specified.

### 1.2. Hashes

nanocryk's avatar
nanocryk committed
All *cryptographic hashes* are done with *SHA256* algorithm unless otherwise specified.
nanocryk's avatar
nanocryk committed

They are stored as raw bytes arrays and should be displayed in hexadecimal format.

### 1.3. Bases

nanocryk's avatar
nanocryk committed
Some specific data is stored or displayed using these bases :
nanocryk's avatar
nanocryk committed

nanocryk's avatar
nanocryk committed
- Base58 (for display) : Mainly used for keys, it avoids using close looking
nanocryk's avatar
nanocryk committed
  characters and allow whole content selection with double-clicking.
  The alphabet is `123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz`.
nanocryk's avatar
nanocryk committed
- Base64 (for display) : Data format used for non user-friendly data such as signatures.
nanocryk's avatar
nanocryk committed
  The alphabet is `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`.
nanocryk's avatar
nanocryk committed
- Name64 (for storage) : Allow to store names in a more compact way that raw ASCII/UTF-8 text.
  Each character is stored on 6bits, and remove any invalid characters.
nanocryk's avatar
nanocryk committed
  The alphabet is `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-`.

### 1.4. Bytes alignments

Data should be aligned in 4 bytes blocks to improve memory speed.
Large values should be aligned, small values packed together to form 4 bytes
blocks and padding be used if alignement is not directly possible.

### 1.5. Block identifiers

nanocryk's avatar
nanocryk committed
Each block is indexed by its **block ID** stored as a *4 bytes unsigned integer*.
nanocryk's avatar
nanocryk committed
The ***genesis block*** *ID* is `0`, and each following block have a *block ID* incremented by `1`.
nanocryk's avatar
nanocryk committed

nanocryk's avatar
nanocryk committed
To refeer a *block*, we use it's **blockstamp** made of its *block ID* and its *hash*. The *blockstamp*
of the genesis block *might be* `0-883228A23F8A75B342E912DF439738450AE94F5D` and the *blockstamp*
nanocryk's avatar
nanocryk committed
of block `443` *might be* `433-FB11681FC1B3E36C9B7A74F4DDE2D07EC2637957`.

nanocryk's avatar
nanocryk committed
Since hashes are stored on 32 bytes, a *blockstamp* is stored on a 36 bytes value.
nanocryk's avatar
nanocryk committed

> Note that is says "might be" because the hash is not known in advence.

### 1.6. Dates

All dates are stored in [UNIX timestamp format][unix-timestamp], as the number of seconds
since 00:00:00 UTC on January 1, 1970. They are stored in a 64bit format to
avoid [year 2038 problem][year-2038-problem]. In this format the counter will overflow
in approximately 293 billion years.

nanocryk's avatar
nanocryk committed
Durations are expressed in eleapsed time between 2 *timestamps*.
nanocryk's avatar
nanocryk committed

nanocryk's avatar
nanocryk committed
Another way to provide dates is to reference a *blockstamp*.
Dates in the *blockchain* are calculated as the average time provided in a window of `MedianTimeBlocks` blocks.
It should be preferred to use *blockstamps* since its independent of any external influences.
nanocryk's avatar
nanocryk committed

> `Param.MedianTimeBlocks = 24` in Ǧ1 currency.

[unix-timestamp]: https://en.wikipedia.org/wiki/Unix_time
[year-2038-problem]: https://en.wikipedia.org/wiki/Unix_time#Representing_the_number

nanocryk's avatar
nanocryk committed
## 1.7. Keys
nanocryk's avatar
nanocryk committed

nanocryk's avatar
nanocryk committed
The new key format allow user to choose which *cryptographic system* he wants to use.
nanocryk's avatar
nanocryk committed
Currently only Ed25519 is supported, but others like [Schnorr signature] could be added.

[Schnorr signature]: https://en.wikipedia.org/wiki/Schnorr_signature

Public and private keys have this format :

| Size | Data |
|:----:|:-----|
nanocryk's avatar
nanocryk committed
| *4 bytes* | Checksum (4 first bytes of hash the following fields without the padding)
nanocryk's avatar
nanocryk committed
| *2 bytes* | Cryptographic system (determine `size` of payload)
| *2 bytes* | Currency code
| *`size` bytes* | Payload
| *`4 - (size % 4)` bytes* | Padding

nanocryk's avatar
nanocryk committed
Depending of the context, `size` will be the size of the public or private key.
nanocryk's avatar
nanocryk committed
Private keys are never stored in the blockchain, but can be used in clients or other protocols.

For now only `Ed25519` is defined for type `0`, with

| Size | Data |
|:----:|:-----|
| *32 bytes* | Public key
| *64 bytes* | Private key

nanocryk's avatar
nanocryk committed
The whole *blob* above is then formated in Base58 and displayed to the user.
nanocryk's avatar
nanocryk committed

nanocryk's avatar
nanocryk committed
> With this format it will be very unlikely someone send to an unwanted address.

The complete *checksum* (hash of all other fields) of a *public key* is known as a **compact public key** (or **compact key**)
and can be used to designate any public key in a fixed size value.
When a *complete public key* is used, it can be hashed and compared with the *compact key*.

### 1.8. Identities

Each identity can be referred as its **identity hash** (or **indentity UID**) computed from the username,
the hash of its associated *compact key* and the *blockstamp* of the identity creation document.

```txt
IdentityHash = SHA256(Username + CompactKey + Blockstamp)
```

> The `+` operation is a raw byte concatenation.

## 2. General document format

nanocryk's avatar
nanocryk committed
Each document is composed of an header, a payload and one or more signatures.
The tuple `(magic value, currency code, document type)` is used for network propagation,
but is ellided when written into a block since they can be deduced from block data and context.
nanocryk's avatar
nanocryk committed
The *header* and *payload* are hashed to optain a **document ID**, then *signatures* are made from it.
nanocryk's avatar
nanocryk committed

The header is composed of :

| Size | Data |
|:----:|:-----|
| *4 bytes* | Magic value : `0xDAE2D598`
| *2 bytes* | Currency code
| *2 bytes* | Document type
nanocryk's avatar
nanocryk committed
| *2 bytes* | Payload size in bytes
| *2 bytes* | Number of issuers
| ... | Issuers *complete public keys* with alignement padding for each
nanocryk's avatar
nanocryk committed

> The magic value has been choosed randomly and contains data with low probability to find in UTF-8 text.

nanocryk's avatar
nanocryk committed
Payload and each signatures have alignement padding.
nanocryk's avatar
nanocryk committed
Signatures cryptographic types are not defined and use the matching public key types.
nanocryk's avatar
nanocryk committed
A document is valid if each public key can match a signature (with 0 bytes left and no overflows)
and each signature is valid for the document content.

## 3. Transaction document

### 3.1. Document structure

A **transaction document** describes the consumption of **sources** and the creation of **outputs**.
Since we're dealing with *Universal Dividend*s, it's possible to provide a list of UDs to spend.
Each source or UD can be spent only once, and the **sum of *inputs* values must equal the sum of *output* values**.

Each *output* describes spending conditions using a **script**. This *script* is defined as an
**Abstract Syntaxic Tree** of operations which returns a boolean : can this output be used as an input of a new transaction.
This format will be describe further in this document.