The Transaction Model

A transaction has the following structure:

{
    "id": "<hash of transaction, excluding signatures (see explanation)>",
    "version": "<version number of the transaction model>",
    "inputs": ["<list of inputs>"],
    "outputs": ["<list of outputs>"],
    "operation": "<string>",
    "asset": "<digital asset description (explained in the next section)>",
    "metadata": "<any JSON document>"
}

Here’s some explanation of the contents of a transaction:

  • id: The id of the transaction, and also the database primary key.
  • version: Version number of the transaction model, so that software can support different transaction models.
  • inputs: List of inputs. Each input contains a pointer to an unspent output and a crypto fulfillment that satisfies the conditions of that output. A fulfillment is usually a signature proving the ownership of the asset. See Inputs and Outputs.
  • outputs: List of outputs. Each output contains crypto-conditions that need to be fulfilled by a transfer transaction in order to transfer ownership to new owners. See Inputs and Outputs.
  • operation: String representation of the operation being performed (currently either “CREATE”, “TRANSFER” or “GENESIS”). It determines how the transaction should be validated.
  • asset: Definition of the digital asset. See next section.
  • metadata: User-provided transaction metadata: Can be any JSON document, or NULL.

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 input. A creation transaction is signed by whoever created it. A transfer transaction is signed by whoever currently controls or owns it.

What gets signed? For each input in the transaction, the “fullfillment message” that gets signed includes the operation, 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 input.