diff options
-rw-r--r-- | README.mediawiki | 7 | ||||
-rw-r--r-- | bip-0174.mediawiki | 453 | ||||
-rw-r--r-- | bip-0174/coinjoin-workflow.png | bin | 0 -> 45999 bytes | |||
-rw-r--r-- | bip-0174/multisig-workflow.png | bin | 0 -> 75935 bytes |
4 files changed, 460 insertions, 0 deletions
diff --git a/README.mediawiki b/README.mediawiki index 9b88513..bbdb1ba 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -729,6 +729,13 @@ Those proposing changes should consider that ultimately consent may rest with th | Informational | Draft |- +| [[bip-0174.mediawiki|174]] +| Applications +| Partially Signed Bitcoin Transaction Format +| Andrew Chow +| Standard +| Draft +|- | [[bip-0175.mediawiki|175]] | Applications | Pay to Contract Protocol diff --git a/bip-0174.mediawiki b/bip-0174.mediawiki new file mode 100644 index 0000000..b1f0aaf --- /dev/null +++ b/bip-0174.mediawiki @@ -0,0 +1,453 @@ +<pre> + BIP: 174 + Layer: Applications + Title: Partially Signed Bitcoin Transaction Format + Author: Andrew Chow <achow101@gmail.com> + Comments-Summary: No comments yet. + Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0174 + Status: Draft + Type: Standards Track + Created: 2017-07-12 + License: BSD-2-Clause +</pre> + +==Introduction== + +===Abstract=== + +This document proposes a binary transaction format which contains the information +necessary for a signer to produce signatures for the transaction and holds the +signatures for an input while the input does not have a complete set of signatures. +The signer can be offline as all necessary information will be provided in the +transaction. + +===Copyright=== + +This BIP is licensed under the 2-clause BSD license. + +===Motivation=== + +Creating unsigned or partially signed transactions to be passed around to multiple +signers is currently implementation dependent, making it hard for people who use +different wallet software from being able to easily do so. One of the goals of this +document is to create a standard and extensible format that can be used between clients to allow +people to pass around the same transaction to sign and combine their signatures. The +format is also designed to be easily extended for future use which is harder to do +with existing transaction formats. + +Signing transactions also requires users to have access to the UTXOs being spent. This transaction +format will allow offline signers such as air-gapped wallets and hardware wallets +to be able to sign transactions without needing direct access to the UTXO set and without +risk of being defrauded. + +==Specification== + +The Partially Signed Bitcoin Transaction (PSBT) format consists of key-value maps. +Each key-value pair must be unique within its scope; duplicates are not allowed. +Each map consists of a sequence of records, terminated by a <tt>0x00</tt> byte <ref>'''Why +is the separator here <tt>0x00</tt> instead of <tt>0xff</tt>?''' +The separator here is used to distinguish between each chunk of data. A separator of 0x00 would mean that +the unserializer can read it as a key length of 0, which would never occur with actual keys. It can thus +be used as a separator and allow for easier unserializer implementation.</ref>. The format +of a record is as follows: + +Note: <tt><..></tt> indicates that the data is prefixed by a compact size unsigned integer representing +the length of that data. <tt>{..}</tt> indicates the raw data itself. + +<pre> +<key>|<value> +</pre> + +{| class="wikitable" style="width: auto; text-align: center; font-size: smaller; table-layout: fixed;" +!Name +!Type +!Description +|- +| Key Length +| Compact Size Unsigned Integer +| Specify how long the key is +|- +| Key +| byte[] +| The key itself with the first byte being the type of the key-value pair +|- +| Value Length +| Compact Size Unsigned Integer +| Specify how long the value is +|- +| Value +| byte[] +| The Value itself +|} + +The format of each key-value map is as follows: + +<pre> +{key-value pair}|{key-value pair}|...|{0x00} +</pre> + +{| class="wikitable" style="width: auto; text-align: center; font-size: smaller; table-layout: fixed;" +!Field Size +!Name +!Type +!Value +!Description +|- +| 1+ +| Key-value pairs +| Array of key-value pairs +| varies +| The key-value pairs. +|- +| 1 +| separator +| char +| <tt>0x00</tt> +| Must be <tt>0x00</tt>. +|} + +The first byte of each key specifies the type of the key-value pair. Some types are +for global fields and other fields are for each input. The only required type in a +PSBT is the transaction type, as defined below. The currently defined global types are as follows: + +{| class="wikitable" style="width: auto; text-align: center; font-size: smaller; +table-layout: fixed;" +!Number +!Name +!Key Data +!Value Data +!Format Example +|- +| <tt>0x00</tt> +| Transaction +| None. The key must only contain the 1 byte type. +| The transaction in network serialization. The scriptSigs and +witnesses for each input must be empty unless the input is complete. The transaction +must be in the witness serialization format as defined in BIP 144. A PSBT must have +a transaction, otherwise it is invalid. +| Key: +<pre> +{0x00} +</pre> +Value: +<pre> +{transaction} +</pre> +|- +| <tt>0x01</tt> +| Redeem Script<ref>'''Why are redeem scripts and witness scripts global''' Redeem + scripts and witness scripts are global data to avoid duplication. Instead of specifying + a redeems script and witness script multiple times in inputs that need those scripts, + they are specified once in the global data.</ref> +| The hash160 of the redeem script +| A redeem script that will be needed to sign a Pay-To-Script-Hash input or is spent +to by an output.<ref>'''Why are outputs' redeem scripts and witness scripts included?''' +Redeem scripts and witness scripts spent to by an output in this transaction are included +so that the user can verify that the transaction they are signing is creating the correct +outputs that have the correct redeem and witness scripts. This is best used when the +PSBT creator is not trusted by the signers.</ref> +| Key: +<pre> +{0x01}|{hash160} +</pre> +Value: +<pre> +{redeem script} +</pre> +|- +| <tt>0x02</tt> +| Witness Script +| The sha256 hash of the witness script +| A witness script that will be needed to sign a Pay-To-Witness-Script-Hash input or is spent +to by an output. +| Key: +<pre> +{0x02}|{sha256} +</pre> +Value: +<pre> +{witness script} +</pre> +|- +| <tt>0x03</tt> +| BIP 32 Derivation path, public key, and Master Key fingerprint +| The public key +| The master key fingerprint concatenated with the derivation path of the public key. The +derivation path is represented as 32 bit unsigned integer indexes concatenated +with each other. This must omit the index of the master key. +| Key: +<pre> +{0x03}|{public key} +</pre> +Value: +<pre> +{master key fingerprint}|{32-bit int}|...|{32-bit int} +</pre> +|- +| <tt>0x04</tt> +| Number of inputs +| None. The key must only contain the 1 byte type. +| A compact size unsigned integer representing the number of inputs that this transaction has +| Key: +<pre> +{0x04} +</pre> +Value: +<pre> +{number of inputs} +</pre> +|} + +The currently defined per-input types are defined as follows: + +{| class="wikitable" style="width: auto; text-align: center; font-size: smaller; +table-layout: fixed;" +!Number +!Name +!Key Data +!Value Data +!Format Example +|- +| <tt>0x00</tt> +| Non-Witness UTXO +| None. The key must only contain the 1 byte type. +| The transaction in network serialization format the current input spends from. +| Key: +<pre> +{0x00} +</pre> +Value: +<pre> +{transaction} +</pre> +|- +| <tt>0x01</tt> +| Witness UTXO +| None. The key must only contain the 1 byte type. +| The entire transaction output in network serialization which the current input spends from. +| Key: +<pre> +{0x01} +</pre> +Value: +<pre> +{serialized transaction output({output value}|<scriptPubKey>)} +</pre> +|- +| <tt>0x02</tt> +| Partial Signature +| The public key which corresponds to this signature. +| The signature as would be pushed to the stack from a scriptSig or witness. +| Key: +<pre> +{0x02}|{public key} +</pre> +Value: +<pre> +{signature} +</pre> +|- +| <tt>0x03</tt> +| Sighash Type +| None. The key must only contain the 1 byte type. +| The 32-bit unsigned integer recommending a sighash type to be used for this input. +The sighash type is only a recommendation and the signer does not need to use +the sighash type specified. +| Key: +<pre> +{0x03} +</pre> +Value: +<pre> +{sighash type} +</pre> +|- +| <tt>0x04</tt> +| Input index +| None. The key must only contain the 1 byte type. +| A compact size unsigned integer representing the index of this input. This field +is optional to allow for completed inputs to be skipped without needing a separator byte. +If one input has this type, then all inputs must have it. +| Key: +<pre> +{0x04} +</pre> +Value: +<pre> +{input index} +</pre> +|} + +The transaction format is specified as follows: + + +<pre> + {0x70736274}|{0xff}|{global key-value map}|{input key-value map}|...|{input key-value map} +</pre> + +{| class="wikitable" style="width: auto; text-align: center; font-size: smaller; table-layout: fixed;" +!Field Size +!Name +!Type +!Value +!Description +|- +| 4 +| Magic Bytes +| int32_t +| <tt>0x70736274</tt> +| Magic bytes which are ASCII for psbt. <ref>'''Why use 4 bytes for psbt?''' The +transaction format needed to start with a 5 byte header which uniquely identifies +it. The first bytes were chosen to be the ASCII for psbt because that stands for +Partially Signed Bitcoin Transaction. </ref> This integer should be serialized +in most significant byte order. +|- +| 1 +| separator +| char +| <tt>0xff</tt> +| Must be <tt>0xff</tt> <ref>'''Why Use a separator after the magic bytes?''' The separator +is part of the 5 byte header for PSBT. This byte is a separator of <tt>0xff</tt> because +this will cause any non-PSBT unserializer to fail to properly unserialize the PSBT +as a normal transaction. Likewise, since the 5 byte header is fixed, no transaction +in the non-PSBT format will be able to be unserialized by a PSBT unserializer.</ref> +|- +| 1+ +| Global data +| Key-value Map +| varies +| The key-value pairs for all global data. +|- +| 1+ +| Inputs +| Array of key-value maps +| varies +| The key-value pairs for each input as described below +|} + +Each block of data between separators can be viewed as a scope, and all separators +are required<ref>'''Why are all separators required?''' The separators are required +so that the unserializer knows which input it is unserializing data for.</ref>. +Types can be skipped when they are unnecessary. For example, if an input is a witness +input, then it should not have a Non-Witness UTXO key-value pair. + +If the signer encounters key-value pairs that it does not understand, it must +pass those key-value pairs through when re-serializing the transaction. + +===Handling Duplicated Keys=== + +Keys within each scope should never be duplicated; all keys in the format are unique. However implementors +will still need to handle events where keys are duplicated, either duplicated in the transaction +itself or when combining transactions with duplicated fields. If duplicated keys are +encountered, the software may choose to use any of the values corresponding to that key. + +==Usage== + +Using the transaction format involves many different roles. The roles may be combined +into one entity, but each role has a specific set of things that it must be able to do. + +===Transaction Creator=== + +The transaction creator must be able to accept either a network serialized transaction or a PSBT +and either produce a PSBT or update the provided PSBT. For all scriptSigs which are not finalized, it must make the +scriptSig empty and fill in the input fields with information from the scriptSig, if any. +If it is able to, it should also look for any required redeemScripts and witnesScripts +and add those to the global data section of the PSBT. The transaction creator +should also fill in UTXOs that it knows about. + +===Transaction Signer=== + +The transaction signer must accept a PSBT. It should use the UTXOs provided in the PSBT +to produce signatures for the inputs that it can sign for. The signer should not need +access to the UTXO set as all necessary information is provided in the PSBT itself. +Any and all signatures created should be added as a Partial Signature key-value pair +to the input for which it corresponds to. + +The signer should also be able to compute the amount being spent, the amount being +transacted, the inputs being spent, the transaction fee, and the addresses being +paid. It can be interactive and ask the user for confirmation of all of the above things. + +===Transaction Combiner=== + +The transaction combiner must be able to accept multiple PSBTs. It should parse each +PSBT and merge them into one transaction if possible. If the PSBTs correspond to the +same transaction, then the combiner should create one PSBT which contains all of the +key-value pairs from the PSBTs. It should also handle duplicated keys and remove the +duplication according to the specification. + +===Transaction Finalizer=== + +The transaction finalizer must take a PSBT and build the finalized scriptSigs for each +input. If an input contains enough signatures for that input to have a complete set of +signatures, the finalizer should take those signatures, any necessary redeemScripts +and witnessScripts, and build the complete scriptSig. The scriptSig should then be +included in the transaction and the input should have all key-value pairs removed. +The finalizer may remove any global data which is not needed for any other inputs. + +===Transaction Broadcaster=== +The transaction broadcaster takes a finalized PSBT. It takes the transaction out of the +PSBT, ensures that the transaction is valid, and broadcasts it to the Bitcoin network. + +==Extensibility== + +The Partially Signed Transaction format can be extended in the future by adding +new types for key-value pairs. Backwards compatibilty will still be maintained as those new +types will be ignored and passed-through by signers which do not know about them. + +Additional key-value maps with different types for the key-value pairs can be added on to +the end of the format. The number of each map that follows must be specified in the globals +section so that parsers will know when to use different definitions of the data types. + +==Compatibility== + +This transaction format is designed so that it is unable to be properly unserialized +by normal transaction unserializers. Likewise, a normal transaction will not be +able to be unserialized by an unserializer for the PSBT format. + +==Examples== + +===Manual CoinJoin Workflow=== + +<img src="bip-0174/coinjoin-workflow.png" align="middle"></img> + +===2-of-3 Multisig Workflow=== + +<img src="bip-0174/multisig-workflow.png" align="middle"></img> + +==Test Vector== + +TBD + +==Rationale== + +<references/> + +==Reference implementation== + +The reference implementation of the PSBT format is available at https://github.com/achow101/bitcoin/tree/psbt. + +==Acknowledgements== + +Special thanks to Pieter Wuille for suggesting that such a transaction format should be made +and for coming up with the name and abbreviation of PSBT. + +Thanks to Pieter Wuille, Gregory Maxwell, Jonathan Underwood, and Daniel Cousens for additional comments +and suggestions for improving this proposal. + +==Appendix A: Data types and their specifications== + +Any data types, their associated scope and BIP number must be defined here + +{| class="wikitable" style="width: auto; text-align: center; font-size: smaller; table-layout: fixed;" +!Scope +!Type values +!BIP Number +|- +| Global +| 0,1,2,3,4 +| BIP 174 +|- +| Input +| 0,1,2,3,4 +| BIP 174 +|} diff --git a/bip-0174/coinjoin-workflow.png b/bip-0174/coinjoin-workflow.png Binary files differnew file mode 100644 index 0000000..0909c1d --- /dev/null +++ b/bip-0174/coinjoin-workflow.png diff --git a/bip-0174/multisig-workflow.png b/bip-0174/multisig-workflow.png Binary files differnew file mode 100644 index 0000000..0e752c5 --- /dev/null +++ b/bip-0174/multisig-workflow.png |