Newer
Older
Type: Hard-fork
Status: WIP
Author: nanocryk <nanocryk@duniter.org>
Created: 2018-01-29
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.
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)
1. [General document format](#2-general-document-format)
1. [Transaction document](#3-transaction-document)
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
All *cryptographic hashes* are done with *SHA256* algorithm unless otherwise specified.
They are stored as raw bytes arrays and should be displayed in hexadecimal format.
### 1.3. Bases
- Base58 (for display) : Mainly used for keys, it avoids using close looking
characters and allow whole content selection with double-clicking.
The alphabet is `123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz`.
- Base64 (for display) : Data format used for non user-friendly data such as signatures.
The alphabet is `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`.
- 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.
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
Each block is indexed by its **block ID** stored as a *4 bytes unsigned integer*.
The ***genesis block*** *ID* is `0`, and each following block have a *block ID* incremented by `1`.
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*
of block `443` *might be* `433-FB11681FC1B3E36C9B7A74F4DDE2D07EC2637957`.
Since hashes are stored on 32 bytes, a *blockstamp* is stored on a 36 bytes value.
> 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.
Durations are expressed in eleapsed time between 2 *timestamps*.
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.
> `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
The new key format allow user to choose which *cryptographic system* he wants to use.
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 |
|:----:|:-----|
| *4 bytes* | Checksum (4 first bytes of hash the following fields without the padding)
| *2 bytes* | Cryptographic system (determine `size` of payload)
| *2 bytes* | Currency code
| *`size` bytes* | Payload
| *`4 - (size % 4)` bytes* | Padding
Depending of the context, `size` will be the size of the public or private key.
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
The whole *blob* above is then formated in Base58 and displayed to the user.
> 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
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.
The *header* and *payload* are hashed to optain a **document ID**, then *signatures* are made from it.
The header is composed of :
| Size | Data |
|:----:|:-----|
| *4 bytes* | Magic value : `0xDAE2D598`
| *2 bytes* | Currency code
| *2 bytes* | Document type
| *2 bytes* | Payload size in bytes
| *2 bytes* | Number of issuers
| ... | Issuers *complete public keys* with alignement padding for each
> The magic value has been choosed randomly and contains data with low probability to find in UTF-8 text.
Signatures cryptographic types are not defined and use the matching public key types.
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.