├── README.md ├── address-format.mediawiki ├── payment-requests.mediawiki ├── asset-definition-protocol.mediawiki ├── payment-methods.mediawiki └── specification.mediawiki /README.md: -------------------------------------------------------------------------------- 1 | # Open Assets Protocol 2 | 3 | The Open Assets Protocol is a simple and powerful protocol built on top of the Bitcoin Blockchain. It allows issuance and transfer of user-created assets. The Open Assets Protocol is an evolution of the concept of colored coins. 4 | 5 | The following documents are available: 6 | 7 | * [Open Assets Protocol specification](specification.mediawiki): Specification of the core protocol 8 | * [Open Assets Address Format specification](address-format.mediawiki): Special address format for wallets supporting the Open Assets Protocol, preventing assets from being sent to legacy wallets 9 | * [Asset Definition Protocol specification](asset-definition-protocol.mediawiki): A protocol built on top of the Open Assets Protocol for associating an asset with metadata 10 | * [Payment Requests specification](payment-requests.mediawiki): extensions to [BIP-70](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki) and [BIP-21](https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki) describing payments in terms of assets instead of (or together with) regular bitcoins 11 | * [Payment Methods specification](payment-methods.mediawiki): A protocol for negotiating the assets to be included in an [Open Assets Payment Request](payment-requests.mediawiki). 12 | 13 | Source code related to the Open Assets Protocol: 14 | 15 | * [`openassets` Python module](https://github.com/OpenAssets/openassets): The reference implementation of the Open Assets Protocol 16 | * [Colorcore](https://github.com/OpenAssets/colorcore): A client providing a command line and RPC interface for performing operations through the Open Assets Protocol 17 | * [NBitcoin](https://github.com/NicolasDorier/NBitcoin): A Complete .NET Library for Bitcoin with its [TransactionBuilder](http://www.codeproject.com/Articles/835098/NBitcoin-Build-Them-All) to issue, transfer and swap assets 18 | * [BTCRuby](https://github.com/oleganza/btcruby): A Complete Ruby Library for Bitcoin with its [TransactionBuilder](https://github.com/oleganza/btcruby/blob/master/lib/btcruby/open_assets/asset_transaction_builder.rb) to issue, transfer and swap assets 19 | * [CoreBitcoin](https://github.com/oleganza/CoreBitcoin): A Complete Objective-C Library for Bitcoin with support for [Payment Requests](payment-requests.mediawiki) and [Payment Methods](payment-methods.mediawiki) 20 | * [openassets-ruby](https://github.com/haw-itn/openassets-ruby): A Ruby implementation of the Open Assets Protocol. This library is able to perform Open Assets operations using APIs like Colorcore. -------------------------------------------------------------------------------- /address-format.mediawiki: -------------------------------------------------------------------------------- 1 |
 2 |   Title: Open Assets Address Format
 3 |   Author: Flavien Charlon 
 4 |   Created: 2014-10-16
 5 | 
6 | 7 | ==Abstract== 8 | 9 | This document describes an address representation used by clients and wallets supporting the Open Assets Protocol. 10 | 11 | ==Motivation== 12 | 13 | A side-effect of the Open Assets Protocol is that a colored output can be spent incorrectly by wallets unaware of the protocol, causing the destruction of the asset encoded in the output. 14 | 15 | This documents describes a special representation for addresses called the Open Assets Address Format. 16 | 17 | ==Specification== 18 | 19 | Wallets capable of correctly manipulating Open Assets outputs must: 20 | 21 | # Give the Open Assets Address Format representation of every address in the wallet capable of receiving assets, in addition to the usual address representation. 22 | # Refuse to send assets to an address not specified using the Open Assets Address Format. 23 | 24 | There is a one-to-one mapping between regular Bitcoin addresses and addresses represented using the Open Assets Address Format. 25 | 26 | The Open Assets Address Format representation is constructed in the following manner: 27 | 28 | base58-encode: [one-byte namespace][one-byte version][payload][4-byte checksum] 29 | 30 | The namespace used for Open Assets is 19 (0x13 in hexadecimal). The version byte is the version byte of the original address. The payload is the payload contained in the original address. The 4-byte checksum is the first four bytes of the double SHA256 hash of the namespace, version and payload. 31 | 32 | ===Example=== 33 | 34 | The following address is represented using the regular address representation: 35 | 36 | Base-58: 16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM 37 | Hex: 00 010966776006953D5567439E5E39F86A0D273BEE D61967F6 38 | 39 | The first byte is the version (0x00) and the last four bytes are the checksum (0xD61967F6). 40 | 41 | The same address represented using the Open Assets Address Format is as follow: 42 | 43 | Base-58: akB4NBW9UuCmHuepksob6yfZs6naHtRCPNy 44 | Hex: 13 00 010966776006953D5567439E5E39F86A0D273BEE 852783AA 45 | 46 | The Open Assets namespace byte is prepended. The checksum has changed as it is now calculated on the namespace, version, and hash. 47 | 48 | ==Rationale== 49 | 50 | Open Assets wallets only accept to send assets to addresses specified in the Open Assets Address Format, and those addresses can only be obtained from wallets supporting Open Assets. This ensures that assets can only be sent to wallets supporting Open Assets. The receiving wallet will know how to handle colored outputs without destroying the asset information. 51 | 52 | ==Backwards Compatibility== 53 | 54 | Wallets supporting Open Assets should still give the regular Bitcoin address representation to allow legacy wallets to send uncolored Bitcoins to it. 55 | 56 | ==See Also== 57 | 58 | * [[specification.mediawiki|Open Assets Protocol Specification]] -------------------------------------------------------------------------------- /payment-requests.mediawiki: -------------------------------------------------------------------------------- 1 |
 2 |   Title: Open Assets Extensions to Payment Requests
 3 |   Authors: Devon Gundry , Oleg Andreev 
 4 |   Status: Draft
 5 |   Created: 2015-05-06
 6 | 
7 | 8 | ==Abstract== 9 | 10 | This document defines extensions to [https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki BIP-70], [https://github.com/bitcoin/bips/blob/master/bip-0071.mediawiki BIP-71], [https://github.com/bitcoin/bips/blob/master/bip-0072.mediawiki BIP-72] and [https://github.com/bitcoin/bips/blob/master/bip-0073.mediawiki BIP-73] to allow clients to support payments using the Open Assets Protocol. 11 | 12 | ==Motivation== 13 | 14 | Merchants that receive Open Assets payments need a convenient and secure way to establish payment details with their customers. Customers need a standard mechanism to support both pure Bitcoin payments and Open Assets payments (or instead, specify only one of them as acceptable). 15 | 16 | Standard Bitcoin payments involve only one asset: bitcoins. The Open Assets Protocol opens up the possibility for many different assets. Therefore, it becomes interesting to enable risk-free atomic swaps of one asset for another, or for pure ("non-colored") bitcoins. This specification describes how this can be accomplished in a single transaction. 17 | 18 | ==Specification== 19 | 20 | ===Open Assets Payment Request=== 21 | 22 | To enable merchants to accept payments in Open Assets units, we propose the following extension to [https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki BIP-70]. 23 | 24 | # A Payment Request must contain payment_details_version with value 0x4f41 to prevent incompatible (Open Assets-unaware) wallets from sending funds. (0x4f41 is the same prefix as used in the OA marker). 25 | # The Output message is extended with a field optional bytes asset_id = 4001; containing a 160-bit binary Asset ID (RIPEMD-160(SHA-256(issuing script))). 26 | # The Output message is extended with a field optional uint64 asset_amount = 4002; containing an amount of units. 27 | 28 | The optional field output.amount MUST NOT be specified (it's reserved for future use). The sender should include enough satoshis to exceed the dust limit (546 per simple output as of April 2015). This is similar to the responsibility of adding adequate mining fees to the transaction. 29 | 30 | If output.amount is specified, then output.asset_id and output.asset_amount MUST NOT be specified. This means that the output is a pure bitcoin output. 31 | 32 | The tags 4001 and 4002 are chosen to avoid conflict with future extensions to v1 payment requests (so they can also be ported to Open Assets compatibility in the future). 33 | 34 | ===Open Assets Atomic Swap=== 35 | 36 | To enable atomic swaps of bitcoins and assets (in any combination) we introduce a repeated field '''Input'''. Inputs define what the merchant offers to the customer in return for payment. 37 | 38 |
39 |     message PaymentDetails {
40 |         optional string network = 1 [default = "main"];
41 |         repeated Output outputs = 2;
42 |         (...)
43 |         repeated Input inputs = 8;
44 |     }
45 |     message Input {
46 |         required bytes txhash = 1;
47 |         required uint32 index = 2;
48 |     }
49 | 
50 | {| 51 | | txhash || a binary 32-byte hash of the transaction being spent by the input 52 | |- 53 | | index || index of the output in the transaction referenced by txhash 54 | |} 55 | 56 | Using input references, the client is able to determine which assets and amounts are being proposed. The merchant should use '''Output''' fields to define any necessary transaction change (assets and/or pure bitcoins). The client should take into account both inputs and outputs when computing net transferred value in terms of assets and pure bitcoins. 57 | 58 | The client must include all specified inputs and use empty signature scripts for each of them. 59 | 60 | The client must include specified inputs and outputs in the transaction '''before''' any of its own inputs and outputs. 61 | 62 | If inputs are specified, the transaction should not be relayed to the network (because it is not fully signed yet), but instead should be sent directly to the merchant via PaymentDetails.payment_url wrapped in a '''Payment''' message. A Payment Request with inputs must contain a valid payment URL, otherwise it should be rejected. 63 | 64 | ===MIME types for Open Assets Payment Requests=== 65 | 66 | To enable merchants and customers to negotiate which Payment Request type is supported, we propose the following extension to [https://github.com/bitcoin/bips/blob/master/bip-0071.mediawiki BIP-71] and [https://github.com/bitcoin/bips/blob/master/bip-0073.mediawiki BIP-73]. 67 | 68 | Open Assets Payment Requests use media type '''application/oa-paymentrequest''' and are encoded in binary. 69 | 70 | The Accept: HTTP header can be used by the wallet to list acceptable MIME types. If the wallet supports both regular Bitcoin payments and Open Assets payments, both MIME types (application/bitcoin-paymentrequest, application/oa-paymentrequest) are listed. If only Open Assets payments are supported, only the Open Assets MIME type is used. If the merchant cannot support any of the requested types, it must return HTTP error code 406 Not Acceptable. 71 | 72 | ===Payment URI=== 73 | 74 | To enable direct payments to an address, we propose an extension to the Bitcoin URI ([https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki BIP-21], [https://github.com/bitcoin/bips/blob/master/bip-0072.mediawiki BIP-72]). 75 | 76 | # In addition to the bitcoin: scheme, we introduce the openassets: scheme. This allows merchants to ensure that clients use Open Assets-compatible software to handle Open Assets payments (instead of launching regular Bitcoin wallets). 77 | # Instead of standard bitcoin address encoding, Open Assets address encoding must be used according to the [[address-format.mediawiki|Address Format Specification]]. 78 | # '''amount''' parameter must be formatted as integer if the address is present and formatted according to [[address-format.mediawiki|Open Assets Address Format Specification]]. 79 | # We introduce additional query string parameter '''asset''', which must declare an Asset ID as defined by the [[specification.mediawiki|Open Assets Protocol Specification]]. 80 | 81 | Note: merchants that support both regular bitcoin payments and Open Assets payments should use bitcoin: scheme and detect the client's intent using the Accept: HTTP header. If such URI is opened by a wallet that is unaware of Open Assets, it will detect incompatible address encoding and decline payment. 82 | 83 | ==See Also== 84 | 85 | * [[specification.mediawiki|Open Assets Protocol Specification]] 86 | -------------------------------------------------------------------------------- /asset-definition-protocol.mediawiki: -------------------------------------------------------------------------------- 1 |
  2 |   Title: Asset Definition Protocol
  3 |   Author: Flavien Charlon 
  4 |   Created: 2014-11-03
  5 | 
6 | 7 | ==Abstract== 8 | 9 | This document defines a process for associating metadata with an asset issued through the [[specification.mediawiki|Open Assets Protocol]]. 10 | 11 | ==Motivation== 12 | 13 | Assets issued through the Open Assets Protocol represent value exiting outside of the Blockchain. Issuers need to be able to inform end-users about their assets and the conditions attached to them. 14 | 15 | It is also important for an issuer to be able to prove their identity so that the user can decide whether or not to trust the issuer of an asset. 16 | 17 | All of this can be handled transparently by client software, and this document describes a way to achieve this. 18 | 19 | ==Specification== 20 | 21 | The metadata association process works in three stages: 22 | 23 | * '''Blockchain association''': The asset definition URL is embedded in the Blockchain by the issuer. 24 | * '''Asset definition file''': The asset definition file is created and made available at the specified URL. 25 | * '''Proof of Authenticity''' (optional): SSL is used to guarantee the real-world identity of the issuer. 26 | 27 | ===Blockchain association=== 28 | 29 | When issuing an asset, the issuer can associate it with a metadata file using a string called the '''asset definition pointer'''. 30 | 31 | The '''asset definition pointer''' has the following format: 32 | 33 | u= 34 | 35 | or 36 | 37 | u=&sha256= 38 | 39 | or 40 | 41 | h (21 bytes) 42 | 43 | Where is the absolute URL of the asset definition, and is the optional SHA-256 hash of the asset definition in hex format. Both values must be URL-encoded, and the asset definition pointer is encoded using UTF-8. 44 | 45 | The asset definition URL can use any valid URI scheme (http, https, ftp, magnet, safe). Clients are free to choose which subset to support. 46 | 47 | The compact form starting with h serves two purposes: to fit in the marker output (limited to 40 bytes by IsStandard checks as of May 2015) and to provide privacy for parties exchanging the asset. The compact form uses Bitcoin Hash160 function defined as RIPEMD-160(SHA-256(asset definition)). If the compact form is used, clients should use one or more pre-defined locations to fetch the data from. These could be generic well-known asset tracking servers or servers known for a given application or a given asset ID. 48 | 49 | There are two ways to associate an asset definition pointer with an asset: 50 | 51 | # Store it in the metadata field of the marker output when issuing the asset. 52 | # Issue the asset using a pay-to-script-hash output whose redeem script is constructed as follow: 53 | 54 | PUSHDATA() OP_DROP [remainder of the script] 55 | 56 | With the first method, the asset definition pointer can be changed by reissuing the asset. With the second method, the asset definition pointer cannot be changed without changing the asset ID, since the asset definition pointer is part of the issuance script, and therefore determines the asset ID. 57 | 58 | ===Determining the asset definition pointer associated to an asset=== 59 | 60 | The current asset definition file of a given asset is determined by clients using the following process: 61 | 62 | The output script responsible for issuing the asset (of which the hash is equal to the asset ID) is determined, as well as the input script used to redeem it when the asset was issued. 63 | 64 | If the following conditions are true: 65 | 66 | # The output script is a pay-to-script-hash script 67 | # The corresponding redeem script starts with a PUSHDATA followed by a OP_DROP 68 | # The PUSHDATA payload is a valid asset definition pointer (as defined in the [[#Blockchain_association|Blockchain association]] section) 69 | 70 | Then the PUSHDATA payload is the asset definition pointer, and the search stops here. 71 | 72 | Otherwise: 73 | 74 | # All transactions where the first input is redeeming that script, and with a valid Open Assets marker output, are retrieved from the Blockchain. 75 | # Transactions with an empty metadata field (zero bytes) in the marker output are excluded. 76 | # The last of those transactions in Blockchain order (block number, then order within the block) is retained. If no such transaction if found, no metadata is associated to this asset. 77 | # The metadata field of the marker output of that transaction is the asset definition pointer. If it has an incorrect format, no metadata is associated to this asset. 78 | 79 | ===Asset definition file=== 80 | 81 | After the asset definition pointer is determined, the file stored at the given URL is retrieved. If a hash is provided in the asset definition pointer, the file is verified against it. If the file can not be retrieved or if the hash doesn't match, no metadata is associated to this asset. 82 | 83 | The file is a JSON file using the following schema: 84 | 85 | { 86 | "asset_ids": [ 87 | "" 88 | ], 89 | "name_short": "", 90 | "name": "", 91 | "contract_url": "", 92 | "issuer": "", 93 | "description": "", 94 | "description_mime": "", 95 | "type": "", 96 | "divisibility": , 97 | "link_to_website": , 98 | "icon_url": "", 99 | "image_url": "", 100 | "version": "" 101 | } 102 | 103 | This table describes each field: 104 | 105 | {| 106 | ! Field !! Description 107 | |- 108 | ! asset_ids || '''(required)''' An array containing the [[specification.mediawiki#protocol-overview|base 58 representation]] of all the asset IDs authorized to use this asset definition file. Clients must verify that the ID of the asset is listed in this array. 109 | If the asset definition pointer was stored in the Blockchain using the pay-to-script-hash method (method 2 in the [[#Blockchain_association|Blockchain association]] section), the asset ID to be included in this list is calculated by hashing only the remainder script (without the initial PUSHDATA and OP_DROP), to work around the circular dependency problem. 110 | |- 111 | ! name_short || '''(required)''' A ticker used to denominate amounts of this asset, such as USD, MSFT, BTC. Clients may reject the asset definition if the value of this field is longer than 10 characters. 112 | |- 113 | ! name || '''(required)''' The name of the asset. 114 | |- 115 | ! contract_url || The URL containing more information about the asset. It must be usable by end users. 116 | |- 117 | ! issuer || The name of the issuer. Clients may choose not to display this value as it is unverified. 118 | |- 119 | ! description || A description of the asset. Clients must be able to support descriptions of at least 4096 characters. 120 | |- 121 | ! description_mime || The MIME type used to interpret the description field. By default, text/plain is assumed. Clients can choose which MIME types they support. 122 | |- 123 | ! type || The type of asset. 124 | |- 125 | ! divisibility || A signed integer indicating how many decimal places amounts of this asset can have. This changes how amounts are displayed. The displayed amount is obtained by taking the asset quantity and dividing it by 10^divisibility. 126 | |- 127 | ! link_to_website || A boolean indicating whether proof of authenticity should be used. If set to false, proof of authenticity is disabled even if the SSL certificate is available and valid. 128 | |- 129 | ! icon_url || The URL to an icon representing the asset. The image file should be 48x48 pixels but clients should be able to handle images of a different format. 130 | |- 131 | ! image_url || The URL to an image representing the asset. The image file should have a width of at least 260 pixels but clients should be able to handle images of a different format. 132 | |- 133 | ! version || A string which must be 1.0 for this version of the asset definition format. 134 | |} 135 | 136 | The order of fields is not significant. If the file is not valid, no metadata is associated to the asset at the current time. 137 | 138 | ===Proof of Authenticity=== 139 | 140 | Proof of Authenticity is an optional step for the issuer to prove its identity, and associate it with the asset. It can only be used if the asset definition URL uses the https scheme. 141 | 142 | Clients must extract the subject field of the SSL certificate presented by the web server when querying the metadata file. The subject is used as the issuer of the asset. 143 | 144 | Clients must follow HTTP redirections when retrieving the asset metadata file, however, the full redirection chain must use HTTPS for the proof of authenticity to be valid. Furthermore, in case of redirections, the SSL certificate of the last resource is used for the purpose of proof of authenticity (i.e. the request that did not result in a redirection). 145 | 146 | ==Rationale== 147 | 148 | The issuer is not required to provide a hash of the asset definition file along with the URL and the definition may be changed at the issuer's discretion. 149 | 150 | The asset metadata is provided by the issuer for informational purposes only, and should not be considered as a contract enforceable in court, unless specified otherwise by the issuer. Providing a framework for legally enforceable contracts is out of scope of this specification. 151 | 152 | ==See Also== 153 | 154 | * [[specification.mediawiki|Open Assets Protocol Specification]] -------------------------------------------------------------------------------- /payment-methods.mediawiki: -------------------------------------------------------------------------------- 1 |
  2 |   Title: Open Assets Payment Method Protocol
  3 |   Authors: Oleg Andreev , Devon Gundry 
  4 |   Status: Draft
  5 |   Created: 2015-05-06
  6 | 
7 | 8 | ==Abstract== 9 | 10 | This document defines a protocol for negotiating the assets to be included in an [[payment-requests.mediawiki|Open Assets Payment Request]]. 11 | 12 | ==Motivation== 13 | 14 | [[payment-requests.mediawiki|Payment requests]] help communicate exact transaction requirements to the client. 15 | The payment response is either a failure to pay, or a complete transaction exactly satisfying the Payment Request. 16 | 17 | This specification solves a problem preceding the actual payment: how do a payer and a payee negotiate which kinds of assets are acceptable for an upcoming transaction? 18 | [https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki BIP70] does not address this problem because it deals with only one kind of asset, Bitcoin. 19 | 20 | We introduce three new types of messages (using the same Protocol Buffers encoding as [https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki BIP70]): 21 | 22 | * A '''Payment Method Request''' contains information about the acceptable payment options. The merchant sends this message to the customer. 23 | * A '''Payment Method''' contains the exact payment method (types and amounts of assets) that will be used for payment. The customer sends this message to the merchant in reply to a Payment Method Request. The merchant then either replies with a finalized [[payment-requests.mediawiki|Payment Request]] or a Payment Method Rejection message. 24 | * A '''Payment Method Rejection''' contains information about why the supplied Payment Method is not acceptable. 25 | 26 | ==Example== 27 | 28 | During the checkout process, a merchant terminal presents a QR code to a customer. The customer scans the QR code with a client wallet to retrieve a Payment Method Request message, which conveys that the merchant accepts both merchant gift card dollars and merchant loyalty points for payment. The message also conveys that the merchant accepts tips (gratuity). 29 | 30 | The client wallet recognizes that the customer has both merchant gift card dollars and merchant loyalty points available and prompts the customer to select one or both for payment. The customer selects gift card dollars. The client wallet then prompts the customer to enter a tip. The customer enters a tip and confirms payment. The client wallet then composes a Payment Method message and returns it to the merchant terminal. 31 | 32 | The merchant terminal uses the Payment Method message to compose a Payment Request message and returns it to the client wallet. The client wallet then composes the transaction and sends it to the merchant terminal in a Payment message. The merchant terminal displays a payment confirmation to the customer. 33 | 34 | ==Specification== 35 | 36 | ===Payment Method Request=== 37 | 38 | Like a [https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki Payment Request], a Payment Method Request is optionally tied to a merchant's identity and signed with an x.509 certificate. 39 | 40 |
 41 |     message PaymentMethodRequest {
 42 |         optional uint32 payment_details_version           = 1 [default = 1];
 43 |         optional string pki_type                          = 2 [default = "none"];
 44 |         optional bytes  pki_data                          = 3;
 45 |         required bytes  serialized_payment_method_details = 4;
 46 |         optional bytes  signature                         = 5;
 47 |     }
 48 | 
49 | 50 | The meaning and signature validation logic for PaymentMethodRequest is the same as in BIP70. 51 | 52 | {| 53 | | payment_method_details || See below for a discussion of versioning/upgrading. 54 | |- 55 | | pki_type || Public-key infrastructure (PKI) system being used to identify the merchant. All implementation should support "none", "x509+sha256" and "x509+sha1". 56 | |- 57 | | pki_data || PKI-system data that identifies the merchant and can be used to create a digital signature. In the case of X.509 certificates, pki_data contains one or more X.509 certificates (see Certificates section below). 58 | |- 59 | | serialized_payment_method_details || A protocol-buffer serialized PaymentMethodDetails message. 60 | |- 61 | | signature || digital signature over a hash of the protocol buffer serialized variation of the PaymentMethodRequest message, 62 | with all serialized fields serialized in numerical order (all current protocol buffer implementations serialize 63 | fields in numerical order) and signed using the private key that corresponds to the public key in pki_data. Optional fields that are not set 64 | are not serialized (however, setting a field to its default value will cause it to be serialized and will affect 65 | the signature). Before serialization, the signature field must be set to an empty value so that the field is included in the signed PaymentMethodRequest hash but contains no data. 66 | |} 67 | 68 | ===Payment Method Details=== 69 | 70 |
 71 |     message PaymentMethodDetails {
 72 |         optional string        network            = 1 [default = "main"];
 73 |         required string        payment_method_url = 2;
 74 |         repeated PaymentItem   items              = 3;
 75 |         required uint64        time               = 4;
 76 |         optional uint64        expires            = 5;
 77 |         optional string        memo               = 6;
 78 |         optional bytes         merchant_data      = 7;
 79 |     }
 80 | 
81 | 82 | {| 83 | | network || Either "main" for payments on the production Bitcoin network, or "test" for payments on test network. If a client receives a PaymentRequest for a network it does not support it must reject the request. 84 | |- 85 | | payment_method_url || Secure (usually https) location where a PaymentMethod message (see below) may be sent to obtain a PaymentRequest. 86 | |- 87 | | items || A list of PaymentItem objects describing different parts of payment (e.g. invoice, tips, donations etc). 88 | |- 89 | | time || Unix timestamp (seconds since 1-Jan-1970 UTC) when the PaymentRequest was created. 90 | |- 91 | | expires || Unix timestamp (UTC) after which the PaymentRequest should be considered invalid. 92 | |- 93 | | memo || UTF-8 encoded, plain-text (no formatting) note that should be displayed to the customer, explaining what this PaymentMethodRequest is for. 94 | |- 95 | | merchant_data || Arbitrary data that may be used by the merchant to identify the PaymentRequest. May be omitted if the merchant does not need to associate Payments with PaymentRequest or if they associate each PaymentRequest with a separate payment address. 96 | |} 97 | 98 | ===Payment Item=== 99 | 100 | Each item has a type. The default type is "default". Different types could be used in various applications. For example, "tip" type could be used to prompt a customer to add gratuity. Another type "donation" could be used to prompt a customer to donate to a charity. However, types other than "default" are beyond the explicit scope of this specification. 101 | 102 |
103 |     message PaymentItem {
104 |         optional string type                   = 1 [default = "default"];
105 |         optional bool   optional               = 2 [default = false];
106 |         optional bytes  item_identifier        = 3;
107 |         optional uint64 amount                 = 4 [default = 0];
108 |         repeated AcceptedAsset accepted_assets = 5;
109 |         optional string memo                   = 6;
110 |     }
111 | 
112 | {| 113 | | type || Standard identifier of a type of the item. Clients that do not know how to react to a certain type should ignore the PaymentItem if it is optional (see below) or consider request invalid if PaymentItem is not optional. 114 | |- 115 | | optional || Flag indicating whether this payment item is optional or not. If omitted, item is considered required. 116 | |- 117 | | item_identifier || Arbitrary data that may be used by the merchant to identify this item in the PaymentMethod response. 118 | |- 119 | | amount || Number of units to be paid. Possible assets and conversion ratios are covered in AcceptedAsset message. If amount is zero or missing, client may put arbitrary amount. 120 | |- 121 | | accepted_assets || One or more assets acceptable for this item. See below for AcceptedAsset description. 122 | |- 123 | | memo || A human-readable description of the item (summary of the invoice, or name of a charity). 124 | |} 125 | 126 | 127 | ===Accepted Asset=== 128 | 129 |
130 |     message AcceptedAsset {
131 |         optional string asset_id = 1 [default = "default"];
132 |         optional string asset_group = 2;
133 |         optional double multiplier = 3 [default = 1.0];
134 |         optional uint64 min_amount = 4 [default = 0];
135 |         optional uint64 max_amount = 5;
136 |     }
137 | 
138 | {| 139 | | asset_id || Open Assets identifier of the asset. Special value "default" (the default value) designates native currency for the current network (e.g. BTC for Bitcoin mainnet). 140 | |- 141 | | asset_group || Arbitrary string describing a group of assets. Client may choose any assets matching the group (e.g. based on Asset Definition file, or defined via other means). If both '''asset_id''' and '''asset_group''' are missing, raw bitcoins are assumed. 142 | |- 143 | | multiplier || Conversion ratio to estimate how many units of a certain asset are required to satisfy the amount in the payment item (number of asset units must be multiplied by this value to be compared with '''amount''' field in the PaymentItem). It does not need to be precise because precise amounts will be computed by the merchant in PaymentRequest. This value is used for UI purposes mostly. 144 | |- 145 | | min_amount || Minimum amount of units of this asset accepted by the merchant. Multiplier is not used to compare units with this value. 146 | |- 147 | | max_amount || Maximum amount of units of this asset accepted by the merchant. Multiplier is not used to compare units with this value. 148 | |} 149 | 150 | 151 | ===Payment Method=== 152 | 153 | When a client chooses a payment method, it replies to the '''payment_method_url''' with a PaymentMethod message. 154 | 155 | The merchant may match a PaymentMethodItem with PaymentItem objects using either '''type''' or '''item_identifier''' fields. For type "default", there is usually one field, and therefore, there is no need to specify '''item_identifier'''. The client must copy both '''type''' and '''item_identifier''' to corresponding PaymentMethodItem objects (if they are present). 156 | 157 |
158 |     message PaymentMethod {
159 |         optional bytes             merchant_data    = 1;
160 |         repeated PaymentMethodItem items            = 2;
161 |     }
162 |     
163 |     message PaymentMethodItem {
164 |         optional string             type                = 1 [default = "default"];
165 |         optional bytes              item_identifier     = 2;
166 |         repeated PaymentMethodAsset payment_item_assets = 3;
167 |     }
168 |     
169 |     message PaymentMethodAsset {
170 |         optional string            asset_id = 1 [default = "default"];
171 |         optional uint64            amount   = 2;
172 |     }
173 | 
174 | 175 | {| 176 | | merchant_data || Copied from PaymentMethodDetails.merchant_data. Merchants may use invoice numbers or any other data they require to match Payments to PaymentRequests. Note that malicious clients may modify the merchant_data, so it should be authenticated in some way (for example, signed with a merchant-only key). 177 | |- 178 | | items || List of PaymentMethodItem objects describing assets and amounts used to pay for the corresponding PaymentItem. 179 | |- 180 | | item_identifier || Copied from PaymentItem.item_identifier. Used to match PaymentItemMethod with a corresponding PaymentItem. 181 | |- 182 | | payment_item_assets || One or more payment descriptions of assets for each payment item. 183 | |- 184 | | payment_item_type || Type of payment item as specified in PaymentItem message. 185 | |- 186 | | asset_id || Open Assets identifier of the asset. Special value "default" (also a default) designates native currency on the current network. 187 | |- 188 | | amount || Optional amount to be paid. If specified, [[payment-requests.mediawiki|Payment Request]] must contain that amount. If not specified, Payment Request may contain arbitrary amount to ensure the payment item is fully paid. 189 | |} 190 | 191 | 192 | ===Payment Method Rejection=== 193 | 194 | If the client specifies unsupported assets or invalid amounts, the merchant may reply with a detailed description of why the payment method negotiation failed. 195 | 196 | The rejection message may contain zero or more reasons for rejecting specific assets. 197 | 198 |
199 |     message PaymentMethodRejection {
200 |       optional string memo = 1;
201 |       optional uint64 code = 2;
202 |       repeated PaymentMethodRejectedAsset rejected_assets = 3;
203 |     }
204 |     message PaymentMethodRejectedAsset {
205 |       required string asset_id = 1;
206 |       optional uint64 code     = 2;
207 |       optional string reason   = 3;
208 |     }
209 | 
210 | 211 | {| 212 | | memo || Human-readable reason for rejection, not specific to any asset. 213 | |- 214 | | rejected_assets || Optional list of per-asset rejection reasons. 215 | |- 216 | | code || Optional merchant-defined numeric code of the error. Clients may use this for debugging purposes or to display appropriate UI. 217 | |- 218 | | asset_id || Identifier of the asset that caused rejection. 219 | |- 220 | | reason || Human-readable reason for rejecting the asset. 221 | |} 222 | 223 | 224 | ===MIME types=== 225 | 226 | Negotiation of payment methods begins with the same URL used by [[payment-requests.mediawiki|Payment Requests]]. 227 | 228 | To adopt payment methods, clients should add application/oa-paymentmethodrequest to the Accept: header when accessing a [[payment-requests.mediawiki|Payment Request URI]]. Compatible merchants should reply with a '''Payment Method Request''' message and Content-type: application/oa-paymentmethodrequest. If the client also supports [[payment-requests.mediawiki|Open Assets or pure Bitcoin payment requests]], appropriate MIME types should be added to the Accept: list and corresponding messages should be expected. 229 | 230 | Clients should reply with '''Payment Method''' message to payment_method_url URI with application/oa-paymentrequest among accepted types. Client SHOULD NOT reply with accepted type application/oa-paymentmethodrequest to avoid receiving '''Payment Method Request''' once again instead of a '''Payment Request'''. Content type for Payment Method message (both for request and response) is application/oa-paymentmethod. 231 | 232 | '''Payment Method Rejection''' message uses content type application/oa-paymentmethodrejection. 233 | 234 | ==See Also== 235 | 236 | * [[payment-requests.mediawiki|Open Assets Extensions to Payment Requests]] 237 | * [[specification.mediawiki|Open Assets Protocol Specification]] 238 | -------------------------------------------------------------------------------- /specification.mediawiki: -------------------------------------------------------------------------------- 1 |
  2 |   Title: Open Assets Protocol (OAP/1.0)
  3 |   Author: Flavien Charlon 
  4 |   Created: 2013-12-12
  5 | 
6 | 7 | ==Abstract== 8 | 9 | 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. 10 | 11 | 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. 12 | 13 | ==Motivation== 14 | 15 | 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. 16 | 17 | There are many applications: 18 | 19 | * A company could issue colored coins representing shares. The shares could then be traded frictionlessly through the Bitcoin infrastructure. 20 | * 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. 21 | * 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. 22 | 23 | ==Protocol Overview== 24 | 25 | Outputs using the Open Assets Protocol to store an asset have two new characteristics: 26 | * The '''asset ID''' is a 160 bits hash, used to uniquely identify the asset stored on the output. 27 | * The '''asset quantity''' is an unsigned integer representing how many units of that asset are stored on the output. 28 | 29 | This document describes how the asset ID and asset quantity of an output are calculated. 30 | 31 | Each output in the Blockchain can be either colored or uncolored: 32 | * Uncolored outputs have no asset ID and no asset quantity (they are both undefined). 33 | * Colored outputs have a strictly positive asset quantity, and a non-null asset ID. 34 | 35 | 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. 36 | 37 | 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. 38 | 39 | The process to generate an asset ID and the matching private key is described in the following example: 40 | # The issuer first generates a private key: 18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725. 41 | # He calculates the corresponding address: 16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM. 42 | # Next, he builds the Pay-to-PubKey-Hash script associated to that address: OP_DUP OP_HASH160 010966776006953D5567439E5E39F86A0D273BEE OP_EQUALVERIFY OP_CHECKSIG. 43 | # The script is hashed: 36e0ea8e93eaa0285d641305f4c81e563aa570a2 44 | # Finally, the hash is converted to a base 58 string with checksum using version byte 23: ALn3aK1fSuG27N96UGYB1kUYUpGKRhBuBC. 45 | 46 | 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. 47 | 48 | ==Open Assets Transactions== 49 | 50 | 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. 51 | 52 | Transactions that are not recognized as an Open Assets transaction are considered as having all their outputs uncolored. 53 | 54 | ===Marker output=== 55 | 56 | 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. 57 | 58 | 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. 59 | 60 | The payload as defined by the Open Assets protocol has the following format: 61 | 62 | {| 63 | ! Field !! Description !! Size 64 | |- 65 | ! OAP Marker || A tag indicating that this transaction is an Open Assets transaction. It is always 0x4f41. || 2 bytes 66 | |- 67 | ! Version number || The major revision number of the Open Assets Protocol. For this version, it is 1 (0x0100). || 2 bytes 68 | |- 69 | ! Asset quantity count || A [https://en.bitcoin.it/wiki/Protocol_specification#Variable_length_integer var-integer] representing the number of items in the asset quantity list field. || 1-9 bytes 70 | |- 71 | ! Asset quantity list || A list of zero or more [http://en.wikipedia.org/wiki/LEB128 LEB128-encoded] unsigned integers representing the asset quantity of every output in order (excluding the marker output). || Variable 72 | |- 73 | ! Metadata length || The [https://en.bitcoin.it/wiki/Protocol_specification#Variable_length_integer var-integer] encoded length of the metadata field. || 1-9 bytes 74 | |- 75 | ! Metadata || Arbitrary metadata to be associated with this transaction. This can be empty. || Variable 76 | |} 77 | 78 | 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. 79 | 80 | The asset quantity list field is used to determine the asset quantity of each output. Each integer is encoded using variable length [http://en.wikipedia.org/wiki/LEB128 LEB128] encoding (also used in [https://developers.google.com/protocol-buffers/docs/encoding#varints 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. 81 | 82 | 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. 83 | 84 | 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. 85 | 86 | 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. 87 | 88 | ====Example==== 89 | 90 | This example illustrates how a marker output is decoded. Assuming the marker output is output 1: 91 | 92 | Data in the marker output Description 93 | ----------------------------- ------------------------------------------------------------------- 94 | 0x6a The OP_RETURN opcode. 95 | 0x10 The PUSHDATA opcode for a 16 bytes payload. 96 | 0x4f 0x41 The Open Assets Protocol tag. 97 | 0x01 0x00 Version 1 of the protocol. 98 | 0x03 There are 3 items in the asset quantity list. 99 | 0xac 0x02 0x00 0xe5 0x8e 0x26 The asset quantity list: 100 | - '0xac 0x02' means output 0 has an asset quantity of 300. 101 | - Output 1 is skipped and has an asset quantity of 0 102 | because it is the marker output. 103 | - '0x00' means output 2 has an asset quantity of 0. 104 | - '0xe5 0x8e 0x26' means output 3 has an asset quantity of 624,485. 105 | - Outputs after output 3 (if any) have an asset quantity of 0. 106 | 0x04 The metadata is 4 bytes long. 107 | 0x12 0x34 0x56 0x78 Some arbitrary metadata. 108 | 109 | ===Asset issuance outputs=== 110 | 111 | All the outputs before the marker output are used for asset issuance. 112 | 113 | 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. 114 | 115 | ===Asset transfer outputs=== 116 | 117 | All the outputs after the marker output are used for asset transfer. 118 | 119 | The asset IDs of those outputs are determined using a method called order-based coloring. 120 | 121 | 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. 122 | 123 | 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. 124 | 125 | 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. 126 | 127 | ===Example=== 128 | 129 | This is an example of an Open Assets transaction. 130 | 131 | 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: 132 | 133 | 0, 10, 6, 0, 7, 3 134 | 135 | This list is used to assign asset quantities to outputs. 136 | 137 | 138 | Inputs Outputs - Initial state Outputs - Final result 139 | ============================= ============================= ============================= 140 | Input 0 Output 0 (Issuance) Output 0 (Issuance) 141 | Asset quantity: 3 Asset quantity: 0 Asset quantity: 142 | Asset ID: A1 Asset ID: Asset ID: 143 | ----------------------------- ----------------------------- ----------------------------- 144 | Input 1 Output 1 (Issuance) Output 1 (Issuance) 145 | Asset quantity: 2 Asset quantity: 10 Asset quantity: 10 146 | Asset ID: A1 Asset ID: Asset ID: H 147 | ----------------------------- ----------------------------- ----------------------------- 148 | Input 2 Output 2 (Marker) Output 2 (Marker) 149 | Asset quantity: Asset quantity: Asset quantity: 150 | Asset ID: Asset ID: Asset ID: 151 | ----------------------------- ----------------------------- ----------------------------- 152 | Input 3 Output 3 (Transfer) Output 3 (Transfer) 153 | Asset quantity: 5 Asset quantity: 6 Asset quantity: 6 154 | Asset ID: A1 Asset ID: Asset ID: A1 155 | ----------------------------- ----------------------------- ----------------------------- 156 | Input 4 Output 4 (Transfer) Output 4 (Transfer) 157 | Asset quantity: 3 Asset quantity: 0 Asset quantity: 158 | Asset ID: A1 Asset ID: Asset ID: 159 | ----------------------------- ----------------------------- ----------------------------- 160 | Input 5 Output 5 (Transfer) Output 5 (Transfer) 161 | Asset quantity: 9 Asset quantity: 7 Asset quantity: 7 162 | Asset ID: A2 Asset ID: Asset ID: A1 163 | ============================= ----------------------------- ----------------------------- 164 | Output 6 (Transfer) Output 6 (Transfer) 165 | Asset quantity: 3 Asset quantity: 3 166 | Asset ID: Asset ID: A2 167 | ============================= ============================= 168 | 169 | Outputs are colored from the first to the last. Outputs before the marker output are issuance outputs: 170 | * Output 0 has an asset quantity of zero, so it is considered uncolored. 171 | * Output 1 gets assigned the asset ID defined by H = RIPEMD160(SHA256((S)) where S is the output script referenced by the first input of the transaction (input 0). 172 | 173 | Output 2 is the marker output, separating issuance outputs from transfer outputs. The marker output is always uncolored. 174 | 175 | Transfer outputs are then colored: 176 | * 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 ID A1 is assigned to output 3. 177 | * Output 4 has an asset quantity of zero, so it is considered uncolored. 178 | * 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 ID A1 is assigned to output 5. 179 | * Output 6 receives the first 3 units of input 5. Input 5 has the asset ID A2 so the asset ID A2 is assigned to output 6. 180 | 181 | ==Rationale== 182 | 183 | This approach offers a number of desirable characteristics: 184 | 185 | # Economical: The cost of issuing or transferring an asset is completely independent from the quantity issued or transferred. 186 | # 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. 187 | # It is possible to determine the asset ID and asset quantity of an output by traversing only a limited number of transactions. 188 | # 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. 189 | # This approach uses the recommended way to embed data in the Blockchain (OP_RETURN), and therefore does not pollute the UTXO. 190 | # 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. 191 | # Generating a new type of asset is as simple as generating an address, can be done offline, and for free. 192 | # 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. 193 | # Single-issuance assets can be achieved by destroying the private key used to issue the asset immediately after issuing it. 194 | # Since issuance is based on standard Bitcoin output scripts, it is possible to create an asset that requires multiple signatures for issuance. 195 | 196 | ==Compatibility== 197 | 198 | For backward compatibility reasons, we consider than an older client is allowed to see a colored output as uncolored. 199 | 200 | ===Backward compatibility with existing Bitcoin protocol=== 201 | 202 | 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. 203 | 204 | ===Compatibility between different versions of OAP=== 205 | 206 | 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. 207 | 208 | ==Copyright== 209 | 210 | This document has been placed in the public domain. 211 | --------------------------------------------------------------------------------