From ba9885512a63ff52af864ef29c1d0299151de25d Mon Sep 17 00:00:00 2001 From: troymc Date: Sun, 29 May 2016 18:42:06 +0200 Subject: [PATCH 1/2] Minor edits to cryptography.md --- docs/source/cryptography.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/cryptography.md b/docs/source/cryptography.md index 0fde8371..48865939 100644 --- a/docs/source/cryptography.md +++ b/docs/source/cryptography.md @@ -2,11 +2,11 @@ The section documents the cryptographic algorithms and Python implementations that we use. -The implementations that we have chosen for now are just for fast prototyping. Some of them are pure Python implementations which may be slow. As future work, we should look at other alternatives. +Before hashing or computing the signature of a JSON document, we serialize it as described in [the section on JSON serialization](json-serialization.html). ## Hashes -For hashing we are using the sha3-256 algorithm and [pysha3](https://bitbucket.org/tiran/pykeccak) as the Python implementation. We store the hex encoded hash in the database. For example: +We compute hashes using the SHA3-256 algorithm and [pysha3](https://bitbucket.org/tiran/pykeccak) as the Python implementation. We store the hex-encoded hash in the database. For example: ```python import hashlib From 776c7a6161f3c1e51921be5b9814e31dcce13c5b Mon Sep 17 00:00:00 2001 From: troymc Date: Mon, 30 May 2016 13:16:22 +0200 Subject: [PATCH 2/2] Docs: Added Trasaction Concepts & more to models.md --- docs/source/_static/models_diagrams.odg | Bin 0 -> 21227 bytes docs/source/_static/stories_3_assets.png | Bin 0 -> 27686 bytes docs/source/models.md | 68 +++++++++++++++-------- 3 files changed, 46 insertions(+), 22 deletions(-) create mode 100644 docs/source/_static/models_diagrams.odg create mode 100644 docs/source/_static/stories_3_assets.png diff --git a/docs/source/_static/models_diagrams.odg b/docs/source/_static/models_diagrams.odg new file mode 100644 index 0000000000000000000000000000000000000000..058fa455d7d9f6e16d6a63bd0deb4e2fa5c48560 GIT binary patch literal 21227 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
  • O6ZJD27GF&k| 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 literal 0 HcmV?d00001 diff --git a/docs/source/models.md b/docs/source/models.md index d5b1a6b7..150594a3 100644 --- a/docs/source/models.md +++ b/docs/source/models.md @@ -1,12 +1,36 @@ # The Transaction, Block and Vote Models -Transactions, blocks and votes are represented using JSON documents with the following models (schemas). See [the section on cryptography](cryptography.html) for more information about how we calculate hashes and signatures. +BigchainDB stores all its records in JSON documents. + +The three main kinds of records are transactions, blocks and votes. +_Transactions_ are used to register, issue, create or transfer things (e.g. assets). Multiple transactions are combined with some other metadata to form _blocks_. Nodes append _votes_ to blocks. This section is a reference on the details of transactions, blocks and votes. + +Below we often refer to cryptographic hashes, keys and signatures. The details of those are covered in [the section on cryptography](cryptography.html). + +## Transaction Concepts + +Transactions are the most basic kind of record stored by BigchainDB. There are two kinds: creation transactions and transfer transactions. + +A creation transaction can be used to register, issue, create or otherwise initiate the history of a single thing (or asset) in BigchainDB. For example, one might register an identity or a creative work. The things are often called "assets" but they might not be literal assets. A creation transaction also establishes the initial owner or owners of the asset. Only a federation node can create a valid creation transaction (but it's usually made based on a message from a client). + +A transfer transaction can transfer one or more assets to new owners. + +BigchainDB works with the [Interledger Protocol (ILP)](https://interledger.org/), a protocol for transferring assets between different ledgers, blockchains or payment systems. + +The owner(s) of an asset can specifiy conditions (ILP crypto-conditions) which others must fulfill (satisfy) in order to become the new owner(s) of the asset. For example, a crypto-condition might require a signature from the owner, or from m-of-n owners (a threshold condition, e.g. 3-of-4). + +When someone creates a transfer transaction with the goal of changing an asset's owners, they must fulfill the asset's current crypto-conditions (i.e. in a fulfillment), and they must provide new conditions (including the list of new owners). + +Every create transaction contains exactly one fulfillment-condition pair. A transfer transaction can contain multiple fulfillment-condition pairs: one per asset transferred. Every fulfillment in a transfer transaction (input) must correspond to a condition (output) in a previous transaction. The diagram below illustrates some of these concepts: transactions are represented by light grey boxes, fulfillments have a label like `f:0`, and conditions have a label like `c:0`. + +![Tracking the stories of three assets](./_static/stories_3_assets.png) + ## The Transaction Model ```json { - "id": "", + "id": "", "version": "", "transaction": { "fulfillments": [""], @@ -14,40 +38,40 @@ Transactions, blocks and votes are represented using JSON documents with the fol "operation": "", "timestamp": "", "data": { - "hash": "", + "hash": "", "payload": "" } } } ``` -Transactions are the basic records stored by BigchainDB. There are two kinds: - -1. A "CREATE" transaction creates a new asset. It has `"operation": "CREATE"`. The `payload` or a "CREATE" transaction describes, encodes, or links to the asset in some way. -2. A "TRANSFER" transaction transfers one or more assets. It has `"operation": "TRANSFER"`. The `payload` of a "TRANSFER" transaction can be empty, but it can also be used for use-case-specific information (e.g. different kinds of transfers). - Here's some explanation of the contents of a transaction: -- `id`: The SHA3-256 hash hexdigest of everything inside the serialized `transaction` body (i.e. `fulfillments`, `conditions`, `operation`, `timestamp` and `data`; see below). The `id` is also the database primary key. +- `id`: The hash of everything inside the serialized `transaction` body (i.e. `fulfillments`, `conditions`, `operation`, `timestamp` and `data`; see below), with one wrinkle: for each fulfillment in `fulfillments`, `fulfillment` is set to `null`. The `id` is also the database primary key. - `version`: Version number of the transaction model, so that software can support different transaction models. - `transaction`: - `fulfillments`: List of fulfillments. Each _fulfillment_ contains a pointer to an unspent asset and a _crypto fulfillment_ that satisfies a spending condition set on the unspent asset. A _fulfillment_ is usually a signature proving the ownership of the asset. See [Conditions and Fulfillments](#conditions-and-fulfillments) below. - - `conditions`: List of conditions. Each _condition_ is a _crypto condition_ that needs to be fulfilled by the + - `conditions`: List of conditions. Each _condition_ is a _crypto-condition_ that needs to be fulfilled by the new owner in order to spend the asset. See [Conditions and Fulfillments](#conditions-and-fulfillments) below. - - `operation`: String representation of the operation being performed (currently either "CREATE" or "TRANSFER"). It determines how - the transaction should be validated. + - `operation`: String representation of the operation being performed (currently either "CREATE" or "TRANSFER"). It determines how the transaction should be validated. - `timestamp`: Time of creation of the transaction in UTC. It's provided by the client. - `data`: - - `hash`: The SHA3-256 hash hexdigest of the serialized `payload`. - - `payload`: Can be any JSON document. Its meaning depends on the whether the transaction - is a "CREATE" or "TRANSFER" transaction; see above. + - `hash`: The hash of the serialized `payload`. + - `payload`: Can be any JSON document. It may be empty in the case of a transfer transaction. + +Later, when we get to the models for the block and the vote, we'll see that both include a signature (from the node which created it). You may wonder why transactions don't have signatures... The answer is that they do! They're just hidden inside the `fulfillment` string of each fulfillment. A creation transaction is signed by the node that created it. A transfer transaction is signed by whoever currently controls or owns it. + +What gets signed? For each fulfillment in the transaction, the "fullfillment message" that gets signed includes the `operation`, `timestamp`, `data`, `version`, `id`, corresponding `condition`, and the fulfillment itself, except with its fulfillment string set to `null`. The computed signature goes into creating the `fulfillment` string of the fulfillment. + ## Conditions and Fulfillments +An aside: In what follows, the list of `new_owners` (in a condition) is always who owned the asset at the time the transaction completed, but before the next transaction started. The list of `current_owners` (in a fulfillment) is always equal to the list of `new_owners` in that asset's previous transaction. + ### Conditions #### One New Owner @@ -83,7 +107,7 @@ If there is only one _new owner_, the condition will be a single-signature condi #### Multiple New Owners -If there are multiple _new owners_, we can create a ThresholdCondition requiring a signature from each new owner in order +If there are multiple _new owners_, they can create a ThresholdCondition requiring a signature from each of them in order to spend the asset. For example: ```json @@ -146,10 +170,10 @@ If there is only one _current owner_, the fulfillment will be a single-signature } ``` -- `fid`: Fulfillment index. It matches a `cid` in the conditions with a new _crypto condition_ that the new owner +- `fid`: Fulfillment index. It matches a `cid` in the conditions with a new _crypto-condition_ that the new owner needs to fulfill to spend this asset. - `current_owners`: A list of public keys of the current owners; in this case it has just one public key. -- `fulfillment`: A cryptoconditions URI that encodes the cryptographic fulfillments like signatures and others, see crypto-conditions. +- `fulfillment`: A crypto-conditions URI that encodes the cryptographic fulfillments like signatures and others, see [crypto-conditions](https://interledger.org/five-bells-condition/spec.html). - `input`: Pointer to the asset and condition of a previous transaction - `cid`: Condition index - `txid`: Transaction id @@ -158,19 +182,19 @@ If there is only one _current owner_, the fulfillment will be a single-signature ```json { - "id": "", + "id": "", "block": { "timestamp": "", "transactions": [""], "node_pubkey": "", "voters": [""] }, - "signature": "", + "signature": "", "votes": [""] } ``` -- `id`: SHA3-256 hash hexdigest of the contents of `block` (i.e. the timestamp, list of transactions, node_pubkey, and voters). This is also a database primary key; that's how we ensure that all blocks are unique. +- `id`: The hash of the serialized `block` (i.e. the `timestamp`, `transactions`, `node_pubkey`, and `voters`). This is also a database primary key; that's how we ensure that all blocks are unique. - `block`: - `timestamp`: Timestamp when the block was created. It's provided by the node that created the block. - `transactions`: A list of the transactions included in the block. @@ -196,7 +220,7 @@ Each node must generate a vote for each block, to be appended to that block's `v "invalid_reason": "" }, - "signature": "" + "signature": "" } ```