docs: restructured & revised the Inputs and Outputs page for v1.0

This commit is contained in:
Troy McConaghy 2017-06-22 09:51:11 +02:00
parent 6c4b7e4373
commit 932a17853b

View File

@ -1,25 +1,85 @@
Inputs and Outputs Inputs and Outputs
================== ==================
BigchainDB is modelled around *assets*, and *inputs* and *outputs* are the mechanism by which control of an asset is transferred. There's a high-level overview of inputs and outputs
in `the root docs page about transaction concepts <https://docs.bigchaindb.com/en/latest/transaction-concepts.html>`_.
Amounts of an asset are encoded in the outputs of a transaction, and each output may be spent separately. In order to spend an output, the output's ``conditions`` must be met by an ``input`` that provides corresponding ``fulfillments``. Each output may be spent at most once, by a single input. Note that any asset associated with an output holding an amount greater than one is considered a divisible asset that may be split up in future transactions. BigchainDB is modelled around *assets*, and *inputs* and *outputs* are the mechanism by which control of an asset (or shares of an asset) is transferred.
Amounts of an asset are encoded in the outputs of a transaction, and each output may be spent separately. To spend an output, the output's ``condition`` must be met by an ``input`` that provides a corresponding ``fulfillment``. Each output may be spent at most once, by a single input. Note that any asset associated with an output holding an amount greater than one is considered a divisible asset that may be split up in future transactions.
.. note::
This document (and various places in the BigchainDB documentation and code) talks about control of an asset in terms of *owners* and *ownership*. The language is chosen to represent the most common use cases, but in some more complex scenarios, it may not be accurate to say that the output is owned by the controllers of those public keysit would only be correct to say that those public keys are associated with the ability to fulfill the output. Also, depending on the use case, the entity controlling an output via a private key may not be the legal owner of the asset in the corresponding legal domain. However, since we aim to use language that is simple to understand and covers the majority of use cases, we talk in terms of *owners* of an output that have the ability to *spend* that output. Inputs
------
In the most basic case, an output may define a **simple signature condition**, which gives control of the output to the entity controlling a corresponding private key. An input has the following structure:
A more complex condition can be composed by using n of the above conditions as inputs to an m-of-n threshold condition (a logic gate which outputs TRUE if and only if m or more inputs are TRUE). If there are n inputs to a threshold condition: .. code-block:: json
{
"owners_before": ["<The public_keys list in the output being spent>"],
"fulfillment": "<Fulfillment URI fulfilling the condition of the output being spent>",
"fulfills": {
"output": "<Index of the output being spent (an integer)>",
"transaction_id": "<ID of the transaction containing the output being spent>"
}
}
You can think of the ``fulfills`` object as a pointer to an output on another transaction: the output that this input is spending/transferring.
A CREATE transaction should have exactly one input. That input can contain one or more ``owners_before``, a ``fulfillment`` (with one signature from each of the owners-before), and the value of ``fulfills`` should be ``null``). A TRANSFER transaction should have at least one input, and the value of ``fulfills`` should not be ``null``.
See the reference on :ref:`inputs <Input>` for more description about the meaning of each field.
To calculate a fulfillment URI, you can use one of the
:ref:`BigchainDB drivers or transaction-builders <Drivers & Clients>`,
or use a low-level crypto-conditions library as illustrated
in the page about `Handcrafting Transactions <https://docs.bigchaindb.com/projects/py-driver/en/latest/handcraft.html>`_.
Outputs
-------
An output has the following structure:
.. code-block:: json
{
"condition": {"<Condition object>"},
"public_keys": ["<List of all public keys associated with the condition object>"],
"amount": "<Number of shares of the asset (an integer in a string)>"
}
The list of ``public_keys`` is always the "owners" of the asset at the time the transaction completed, but before the next transaction started.
See the reference on :ref:`outputs <Output>` for more description about the meaning of each field.
Below is a high-level description of what goes into building a ``condition`` object.
To construct an actual ``condition`` object, you can use one of the
:ref:`BigchainDB drivers or transaction-builders <Drivers & Clients>`,
or use a low-level crypto-conditions library as illustrated
in the page about `Handcrafting Transactions <https://docs.bigchaindb.com/projects/py-driver/en/latest/handcraft.html>`_.
Conditions
----------
At a high level, a condition is like a lock on an output.
If can you satisfy the condition, you can unlock the output and transfer/spend it.
BigchainDB Server v1.0 supports a subset of the ILP Crypto-Conditions
(`version 02 of Crypto-Conditions <https://tools.ietf.org/html/draft-thomas-crypto-conditions-02>`_).
The simplest supported condition is a simple signature condition.
Such a condition could be stated as,
"You can satisfy this condition
if you send me a message and a cryptographic signature of that message,
produced using the private key corresponding to this public key."
The public key is put in the output.
BigchainDB currently only supports ED25519 signatures.
A more complex condition can be composed by using n simple signature conditions as inputs to an m-of-n threshold condition (a logic gate which outputs TRUE if and only if m or more inputs are TRUE). If there are n inputs to a threshold condition:
* 1-of-n is the same as a logical OR of all the inputs * 1-of-n is the same as a logical OR of all the inputs
* n-of-n is the same as a logical AND of all the inputs * n-of-n is the same as a logical AND of all the inputs
For example, one could create a condition requiring m (of n) signatures before their asset can be transferred. For example, one could create a condition requiring m (of n) signatures before their asset can be transferred.
One can also put different weights on the inputs to a threshold condition, along with a threshold that the weighted-sum-of-inputs must pass for the output to be TRUE.
The (single) output of a threshold condition can be used as one of the inputs of other threshold conditions. This means that one can combine threshold conditions to build complex logical expressions, e.g. (x OR y) AND (u OR v). The (single) output of a threshold condition can be used as one of the inputs of other threshold conditions. This means that one can combine threshold conditions to build complex logical expressions, e.g. (x OR y) AND (u OR v).
When one creates a condition, one can calculate its fulfillment length (e.g. When one creates a condition, one can calculate its fulfillment length (e.g.
@ -38,127 +98,8 @@ so the only real option was to
If someone tries to make a condition where the output of a threshold condition feeds into the input of another “earlier” threshold condition (i.e. in a closed logical circuit), then their computer will take forever to calculate the (infinite) “condition URI”, at least in theory. In practice, their computer will run out of memory or their client software will timeout after a while. If someone tries to make a condition where the output of a threshold condition feeds into the input of another “earlier” threshold condition (i.e. in a closed logical circuit), then their computer will take forever to calculate the (infinite) “condition URI”, at least in theory. In practice, their computer will run out of memory or their client software will timeout after a while.
Outputs
-------
.. note:: .. note::
In what follows, the list of ``public_keys`` (in a condition) is always the controllers of the asset at the time the transaction completed, but before the next transaction started. The list of ``owners_before`` (in an input) is always equal to the list of ``public_keys`` in that asset's previous transaction. The BigchainDB documentation and code talks about control of an asset in terms of "owners" and "ownership." The language is chosen to represent the most common use cases, but in some more complex scenarios, it may not be accurate to say that the output is owned by the controllers of those public keys—it would only be correct to say that those public keys are associated with the ability to fulfill the conditions on the output. Also, depending on the use case, the entity controlling an output via a private key may not be the legal owner of the asset in the corresponding legal domain. However, since we aim to use language that is simple to understand and covers the majority of use cases, we talk in terms of "owners" of an output that have the ability to "spend" that output.
One New Owner
`````````````
If there is only one *new owner*, the output will contain a simple signature condition (i.e. only one signature is required).
.. code-block:: json
{
"condition": {
"details": {
"bitmask": "<base16 int>",
"public_key": "<new owner public key>",
"signature": null,
"type": "fulfillment",
"type_id": "<base16 int>"
},
"uri": "<string>"
},
"public_keys": ["<new owner public key>"],
"amount": "<int>"
}
See the reference on :ref:`outputs <Output>` for descriptions of the meaning of each field.
Multiple New Owners
```````````````````
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:
.. code-block:: json
{
"condition": {
"details": {
"bitmask": 41,
"subfulfillments": [
{
"bitmask": 32,
"public_key": "<new owner 1 public key>",
"signature": null,
"type": "fulfillment",
"type_id": 4,
"weight": 1
},
{
"bitmask": 32,
"public_key": "<new owner 2 public key>",
"signature": null,
"type": "fulfillment",
"type_id": 4,
"weight": 1
}
],
"threshold": 2,
"type": "fulfillment",
"type_id": 2
},
"uri": "cc:2:29:ytNK3X6-bZsbF-nCGDTuopUIMi1HCyCkyPewm6oLI3o:206"},
"public_keys": [
"<owner 1 public key>",
"<owner 2 public key>"
]
}
- ``subfulfillments``: a list of fulfillments
- ``weight``: integer weight for each subfulfillment's contribution to the threshold
- ``threshold``: threshold to reach for the subfulfillments to reach a valid fulfillment
The ``weight``s and ``threshold`` could be adjusted. For example, if the ``threshold`` was changed to 1 above, then only one of the new owners would have to provide a signature to spend the asset.
Inputs
------
One Current Owner
`````````````````
If there is only one *current owner*, the fulfillment will be a simple signature fulfillment (i.e. containing just one signature).
.. code-block:: json
{
"owners_before": ["<public key of the owner before the transaction happened>"],
"fulfillment": "cf:4:RxFzIE679tFBk8zwEgizhmTuciAylvTUwy6EL6ehddHFJOhK5F4IjwQ1xLu2oQK9iyRCZJdfWAefZVjTt3DeG5j2exqxpGliOPYseNkRAWEakqJ_UrCwgnj92dnFRAEE",
"fulfills": {
"output": 0,
"transaction_id": "11b3e7d893cc5fdfcf1a1706809c7def290a3b10b0bef6525d10b024649c42d3"
}
}
See the reference on :ref:`inputs <Input>` for descriptions of the meaning of each field.
Multiple Current Owners
```````````````````````
If there are multiple *current owners*, the fulfillment will be a little different from `One Current Owner`_. Suppose it has two current owners.
.. code-block:: json
{
"owners_before": ["<public key of the first owner before the transaction happened>","<public key of the second owner before the transaction happened>"],
"fulfillment": "cf:2:AQIBAgEBYwAEYEv6O5HjHGl7OWo2Tu5mWcWQcL_OGrFuUjyej-dK3LM99TbZsRd8c9luQhU30xCH5AdNaupxg-pLHuk8DoSaDA1MHQGXUZ80a_cV-4UaaaCpdey8K0CEcJxre0X96hTHCwABAWMABGBnsuHExhuSj5Mdm-q0KoPgX4nAt0s00k1WTMCzuUpQIp6aStLoTSMlsvS4fmDtOSv9gubekKLuHTMAk-LQFSKF1JdzwaVWAA2UOv0v_OS2gY3A-r0kRq8HtzjYdcmVswUA",
"fulfills": {
"output": 0,
"transaction_id": "e4805f1bfc999d6409b38e3a4c3b2fafad7c1280eb0d441da7083e945dd89eb8"
}
}
- ``owners_before``: A list of public keys of the owners before the transaction; in this case it has two owners, hence two public keys.
- ``fulfillment``: A crypto-conditions URI that encodes the cryptographic fulfillments like signatures and others;'cf' indicates this is a fulfillment, '2' indicates the condition type is THRESHOLD-SHA-256 (while '4' in `One Current Owner`_ indicates its condition type is ED25519).
- ``fulfills``: Pointer to an output from a previous transaction that is being spent
- ``output``: The index of the output in a previous transaction
- ``transaction_id``: ID of the transaction