<oembed><type>rich</type><version>1.0</version><author_name>npub1s4lj77xuzcu7wy04afcr487f0r3za0f8n2775xrpkld2sv639mjqsd44kw</author_name><author_url>https://nostr.ae/npub1s4lj77xuzcu7wy04afcr487f0r3za0f8n2775xrpkld2sv639mjqsd44kw</author_url><provider_name>njump</provider_name><provider_url>https://nostr.ae</provider_url><html>📅 Original date posted:2012-11-26&#xA;📝 Original message:This is the next big &#34;lets all agree to do things the same way&#34; thing&#xA;I think we should tackle. I&#39;m particularly looking for feedback from&#xA;other bitcoin client developers, even if it is just a quick &#34;looks&#xA;reasonable, if everybody else is going to do it then I will&#xA;(eventually) too...&#34;&#xA;&#xA;Thanks to Pieter Wuille and Mike Hearn for lots of feedback and&#xA;suggestions and brainstorming.&#xA;&#xA;This document is online at https://gist.github.com/4120476&#xA;&#xA;If you respond to this message, please be considerate of people who&#xA;subscribe to the digest version of this mailing list and trim your&#xA;response.&#xA;&#xA;&#xA;Invoices, Payments and Receipts for Bitcoin Transactions&#xA;========================================================&#xA;&#xA;This document proposes protocol buffer-based formats for signed,&#xA;authenticated &#34;invoices&#34; and &#34;receipts&#34; -- requests for payment, and&#xA;proof-of-payment.&#xA;&#xA;Separate documents propose an extension to the Bitcoin URI syntax and&#xA;new MIME types to support them.&#xA;&#xA;Motivation&#xA;==========&#xA;&#xA;The idea of a &#34;payment protocol&#34; to improve on Bitcoin addresses has&#xA;been around for over a year. Users have been asking for some features&#xA;in this proposal (like the ability to provide a refund address so&#xA;overpayments or refunds can be returned to customers without the need&#xA;to ask them for their address) for two or three years, and have&#xA;started to work around shortcomings in the Bitcoin payment process&#xA;with creative (but inefficient) uses of transactions.&#xA;&#xA;The key features of this proposal are:&#xA;&#xA;+ Requests for payment (Invoices) are tied to authenticated identities&#xA;using the only widely-deployed identity authentication system we have&#xA;right now (X.509 certificates signed by root certificate authorities)&#xA;+ Invoices include a user-friendly description of what the payment is for&#xA;+ Payments include where refunds should be sent&#xA;+ At the end of the payment process, the customer holds a&#xA;cryptographically signed Receipt that can be used as proof-of-payment&#xA;if there is any dispute with the merchant.&#xA;&#xA;&#xA;Specification&#xA;=============&#xA;&#xA;Invoice/SignedInvoice&#xA;---------------------&#xA;&#xA;An Invoice is a request for payment from a merchant to a customer:&#xA;&#xA;::&#xA;&#xA;    message Output {&#xA;&#x9;optional uint64 amount = 1;&#xA;&#x9;required bytes script = 2;&#xA;    }&#xA;&#xA;amount: Number of satoshis (0.00000001 BTC) to be paid. If not given&#xA;or zero, then the customer will be asked how much to pay.&#xA;&#xA;script: a &#34;TxOut&#34; script to which the customer should direct payment.&#xA;This will normally be one of the standard Bitcoin transaction script&#xA;(e.g. pubkey OP_CHECKSIG).&#xA;&#xA;::&#xA;&#xA;    message Invoice {&#xA;        repeated bytes x509chain = 1;&#xA;        repeated Output outputs = 2;&#xA;        required uint64 time = 3;&#xA;        optional uint64 expires = 4;&#xA;        optional bool single_use = 5 [default = true];&#xA;        optional string memo = 6;&#xA;        optional string receiptURI = 7;&#xA;        optional bytes merchant_data = 8;&#xA;    }&#xA;&#xA;outputs: one or more outputs where Bitcoins are to be sent.&#xA;&#xA;x509chain: one or more DER-encoded X.509 certificates that identifies&#xA;the merchant. See the &#34;Certificates&#34; section below for details.&#xA;&#xA;time: Unix timestamp (seconds since 1-Jan-1970) when the Invoice was created.&#xA;&#xA;expires: Unix timestamp after which the Invoice should be considered&#xA;invalid. If not given, the Invoice may be re-used until the earliest&#xA;certificate expiration date in the X509chain.&#xA;&#xA;single_use: If true, this Invoice should be used for only one payment.&#xA;If false, it may be added to the user&#39;s address book and used&#xA;repeatedly until it expires (e.g. for donations or a recurring&#xA;payment).&#xA;&#xA;memo: UTF-8 encoded, plain-text (no formatting) note that should be&#xA;displayed to the customer, explaining what this Invoice is for.&#xA;&#xA;receiptURI: Secure (https) URI where a Payment message (see below) may&#xA;be sent to obtain a SignedReceipt as proof-of-payment.&#xA;&#xA;merchant_data : Arbitrary data ignored by the client that may be used&#xA;by the merchant to identify the Invoice.&#xA;&#xA;::&#xA;&#xA;    message SignedInvoice {&#xA;        required Invoice invoice = 1;&#xA;        required bytes signature = 2;&#xA;    }&#xA;&#xA;A SignedInvoice is an Invoice signed using the private key&#xA;corresponding to the public key in the first certificate in the&#xA;x509chain and the HMAC SHA-256 algorithm.&#xA;&#xA;When a Bitcoin client receives a SignedInvoice, it must authorize&#xA;payment by doing the following:&#xA;&#xA;1. Validate the x509chain certificate chain up to it&#39;s list of root&#xA;certificate authorities&#xA;2. Validate that the time on the customer&#39;s system is before Invoice.expires&#xA;3. Display the &#34;Common Name&#34; (CN) string from the first x509chain&#xA;certificate and ask the customer if they would like to submit payment&#xA;&#xA;Payment&#xA;-------&#xA;&#xA;::&#xA;&#xA;    message Payment {&#xA;        required Invoice invoice = 1;&#xA;        repeated bytes transactions = 2;&#xA;        repeated Output refund_to = 3;&#xA;        optional string memo = 4;&#xA;    }&#xA;&#xA;invoice : the invoice received from the merchant. A merchant must&#xA;validate the Invoice and may reject the Payment if the Invoice was&#xA;altered by the customer.&#xA;&#xA;transactions : One or more valid, signed Bitcoin transactions that&#xA;fully pay the Invoice&#xA;&#xA;refund_to : One or more outputs where the merchant may return funds,&#xA;if necessary.&#xA;&#xA;memo : UTF-8 encoded, plain-text note from the customer to the merchant.&#xA;&#xA;If the customer authorizes payment, then the Bitcoin client:&#xA;&#xA;1. Creates and signs a transaction with one output sending the Invoice.script&#xA;2. If there is no Invoice.receiptURI, then the transaction is&#xA;broadcast on the Bitcoin p2p network.&#xA;3. Else POST a Payment message to Invoice.receiptURI and expect a&#xA;SignedReceipt in response.&#xA;&#xA;Invoice.receiptURI must be secure against man-in-the-middle attacks&#xA;that might alter Payment.refund_to.&#xA;&#xA;*Note: an alternative would be a SignedPayment message that ties the&#xA;signatures in Payment.transactions to a signature for the entire&#xA;Payment message. Spending multisig inputs that may be controlled by&#xA;more than one person or spending arbitrary non-standard transactions&#xA;makes that non-trivial.*&#xA;&#xA;Receipt/SignedReceipt&#xA;---------------------&#xA;&#xA;::&#xA;&#xA;    message Receipt {&#xA;        required Payment payment = 1;&#xA;        required bool accepted = 2;&#xA;        optional string memo = 3;&#xA;    }&#xA;&#xA;accepted : true if the Payment is accepted and will be broadcast on&#xA;the Bitcoin p2p network.&#xA;&#xA;memo : UTF-8 encoded note that should be displayed to the customer&#xA;indicating that the transaction is complete.&#xA;&#xA;::&#xA;&#xA;    message SignedReceipt {&#xA;        required Receipt receipt = 1;&#xA;        required bytes signature = 3;&#xA;    }&#xA;&#xA;A SignedReceipt is a Receipt signed using the private key&#xA;corresponding to the public key in the first certificate in the&#xA;Receipt-&gt;Payment-&gt;Invoice.x509chain and the HMAC SHA-256 algorithm.&#xA;&#xA;Upon receiving a SignedReceipt, a Bitcoin client should validate the&#xA;signature and, if valid, display the Receipt.memo and store the&#xA;SignedReceipt as proof-of-payment.&#xA;&#xA;If a SignedReceipt is not received for any reason (timeout, error) and&#xA;Payment.transactions has not been broadcast by the merchant on the&#xA;Bitcoin p2p network, then the Bitcoin client should assume that the&#xA;payment failed, inform the customer that the payment failed, and&#xA;return coins involved in the transaction to the customer&#39;s wallet.&#xA;&#xA;&#xA;Certificates&#xA;============&#xA;&#xA;The Invoice.x509chain (X.509 Certificate Chain) field contains the&#xA;X.509 public key certificate or certificate chain [RFC5280]&#xA;corresponding to the key used to digitally sign the Invoice and&#xA;Receipt. The certificate or certificate chain is represented as an&#xA;array of DER [ITU.X690.1994] PKIX certificate value. The certificate&#xA;containing the public key of the entity that digitally signed the&#xA;Invoice MUST be the first certificate. This MAY be followed by&#xA;additional certificates, with each subsequent certificate being the&#xA;one used to certify the previous one. The recipient MUST verify the&#xA;certificate chain according to [RFC5280] and reject the payment&#xA;request if any validation failure occurs.&#xA;&#xA;*What should we say about root certificates and certificate management&#xA;in general? Any requirements, or leave it up to each Bitcoin client to&#xA;determine which root CA&#39;s are trustworthy, as happens with web&#xA;browsers? Gavin suggests trusting only (say) ten of the Extended&#xA;Validation authorities:&#xA;http://en.wikipedia.org/wiki/Extended_Validation_Certificate#Extended_Validation_certificate_identification&#xA;*&#xA;&#xA;*X.509 is widely criticised for doing too much. However, it is the&#xA;Public Key Infrastructure (PKI) system we&#39;re stuck with. Do web&#xA;browsers / certificate authorities support the full X.509 spec, or&#xA;only a subset? Should Bitcoin clients only support some well-defined&#xA;subset of X.509 ? More research needed here... *&#xA;&#xA;Use Cases&#xA;=========&#xA;&#xA;Merchant Payment Service&#xA;------------------------&#xA;&#xA;A merchant payment service (like Paysius or bit-pay.com) would use&#xA;Invoices and Receipts as follows:&#xA;&#xA;1. Merchant pays for a certificate from a certificate authority, and&#xA;then gives the payment service the certificate and their private key.&#xA;This could be the same certificate and private key as is used for the&#xA;merchant&#39;s web site, but best security practice would be to purchase a&#xA;separate certificate for authenticating Invoices. Very successful&#xA;merchant payment services might act as intermediate certificate&#xA;authorities, issuing certificates for their merchants.&#xA;2. Customer goes through the checkout process on either the merchant&#39;s&#xA;or payment service&#39;s web site.&#xA;3. At the end of the checkout process, a SignedInvoice is generated&#xA;and sent to the customer&#39;s Bitcoin client.&#xA;4. Customer&#39;s Bitcoin client displays the Invoice, showing that the&#xA;payment is for the merchant.&#xA;5. On customer approval, a Payment is sent to the payment service&#39;s&#xA;paymentURI. The merchant is notified of the payment, and the customer&#xA;receives a SignedReceipt as proof-of-payment.&#xA;&#xA;SatoshiDice&#xA;-----------&#xA;&#xA;SatoshiDice (www.satoshidice.com) is an extremely popular game that&#xA;uses tiny transactions for some customer/service communications. In&#xA;particular, customers can add an extra output to their transactions to&#xA;indicate where winnings should be sent. And SatoshiDice creates tiny&#xA;transactions to let their customers know that a bet was received, but&#xA;lost.&#xA;&#xA;Assuming Bitcoin clients upgrade to support this proposal, a bet on&#xA;SatoshiDice would proceed as follows:&#xA;&#xA;1. Customer clicks on a link on SatoshiDice.com and their Bitcoin&#xA;client receives a SignedInvoice.&#xA;2. Customer authorizes payment, and their Bitcoin client creates a&#xA;Payment message and submits it directly to&#xA;https://satoshidice.com/something&#xA;3. The SatoshiDice web server checks to make sure the transaction is&#xA;valid, broadcasts it, and determines whether the customer wins or&#xA;loses. It returns a SignedReceipt with either a &#34;You win&#34; or &#34;You&#xA;lost&#34; memo.&#xA;4. If the customer won, it broadcasts a transaction to pay them using&#xA;Payment.refund_to&#xA;5. Customer&#39;s Bitcoin client displays the win/lose memo, and if they&#xA;won the winnings appear in their wallet when received over the p2p&#xA;network.&#xA;&#xA;Multiperson Wallet&#xA;------------------&#xA;&#xA;This use case starts with a multi-signature Bitcoin address or wallet,&#xA;with keys held by two different people (Alice and Bob). Payments from&#xA;that address/wallet must be authorized by both Alice and Bob, and both&#xA;are running multi-signature-capable Bitcoin clients.&#xA;&#xA;Alice begins the payment process by getting a SignedInvoice from a&#xA;merchant that needs to be paid. She authorizes payment and her Bitcoin&#xA;client creates a Payment message with a partially-signed transaction,&#xA;which is then sent to Bob any way that is convenient (email&#xA;attachment, smoke signals...).&#xA;&#xA;Bob&#39;s Bitcoin client validates the SignedInvoice and asks Bob to&#xA;authorize the transaction. He says OK, his Bitcoin client completes&#xA;the transaction by providing his signature, submits the payment to the&#xA;merchant, and then sends a message to Alice with the SignedReceipt he&#xA;received from the merchant, completing the payment process.&#xA;&#xA;&#xA;Design Notes&#xA;============&#xA;&#xA;Why X.509 Certificates?&#xA;-----------------------&#xA;&#xA;This proposal uses X.509 certificates as the identity system for&#xA;merchants because most of them will have already purchased a&#xA;certificate to secure their website and will be familiar with the&#xA;process of proving their identity to a certificate issuing authority.&#xA;&#xA;Implementing a better global PKI is outside the scope of this&#xA;proposal. If a better PKI is adopted, the only change to this proposal&#xA;would be to replace the Invoice.x509chain with whatever that better&#xA;infrastructure uses to identify entities.&#xA;&#xA;&#xA;Why not JSON?&#xA;-------------&#xA;&#xA;Invoice, Payment and Receipt messages could all be JSON-encoded. And&#xA;the Javascript Object Signing and Encryption (JOSE) working group at&#xA;the IETF has a draft specification for signing JSON data.&#xA;&#xA;But the spec is non-trivial. Signing JSON data is troublesome because&#xA;JSON can encode the same data in multiple ways (whitespace is&#xA;insignificant, characters in strings can be represented escaped or&#xA;un-escaped, etc.), and the standards committee identified at least one&#xA;security-related issue that will require special JSON parsers for&#xA;handling JSON-Web-Signed (JWS) data (duplicate keys must be rejected&#xA;by the parser, which is more strict than the JSON spec requires).&#xA;&#xA;A binary message format has none of those complicating issues. Which&#xA;encoding format to pick is largely a matter of taste, but Protocol&#xA;Buffers is a simple, robust, multi-programming-language,&#xA;well-documented, easy-to-work-with, extensible format.&#xA;&#xA;What about a merchant-pays-fee feature?&#xA;---------------------------------------&#xA;&#xA;It is desireable to allow a merchant to pay the cost of any Bitcoin&#xA;network transaction processing fees, so if a customer is paying for a&#xA;1 BTC item they pay exactly 1 BTC.&#xA;&#xA;One way of accomplishing that is to add a &#39;maxfee&#39; field to the&#xA;Invoice, and have the Bitcoin client construct a transaction that pays&#xA;the merchant (amount-maxfee).&#xA;&#xA;Another way of accomplishing that is to change the transaction&#xA;selection code used by Bitcoin miners, so that dependent transactions&#xA;are considered as a group. Then a merchant with several unconfirmed&#xA;zero-fee transaction from customers can create a pay-to-self&#xA;transaction with a large enough fee to pay for the set of transactions&#xA;to be confirmed.&#xA;&#xA;A third way of accomplishing that is for the Bitcoin client to sign&#xA;Payment.transactions[0] using the SIGHASH_ANYONECANPAY flag, and for&#xA;the merchant to add an additional, small-BTC-value input to the&#xA;transaction before broadcasting it. That additional input would go&#xA;directly to miners as a fee. *Note: Gavin is not sure if he loves or&#xA;hates this idea.*&#xA;&#xA;Checking for revoked certificates&#xA;---------------------------------&#xA;&#xA;The Online Certificate Checking Protocol (OCSP) is supposed to be a&#xA;quick and easy way for applications to check for revoked certificates.&#xA;&#xA;In practice, it doesn&#39;t work very well. Certificate Authorities have&#xA;no financial incentive to support a robust infrastructure that can&#xA;handle millions of OCSP validation requests quickly.&#xA;&#xA;Ideally, Bitcoin clients would use OCSP to check certificate statuses&#xA;every time they received or re-used an Invoice. But if that results in&#xA;long pauses or lots of false-positive rejections (because an OCSP&#xA;endpoint is offline or overwhelmed, perhaps) then merchants and&#xA;customers might revert to just using &#34;never fails&#34; Bitcoin addresses.&#xA;&#xA;&#xA;&#xA;References&#xA;==========&#xA;&#xA;Public-Key Infrastructure (X.509) working group :&#xA;http://datatracker.ietf.org/wg/pkix/charter/&#xA;&#xA;RFC 2560, X.509 Internet Public Key Infrastructure Online Certificate&#xA;Status Protocol - OCSP : http://tools.ietf.org/html/rfc2560&#xA;&#xA;Protocol Buffers : https://developers.google.com/protocol-buffers/&#xA;&#xA;See Also&#xA;========&#xA;&#xA;Javascript Object Signing and Encryption working group :&#xA;http://datatracker.ietf.org/wg/jose/&#xA;&#xA;sipa&#39;s payment protocol proposal: https://gist.github.com/1237788&#xA;&#xA;ThomasV&#39;s &#34;Signed Aliases&#34; proposal : http://ecdsa.org/bitcoin_URIs.html</html></oembed>