mirror of
https://github.com/bitcoin/bips.git
synced 2026-06-08 17:25:25 +00:00
156 lines
7.1 KiB
Plaintext
156 lines
7.1 KiB
Plaintext
|
|
<pre>
|
|
BIP: 127
|
|
Layer: Applications
|
|
Title: Simple Proof-of-Reserves Transactions
|
|
Authors: Steven Roose <steven@stevenroose.org>
|
|
Status: Complete
|
|
Type: Specification
|
|
Assigned: 2019-01-28
|
|
License: CC0-1.0
|
|
Version: 1.0.0
|
|
</pre>
|
|
|
|
|
|
==Abstract==
|
|
|
|
This BIP describes a simple way to construct proof-of-reserves transactions.
|
|
This proposal formalizes a standard format for constructing such proofs, easing
|
|
their construction with existing wallet infrastructure and enabling general
|
|
proof-verification software. It relies on existing standards such as regular
|
|
Bitcoin transaction serialization/validation and the BIP 174 PSBT format.
|
|
The proposal also includes the description of a PSBT extension for a better
|
|
user experience.
|
|
|
|
==Copyright==
|
|
|
|
This BIP is licensed under the Creative Commons CC0 1.0 Universal license.
|
|
|
|
==Motivation==
|
|
|
|
From the very early days in the history of Bitcoin, there have been companies
|
|
managing bitcoins for their users. These users give up control over their coins
|
|
in return for a certain service. Inevitably, there have been many cases of
|
|
companies losing their users' bitcoins without timely disclosing such events to
|
|
the public. Proofs of Reserves are a way for companies managing large amounts
|
|
of bitcoins to prove ownership over a given amount of funds. The regular proof
|
|
of control helps to ensure that no significant loss has occurred.
|
|
|
|
While the term proof-of-reserves is not new by any means, the procedure is not
|
|
very common among high-value custodian companies. One of the reasons for this
|
|
is that every company that wants to perform a proof-of-reserves has to construct
|
|
its own way to do so. Accordingly, their users have to understand the
|
|
construction of the proof in order to be able to verify it. This raises the bar
|
|
of entry both for custodians and for users.
|
|
|
|
|
|
===What this BIP is not doing===
|
|
|
|
The proof-of-reserve construction described in this document has some known
|
|
shortcomings, mostly with regards to its privacy properties. While there exists
|
|
research about improved proof-of-reserves mechanisms that have much better
|
|
privacy properties<ref>Dagher, Gaby G., Benedikt Bünz, Joseph Bonneau, Jeremy
|
|
Clark, and Dan Boneh. "Provisions: Privacy-preserving proofs of solvency for
|
|
Bitcoin exchanges." (2015).</ref>, this BIP intentionally only formalizes
|
|
the de-facto existing method.
|
|
|
|
|
|
==Specification==
|
|
|
|
Our proof construction should have the following properties:
|
|
* flexible proof construction to support complex wallet infrastructures
|
|
* easy integration with existing wallet solutions (both hardware and software wallets)
|
|
* support for verification via a standard procedure, regardless of publisher of the proof
|
|
* proof prevents reuse of proofs by other parties by committing to a message
|
|
* allow validating that the issuer had the funds under his control at a certain block, regardless of what happened after that block
|
|
|
|
|
|
===Proof Format===
|
|
|
|
To allow for maximal compatibility with existing systems, proofs are formatted as regular Bitcoin
|
|
transactions. However, one small adaptation to the transaction is made that has two functions:
|
|
# make the transaction unspendable to avoid putting funds at risk
|
|
# link the proof to the issuer of the proof to prevent copying proofs from other custodians
|
|
|
|
The resulting construction is a Bitcoin transaction with the following
|
|
characteristics:
|
|
|
|
* The first input (the "commitment input")
|
|
** MUST have the txid part of the previous outpoint set to the SHA-256 hash of the commitment message prefixed with "Proof-of-Reserves: "<ref>If the message is "Some Message", the txid part should be <tt>SHA-256("Proof-of-Reserves: Some Message")</tt> with the string encoded as UTF-8.</ref> and index 0.
|
|
* The remaining inputs
|
|
** MUST have signatures that commit to the commitment input (e.g. using <tt>SIGHASH_ALL</tt>).
|
|
* The transaction MUST have a single output that is the exact sum of all the inputs, assuming the commitment input to have 0 value; this means the transaction has no miner fee.
|
|
|
|
The existence of the first input (which is just a commitment hash) ensures
|
|
that this transaction is invalid and can never be confirmed.
|
|
|
|
|
|
===PSBT (BIP 174) extension===
|
|
|
|
The "commitment input" detailed in the proof format section does not spend an
|
|
existing UTXO and thus shouldn't be signed (empty <tt>scriptSig</tt> and
|
|
witness). This can cause some problems when signing this type of transactions.
|
|
For example, hardware wallets often require the signer to provide information
|
|
about all inputs of transactions they are signing, such as the previous output
|
|
or previous transaction; this data obviously doesn't exist for the commitment
|
|
inputs.
|
|
|
|
For most existing devices, it's possible to circumvent these requirements by
|
|
providing dummy data or by instructing the device to ignore this specific
|
|
input. However, there is still a UX problem. Because the hardware wallet
|
|
device doesn't recognize the transaction as a proof-of-reserves transaction it
|
|
will think it is signing a regular transaction that is spending all the money
|
|
in the UTXOs. Most devices will ask for confirmation with a message along the
|
|
lines of "Are you sure you want to send XXX BTC to address [...]?". This is
|
|
not the best user experience.
|
|
|
|
An addition to the BIP 174 PSBT format could help signing devices to recognize proof-of-reserve transactions.
|
|
The following field is added to the BIP 174 <tt>INPUT</tt> map:
|
|
|
|
* Type: Proof-of-reserves commitment <tt>PSBT_IN_POR_COMMITMENT = 0x09</tt>
|
|
** Key: None. The key must only contain the 1 byte type.
|
|
*** <tt>{0x09}</tt>
|
|
** Value: The UTF-8 encoded commitment message string for the proof-of-reserves.
|
|
*** <tt>{porCommitment}</tt>
|
|
|
|
Wallets processing an input that has this field set
|
|
* MUST make sure the txid of the previous outpoint is set to the SHA-256 hash of the prefixed commitment message string, as detailed above;
|
|
* MUST assume the input value to be 0 (without requiring the previous output or transaction to be provided);
|
|
* SHOULD display the commitment message to ask the user for confirmation before signing any inputs;
|
|
* SHOULD only provide signatures with a signature hash that commits to this input;
|
|
* SHOULD accept an empty <tt>scriptSig</tt> for this input (as if the <tt>scriptPubKey</tt> was <tt>OP_TRUE</tt>).
|
|
|
|
|
|
==Compatibility==
|
|
|
|
The proof transaction specification is based on the Bitcoin transaction
|
|
serialization protocol and will thus always be compatible with serializers
|
|
that can interpret Bitcoin transactions.
|
|
|
|
|
|
==Implementations==
|
|
|
|
A proof-of-concept implementation of the PSBT extension in the
|
|
[https://github.com/rust-bitcoin/rust-bitcoin rust-bitcoin] project can be
|
|
found in the <tt>psbt-por</tt> branch here:
|
|
https://github.com/stevenroose/rust-bitcoin/tree/psbt-por
|
|
|
|
A work-in-progress implementation of a tool that produces and verifies proofs
|
|
in the described format can be found here:
|
|
https://github.com/stevenroose/reserves
|
|
|
|
An implementation of the custom proof PSBTs is part of the [https://bitcoindevkit.org/ BDK], and can be found here: https://crates.io/crates/bdk-reserves
|
|
|
|
==Changelog==
|
|
|
|
* '''1.0.0''' (2026-05-21):
|
|
** Advance to Complete
|
|
** Remove incomplete and unused protocol buffers part
|
|
* '''0.0.1''' (2019-04-03):
|
|
** Initial Draft
|
|
|
|
== Footnotes ==
|
|
|
|
<references />
|
|
|