Title: Open Assets Protocol (OAP/1.0) Author: Flavien Charlon <[email protected]> Created: 2013-12-12
This document describes a protocol used for storing and transferring custom, non-native assets on the Blockchain. Assets are represented by tokens called colored coins.
An issuer would first issue colored coins and associate them with a formal or informal promise that he will redeem the coins according to terms he has defined. Colored coins can then be transferred using transactions that preserve the quantity of every asset.
In the current Bitcoin implementation, outputs represent a quantity of Bitcoin, secured by an output script. With the Open Assets Protocol, outputs can encapsulate a quantity of a user-defined asset on top of that Bitcoin amount.
There are many applications:
- A company could issue colored coins representing shares. The shares could then be traded frictionlessly through the Bitcoin infrastructure.
- A bank could issue colored coins backed by a cash reserve. People could withdraw and deposit money in colored coins, and trade those, or use them to pay for goods and services. The Blockchain becomes a system allowing to transact not only in Bitcoin, but in any currency.
- Locks on cars or houses could be associated with a particular type of colored coins. The door would only open when presented with a wallet containing that specific coin.
Outputs using the Open Assets Protocol to store an asset have two new characteristics:
- The asset ID is a 160 bits hash, used to uniquely identify the asset stored on the output.
- The asset quantity is an unsigned integer representing how many units of that asset are stored on the output.
This document describes how the asset ID and asset quantity of an output are calculated.
Each output in the Blockchain can be either colored or uncolored:
- Uncolored outputs have no asset ID and no asset quantity (they are both undefined).
- Colored outputs have a strictly positive asset quantity, and a non-null asset ID.
The ID of an asset is the RIPEMD-160 hash of the SHA-256 hash of the output script referenced by the first input of the transaction that initially issued that asset (script_hash = RIPEMD160(SHA256(script))
). An issuer can reissue more of an already existing asset as long as they retain the private key for that asset ID. Assets on two different outputs can only be mixed together if they have the same asset ID.
Like addresses, asset IDs can be represented in base 58. They must use version byte 23 (115 in TestNet3) when represented in base 58. The base 58 representation of an asset ID therefore starts with the character 'A' in MainNet.
The process to generate an asset ID and the matching private key is described in the following example:
- The issuer first generates a private key:
18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725
. - He calculates the corresponding address:
16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
. - Next, he builds the Pay-to-PubKey-Hash script associated to that address:
OP_DUP OP_HASH160 010966776006953D5567439E5E39F86A0D273BEE OP_EQUALVERIFY OP_CHECKSIG
. - The script is hashed:
36e0ea8e93eaa0285d641305f4c81e563aa570a2
- Finally, the hash is converted to a base 58 string with checksum using version byte 23:
ALn3aK1fSuG27N96UGYB1kUYUpGKRhBuBC
.
The private key from the first step is required to issue assets identified by the asset ID ALn3aK1fSuG27N96UGYB1kUYUpGKRhBuBC
. This acts as a digital signature, and gives the guarantee that nobody else but the original issuer is able to issue assets identified by this specific asset ID.
Transactions relevant to the Open Assets Protocol must have a special output called the marker output. This allows clients to recognize such transactions. Open Assets transactions can be used to issue new assets, or transfer ownership of assets.
Transactions that are not recognized as an Open Assets transaction are considered as having all their outputs uncolored.
The marker output can have a zero or non-zero value. The marker output starts with the OP_RETURN opcode, and can be followed by any sequence of opcodes, but it must contain a PUSHDATA opcode containing a parsable Open Assets marker payload. If multiple parsable PUSHDATA opcodes exist in the same output, the first one is used, and the other ones are ignored.
If multiple valid marker outputs exist in the same transaction, the first one is used and the other ones are considered as regular outputs. If no valid marker output exists in the transaction, all outputs are considered uncolored.
The payload as defined by the Open Assets protocol has the following format:
Field | Description | Size |
---|---|---|
OAP Marker | A tag indicating that this transaction is an Open Assets transaction. It is always 0x4f41. | 2 bytes |
Version number | The major revision number of the Open Assets Protocol. For this version, it is 1 (0x0100). | 2 bytes |
Asset quantity count |
A var-integer representing the number of items in the asset quantity list field.
| 1-9 bytes |
Asset quantity list | A list of zero or more LEB128-encoded unsigned integers representing the asset quantity of every output in order (excluding the marker output). | Variable |
Metadata length |
The var-integer encoded length of the metadata field.
| 1-9 bytes |
Metadata | Arbitrary metadata to be associated with this transaction. This can be empty. | Variable |
Possible formats for the metadata
field are outside of scope of this protocol, and may be described in separate protocol specifications building on top of this one.
The asset quantity list
field is used to determine the asset quantity of each output. Each integer is encoded using variable length LEB128 encoding (also used in Google Protocol Buffers). If the LEB128-encoded asset quantity of any output exceeds 9 bytes, the marker output is deemed invalid. The maximum valid asset quantity for an output is 263 - 1 units.
If the marker output is malformed, it is considered non-parsable. Coinbase transactions and transactions with zero inputs cannot have a valid marker output, even if it would be otherwise considered valid.
If there are less items in the asset quantity list
than the number of colorable outputs (all the outputs except the marker output), the outputs in excess receive an asset quantity of zero. If there are more items in the asset quantity list
than the number of colorable outputs, the marker output is deemed invalid. The marker output is always uncolored.
After the asset quantity list
has been used to assign an asset quantity to every output, asset IDs are assigned to outputs. Outputs before the marker output are used for asset issuance, and outputs after the marker output are used for asset transfer.
This example illustrates how a marker output is decoded. Assuming the marker output is output 1:
Data in the marker output Description ----------------------------- ------------------------------------------------------------------- 0x6a The OP_RETURN opcode. 0x10 The PUSHDATA opcode for a 16 bytes payload. 0x4f 0x41 The Open Assets Protocol tag. 0x01 0x00 Version 1 of the protocol. 0x03 There are 3 items in the asset quantity list. 0xac 0x02 0x00 0xe5 0x8e 0x26 The asset quantity list: - '0xac 0x02' means output 0 has an asset quantity of 300. - Output 1 is skipped and has an asset quantity of 0 because it is the marker output. - '0x00' means output 2 has an asset quantity of 0. - '0xe5 0x8e 0x26' means output 3 has an asset quantity of 624,485. - Outputs after output 3 (if any) have an asset quantity of 0. 0x04 The metadata is 4 bytes long. 0x12 0x34 0x56 0x78 Some arbitrary metadata.
All the outputs before the marker output are used for asset issuance.
All outputs preceding the marker output and with a non-zero asset quantity get assigned the asset ID defined as the RIPEMD-160 hash of the SHA-256 hash of the output script referenced by the first input of the transaction. Outputs that have an asset quantity of zero are uncolored.
All the outputs after the marker output are used for asset transfer.
The asset IDs of those outputs are determined using a method called order-based coloring.
Inputs are seen as a sequence of asset units, each having an asset ID. Similarly, outputs are seen as a sequence of asset units to be assigned an asset ID. These two sequences are built by taking each input or output in order, each of them adding a number of asset units equal to their asset quantity. The process starts with the first input of the transaction and the first output after the marker output.
After the sequences have been built, the asset ID of every asset unit in the input sequence is assigned to the asset unit at the same position in the output sequence until all the asset units in the output sequence have received an asset ID. If there are less asset units in the input sequence than in the output sequence, the marker output is considered invalid.
Finally, for each transfer output, if the asset units forming that output all have the same asset ID, the output gets assigned that asset ID. If any output is mixing units with more than one distinct asset ID, the marker output is considered invalid. Outputs with an asset quantity of zero are always considered uncolored.
This is an example of an Open Assets transaction.
The coloring process starts by retrieving the asset quantities and asset IDs of the outputs referenced by each input of the transaction. Then, the marker output is identified. In this example, it is output 2, and the asset quantity list
field contains the following values:
0, 10, 6, 0, 7, 3
This list is used to assign asset quantities to outputs.
Inputs Outputs - Initial state Outputs - Final result ============================= ============================= ============================= Input 0 Output 0 (Issuance) Output 0 (Issuance) Asset quantity: 3 Asset quantity: 0 Asset quantity: <NULL> Asset ID: A1 Asset ID: Asset ID: <NULL> ----------------------------- ----------------------------- ----------------------------- Input 1 Output 1 (Issuance) Output 1 (Issuance) Asset quantity: 2 Asset quantity: 10 Asset quantity: 10 Asset ID: A1 Asset ID: Asset ID: H ----------------------------- ----------------------------- ----------------------------- Input 2 Output 2 (Marker) Output 2 (Marker) Asset quantity: <NULL> Asset quantity: <NULL> Asset quantity: <NULL> Asset ID: <NULL> Asset ID: <NULL> Asset ID: <NULL> ----------------------------- ----------------------------- ----------------------------- Input 3 Output 3 (Transfer) Output 3 (Transfer) Asset quantity: 5 Asset quantity: 6 Asset quantity: 6 Asset ID: A1 Asset ID: Asset ID: A1 ----------------------------- ----------------------------- ----------------------------- Input 4 Output 4 (Transfer) Output 4 (Transfer) Asset quantity: 3 Asset quantity: 0 Asset quantity: <NULL> Asset ID: A1 Asset ID: Asset ID: <NULL> ----------------------------- ----------------------------- ----------------------------- Input 5 Output 5 (Transfer) Output 5 (Transfer) Asset quantity: 9 Asset quantity: 7 Asset quantity: 7 Asset ID: A2 Asset ID: Asset ID: A1 ============================= ----------------------------- ----------------------------- Output 6 (Transfer) Output 6 (Transfer) Asset quantity: 3 Asset quantity: 3 Asset ID: Asset ID: A2 ============================= =============================
Outputs are colored from the first to the last. Outputs before the marker output are issuance outputs:
- Output 0 has an asset quantity of zero, so it is considered uncolored.
- Output 1 gets assigned the asset ID defined by
H = RIPEMD160(SHA256((S))
whereS
is the output script referenced by the first input of the transaction (input 0).
Output 2 is the marker output, separating issuance outputs from transfer outputs. The marker output is always uncolored.
Transfer outputs are then colored:
- Output 3 receives 3 units from input 0, 2 units from input 1, 0 unit from input 2 and 1 unit from input 3. All the 6 units have the same asset ID
A1
, so the asset IDA1
is assigned to output 3. - Output 4 has an asset quantity of zero, so it is considered uncolored.
- Output 5 receives the remaining 4 units of input 3, and 3 units from input 4. All the 7 units have the same asset ID
A1
, so the asset IDA1
is assigned to output 5. - Output 6 receives the first 3 units of input 5. Input 5 has the asset ID
A2
so the asset IDA2
is assigned to output 6.
This approach offers a number of desirable characteristics:
- Economical: The cost of issuing or transferring an asset is completely independent from the quantity issued or transferred.
- Clients have a way to identify colored outputs simply by traversing the Blockchain, without needing to be fed external data. Transactions relevant to the Open Assets Protocol are identified by the special marker output.
- It is possible to determine the asset ID and asset quantity of an output by traversing only a limited number of transactions.
- Assets are pseudonymous. They are represented by an asset ID, which is enough to identify each asset uniquely, while still providing an adequate level of anonymity for both the issuer and users of the asset.
- This approach uses the recommended way to embed data in the Blockchain (OP_RETURN), and therefore does not pollute the UTXO.
- The whole cryptographic infrastructure that Bitcoin provides for securing the spending of outputs is reused for securing the ability to issue assets. There is a symmetry between an address + private key as a way to spend Bitcoins, and an address + private key as a way to issue assets.
- Generating a new type of asset is as simple as generating an address, can be done offline, and for free.
- Reissuing more of an existing asset is easy and can be done quickly and at no cost (except for the transaction fee) as long as the issuer retains the private key for the asset ID.
- Single-issuance assets can be achieved by destroying the private key used to issue the asset immediately after issuing it.
- Since issuance is based on standard Bitcoin output scripts, it is possible to create an asset that requires multiple signatures for issuance.
For backward compatibility reasons, we consider than an older client is allowed to see a colored output as uncolored.
The Open Assets Protocol sits on top of the Bitcoin protocol. It does not require any change to the existing Bitcoin protocol. Existing clients that don't support the Open Assets Protocol will see all outputs as uncolored, and will not be able to perform transfer transactions.
New versions with the same major version number (e.g. 1.1) should be backwards compatible. New versions with a different major version number (e.g. 2.0) can introduce breaking changes, but transactions created by newer clients will be identifiable by a different version number in the output 0 of genesis and transfer transactions.
This document has been placed in the public domain.