Direct Payment Protocol
by Julie G on 10 August 2021
Category
Expiry date
Licence
Licensing terms to be announced
Applies to
Wallets
Standard Stage
In Consideration Draft Internal Review Public Review Published Recommended
Thanks for submiting your comments!

TS 2021.010-20

Direct Payment Protocol

AttributeDescription
Version1.0
AuthorsBernhard Müller, Krzysztof Fonał
ReviewersAleksandar Dinkov, Darren Kellenschwiler, Jad Wahab, Janez Urevc, Jonathan Vaage, Kapil Jain, Rafa Jimenez, Roger Taylor
Tags and CategoriesInvoices, Payments, BIP270, BIP271, BIP272, BIP273, BIP274, BIP275, BIP282 P2P, Requests, Meta-Assets
Publication Date20 April 2022 for Public Review
Valid Untiln/a
Copyright2022 Bitcoin Association for BSV
IP GenerationPatent details to be added
Known Implementationsn/a
Applies ToPayments, Micropayments, Merchants, Consumers, Payees, Collection, Cash Handling
BRFC IDTBD
AcknowledgementsThe Authors would particularly like to thank the following people for their significant contributions to the standard document: Aleksandar Dinkov and Jad Wahab
StatusPublic Review
VisibilityPublic

Background

This standard serves two purposes:

  1. Ensure a well maintained source of information for all invoice based payment standards (currently BIP270, BIP271, BIP272, BIP273, BIP274, BIP275, BIP282) and related invoicing standards such that new industry players and developers find up to date and accurate information.
  2. Harmonize extensions to BIP270, BIP271, BIP272, BIP273, BIP274, BIP275, BIP282 to allow invoicing for different payment options as well as combinations of payment options either in a single transaction or in multiple transactions.

You should join this standard’s committee if your business or project has a focus on payments, either from the wallet side or from the payment collection side, as harmonization will benefit your business/project as well as our industry as a whole. The audience of the standard is anyone implementing invoice based payments in BSV or meta-assets on top of BSV.

Problem Statement

Currently BIP270, BIP271, BIP272, BIP273, BIP274, BIP275, BIP282 are not owned by a standards committee. Several versions exist on GitHub and they all share one thing in common: They don’t represent the current implementations in the field. This makes it very hard for new players to come in and get invoice based payments right the first time.

Further, many industry representatives have voiced the need for an extension to the current standard which, for example, could allow for payments in meta-assets or the accepting of discount coupons which lower the amount of BSV required to successfully satisfy the invoiced amount.

Both of these needs shall be covered by this standard’s working group.

Objectives

  1. Re-evaluate the current BIP270, BIP271, BIP272, BIP273, BIP274, BIP275, BIP282 standard and baseline it to the common field implementation.
  2. Maintain backwards compatibility.
  3. Collect extension wishes and needs from industry players.
  4. Find the smallest denominator for such extension needs.
  5. Allow for future custom extensions without jeopardizing backwards compatibility (e.g. Travel Rule information, SPV information, etc.)
  6. Publish the standard/BIPs publicly (e.g. GitHub) and advertise it through the appropriate channels to spur adoption.
  7. Maintain the standard/BIPs

Scope

Invoice Based Payments, BIP270, BIP271, BIP272, BIP273, BIP274, BIP275, BIP282

Out of Scope

Topics covered by other working groups such as merchant-payee address resolution, and Simplified Payment Verification (SPV) transaction validation.

Methods and Concepts

  1. Intro session with all interested participants. Understanding of interests and needs. Introduction to the existing draft proposal. Potential break out sessions for particular needs after. Collection of Requirements.
  2. Formation of core group which writes the actual standard and makes sure requirements collected in phase 1 are covered as well as possible.
  3. Preliminary rollout and implementation phase. Collection of Feedback from these implementations.
  4. Amendments based on Feedback
  5. Publication and Rollout.
  6. Maintain standard.

Specification

Abstract

This RFC describes a protocol for communication between a payment host (usually either a merchant, a payment processor, or simply the recipient’s wallet) and sender (a customer, acquaintance, or device like an IoT device – an entity known to the receiver). It aims to improve customer experience, simplifying wallet infrastructure to make more advanced wallet features such as multiple outputs easier to implement, and to improve wallet security against payment process attacks such as man-in-the-middle.

Please note that the “payment host” in this document may not actually be the recipient of the funds. Like BitPay, the payment host may actually be a host or payment processor who is providing this protocol as a service for another party who is the actual recipient of the funds. We have chosen the name “payment” host to be an abstraction over either a merchant, a payment processor, a wallet, or any other agent that receives funds or acts as a proxy to whoever is the true recipient of the funds.

Motivation

The naive Bitcoin payment protocol operates as follows:

  1. Customer decides to checkout while online shopping, and chooses to pay using Bitcoin.
  2. Payment host generates a unique payment address, generates an invoice for the customer, updates the invoice with the payment address, and displays the invoice on an order completion web page.
  3. Customer copies the Bitcoin address from the payment host’s web page and pastes it into whatever wallet they are using, or follows a bitcoin: link (e.g., scans a QR code from a wallet on their smart phone) and their wallet is launched with the amount to be paid.
  4. Customer authorizes payment to the merchant and their wallet posts the transaction to a wallet server which posts the transaction to a Bitcoin node.
  5. Payment host’s server continuously scans the Bitcoin blockchain until the payment is detected, and after the transaction reached a certain threshold of transaction confirmations set by the merchant, it is considered settled.

There are several major problems with the naive approach. First, it requires the customer broadcast the transaction; meaning the customer’s wallet must connect to the Bitcoin network, and the payment host must wait for the transaction to be validated and propagate before accepting the payment. Second, it has no ability to allow for multiple outputs, which is necessary for many interesting use-cases of Bitcoin such as OP_RETURN data. Third, there is no reliable way for a payment host to refund a payment in case of an issue.

This RFC extends the naive protocol to simplify wallet construction, add new wallet features, and help make exponential ‘on-chain’ scaling possible; to the effect of enabling Bitcoin nodes to accommodate all future global network communications:

  1. Human-readable, secure payment destinations: customers will be asked to authorize payment to Example Domain instead of an inscrutable 34-character bitcoin address.
  2. Secure proof of payment, which customers can use in the event of a dispute with the merchant.
  3. Protection from man-in-the-middle attacks that replace a payment host’s receiving Bitcoin address with an attacker’s address before a transaction is authorized with a hardware wallet.
  4. Payment is sent directly to the payment host, removing the necessity of the customer engaging with the Bitcoin p2p network, and enabling quicker confirmation.
  5. Payment received messages, so the customer knows immediately that the payment host has received, and has processed (or is processing) their payment.
  6. Refund addresses, automatically given to the payment host by the customer’s wallet software, so payment hosts do not have to contact customers before refunding overpayments or orders that cannot be fulfilled for some reason.
  7. Payment can contain multiple outputs which can be arbitrary scripts and not just addresses, making new applications possible.
  8. It is no longer necessary for wallets to connect to the Bitcoin p2p network to broadcast transactions.
  9. It is no longer necessary for payment hosts to maintain an address index to monitor for in coming transactions.

Protocol

This BIP describes payment protocol messages encoded using JSON, authenticated and communicated using HTTPS or other authentication and communication systems (such as the blockchain itself). Future BIPs might extend this payment protocol to other encodings, PKI systems, or transport protocols.

The payment protocol consists of three messages; PaymentTerms, Payment, and PaymentACK, and begins with the customer somehow indicating that they are ready to pay and the payment host’s server responding with a PaymentTerms message:

Messages

There are several JSON objects used in the protocol. We start with a summary of the JSON objects, and then proceed to the details. Top-level objects are the messages type at the same time.

  • PaymentTerms: A way of specifying the details of a required payment, including a dict of destinations, expiration data, and other meta data. This message/object contains 2 main parts (and a few variables):
    • Modes: Payment modes where each mode describes detailed instruction about payment requirements, where requirements are embedded in specified format (Payment Mode)
    • Beneficiary: A way of specifying data about merchant.
  • Payment: Includes a signed Bitcoin transaction. Detailed format of Payment depends on chosen Payment Mode but the below object is common for all modes:
    • Originator: A way of specifying data about payer.
  • PaymentAck: Acknowledgement of receipt of payment. Detailed format of PaymentACK depends on chosen Payment Mode but the below object is common for all modes
    • PeerChannel: A way to provide data needed to communicate via created channel in a secure manner.

PaymentTerms

PaymentTerms {
    network // string. required. always set to "bitcoin".
    version // string. required. 
    outputs // an array of outputs. optional, deprecated - for backward compatibility.
    creationTimestamp // number. required.
    expirationTimestamp // number. optional.
    memo // string. optional.
    paymentUrl // string. required.
    beneficiary // object. optional.
    modes // a key-value map. required (not if legacy outputs provided) 
}

A payment request contains the information the consumer needs to make the payment to the payment host.

networkThis field is required and takes on the standard bitcoin network values: `mainnet` `testnet` `stn` `regtest`
outputsOne or more outputs where Bitcoins are to be sent. Deprecated (for backward compatibility only).
optionsMap with zero or more payment options. Each entry is an alternative option object identified by key. One of them has to be paid.
creationTimestampUnix timestamp (seconds since 1-Jan-1970 UTC) when the PaymentTerms was created.
expirationTimestampUnix timestamp (UTC) after which the PaymentTerms should be considered invalid.
memoNote that should be displayed to the customer, explaining what this PaymentTerms is for. Maximum length is 50 characters.
paymentUrlSecure HTTPS location where a Payment message (see below) will be sent to obtain a PaymentACK. Maximum length is 4000 characters.
beneficiaryArbitrary data that may be used by the payment host to identify the PaymentTerms. May be omitted if the payment host does not need to associate Payments with PaymentTerms or if they associate each PaymentTerms with a separate payment address. Maximum length is 10000 characters.
modespossible, specified by ID (and well defined) modes customer can choose to pay. More about the modes and first defined mode can be find here.

The paymentUrl specified in the PaymentTerms should remain valid at least until the PaymentTerms expirationTimestamp (or as long as possible if the PaymentTerms does not expire). Note that this is irrespective of any state change in the underlying payment request; for example cancellation of an order should not invalidate the paymentUrl, as it is important that the payment host’s server can record mis-payments in order to refund the payment.

When a Bitcoin wallet application receives a PaymentTerms, it must authorize payment by doing the following:

  1. Validate the payment host’s identity and signature using the PKI system. The PKI system is assumed to occur in a wrapper layer (such as HTTPS) and if no PKI system is available then the wallet can choose whether or not to display the payment request. The PKI system is usually HTTPS, and as such if the payment request is retrieved over HTTPS then the domain name should be displayed as the payment host.
  2. Validate that customer’s system unix time (UTC) is before PaymentTerms.expirationTimestamp. If it is not, then the payment request must be rejected.
  3. Display the payment host’s identity and ask the customer if they would like to submit payment (e.g. display the “Common Name” in the first X.509 certificate).

PaymentTerms messages larger than 10 MB should be rejected by the wallet application, to mitigate denial-of-service attacks.

Example:

{
  memo: "Payment for purchasing Socks online",
  network: mainnet,
  creationTimestamp: 1648163657,
  expirationTimestamp: 1648164657,
  paymentURL: https://localhost:3443/api/v1/payment/Order-325214,
  beneficiary: {
    name: "GoldenSocks.com",
    paymentReference: "Order-325214",
  },
  modes: {
  'ef63d9775da5': { // HybridPaymentMode
      choiceID0: {
        transactions: [
          {
            outputs: {
              native: [
                {
                  satoshis: 10000000,
                  script: "76a91493d0d43918a5df78f08cfe22a4e022846b6736c288ac",
                },
              ],
            },
            policies: {
              fees: {
                  standard: {
                    satoshis: 1,
                    bytes: 1
                  },
                  data: {
                    satoshis: 1,
                    bytes: 10
                  }
                },
              SPVRequired: false
            }
          },
        ],
      },
      choiceID1: {
        transactions: [
          {
            outputs: {
              native: [
                {
                  satoshis: 10000,
                  script: "76a91493d0d43918a5df78f08cfe22a4e022846b6736c288ac",
                },
              ],
              brfc1: [ // please note that this is only example, RUN protocol schema might be differ
                {
                  contractName: "MyToken",
                  contractType: "RUN's word for Standard Fungible Token", // this will further devide the sub-protocol into sub-sub-protocols.
                  contractLocation:
                    "bc64f3ab1ffe7b4396097b9611ed4105ac5994901202c84b334708d6cc42067a_o1",
                  tokenAmount: 400,
                  tokenRecepient: "1DjmxqX7AnzQe6rUyG1AibPhUCXLJyoMVU",
                },
              ],
            },
            inputs: {
              native: [
                {
                  // input #1
                },
              ],
              // brfc100: [
              //     {}
              // ]
            },
            policies: {
              ancestry: { format: "binary", minDepth: 2 },
              SPVRequired: false
              // can be extended with "req-" parameter if extensions are Required!
            },
            // can be extended with "req-" parameter if extensions are Required!
          },
          {
            outputs: {
              STAS: [ // please note that this is only example, STAS protocol schema might be differ
                {
                  satoshis: 10000,
                  script: "some really long STAS script",
                  contractTX: "XYZ",
                  contractAddress: "ABC",
                },
              ],
            },
            policies: {
              ancestry: { format: "binary", minDepth: 2 },
              SPVRequired: false
            },
          }
        ],
      },
    }
  }
}
a. Modes

Required outputs packed inside some specified mode. PaymentTerms might provide various modes and the customer or wallet logic has to choose which mode it’s going to use. Chosen mode then dictates how the Payment and PaymentACK objects will look like to fit the chosen mode’s flow and requirements. More information about PaymentModes can be found <here>.

b. Beneficiary

The beneficiary data contains information about the merchant.

Beneficiary {
  name // string. required.
  email // string. required.
  address // string. required.
  paymentReference // string. ID of invoice.
  avatar // string. optional.
  extendedData // object. optional, freestyle object.
}
nameName of merchant.
avatarURL to an avatar.
emailOfficial merchant email.
addressMerchant’s address.
paymentReferenceID of the payment/invoice.
extendedDataAdditional optional data.

Payment

Payment messages are sent after the customer has authorized payment. It refers to which payment mode was chosen and provides the specific data required for the particular mode:

Payment {
  modeId // string. The chosen mode
  mode // object. The Payment object for the specific mode used.
  originator // object. payer data needed for identification as well as refund. optional.
  transaction // a hex-formatted (and fully-signed and valid) transaction. optional. deprecated
  memo // string. optional.
}
modeIdMode chosen from possible modes of PaymentTerms.
modeObject with data required by specific mode, e.g. HybridPaymentMode
originatorData about payer. This data might be needed in many cases, e.g. refund, tract data for later loyalty points processing etc.
transactionA single valid, signed Bitcoin transaction that fully pays the PaymentTerms. This field is deprecated.
memoA plain-text note from the customer to the payment host.

When the payment host’s server receives the Payment message, it must determine whether or not the transactions satisfies conditions of payment terms. If and only if they do, it should broadcast the transaction to the the Bitcoin p2p network.

Payment messages larger than 10 MB should be rejected by the payment host’s server, to mitigate denial-of-service attacks.

Example:

{
  modeId: "ef63d9775da5", // This ID is brfcid for HybridPaymentMode"
  mode: {
    ...  //HybridPaymentMode Payment object
  },
  originator: {
    name: "Aleks Dinkov",
    paymail: "[email protected]",
    avatarUrl: "https://iamges.com/vtwe4eerf",
  }
}
a. Originator

A payer data contains info about payer of the TX.

Originator {
  name // string. required.
  paymail // string. required.
  avatar // string. optional.
  extendedData // object. optional, freestyle object.
}
nameName of payer.
avatarURL to an avatar.
paymailPayer’s paymail (where e.g. refunds will be send, identity can be use somehow etc.)
extendedDataAdditional optional data.
b. Ancestor

The details about this object are referenced in the Transactions Ancestors Standard


PaymentACK

PaymentACK is the final message in the payment protocol; it is sent from the payment host’s server to the bitcoin wallet in response to a Payment message:

PaymentACK {
  modeId // string. The chosen mode
  mode // object. The Payment object for the specific mode used.
  peerChannel // object. optional
  redirectUrl // string. optional
}
modeIdMode chosen from possible modes of PaymentTerms.
modeObject with data required by specific mode, e.g. HybridPaymentMode.
peerChannelData which specify created channel for secure direct communication. More info can be found here.
redirectUrl Optional URL where merchant wants customer to redirect after payment is done.

Example:

{
  modeId: "ef63d9775da5", // This ID is brfcid for HybridPaymentMode"
  mode: {
    ...  //HybridPaymentMode PaymentACK object
  },
  peerChannel: {
    host: "peerchannels:25009",
    token: "token",
    channel_id: "channelid",
  },
}

PaymentACK messages larger than 11 MB bytes should be rejected by the wallet application, to mitigate denial-of-service attacks. This is larger than the limits on Payment and PaymentTerms messages as PaymentACK contains a full Payment message within it.

Payment Modes

This is the main part of the PaymentTerms object. For now we propose one, flexible payment mode which you can use to pay with BSV, tokens, or a combination of funding sources (called HybridPaymentMode). In the future if HybridPaymentMode cannot fullfil some requirements, other PaymentModes can be specified. Chosen payment mode also has impact on the format of Payment and PaymentACK objects which might differ for different modes.

In the next section, predefined mode – HybridPaymentMode will be described together with related Payment and PaymentACK objects.

HybridPaymentMode (BRFCID: ef63d9775da5)

This is first defined payment which may fullfil a lot of requirements because of its flexible nature. It allows for a payment host to stipulate payment from a set of funding types created with AND and OR connections. With this arrangement a payment host can define a set of various outputs (tokens + BSV + loyalty points + stable coins) or even multiple equivalent alternatives to successfully fund the transaction. The wallet may chose which option depending upon user resources. This is the definition of the mode:

Options {
  "ID": Transactions // required, min one key-value pair.                   
}

So this payment mode just contains a dictionary of various options (options are OR relation, so they are alternative sets of outputs and the customer or their wallet will pick one).

Options (In PaymentTerms)

Every option contains a set of transactions (AND relation, if the customer chooses the option they must provide all the required funds to satisfy the transaction). Below you can find the interface for transaction object and transaction’s internal objects.

Transaction

Transaction object is a set which contains 3 parts:

  1. Outputs: A way of specifying a Bitcoin transaction output, including the value and script for various token standards.
  2. Inputs: A way of declaring which specific inputs should be used (useful for multisig, payment_channels etc).
  3. Policies: A way of requesting specific TX policies like fees, SPV, nLockTime etc.
Transaction {
  outputs // list of output objects. required
  inputs // list of input objects. optional
  policies // additional properties and requirements for transaction. optional
}


Outputs

List of outputs – payment destinations.

Outputs {
  native // list of native output objects. optional.
  brfcXYZ // list of brfc objects of XYZ token. optional.
  tokenABC // list of ABC token objects. optional.
  ...
}

Native output

Outputs are used in PaymentTerms messages to specify where a payment (or part of a payment) should be sent. They are also used in Payment messages to specify where a refund should be sent.

Native output {
  amount // number. required.
  script // string. required. hexadecimal script.
  description // string. optional. must not have JSON string length of greater than 100.
}
amountNumber of satoshis (0.00000001 BSV) to be paid.
scriptA “TxOut” script where payment should be sent, formatted as a hexadecimal string.
descriptionAn optional description such as “tip” or “sales tax”. Maximum length is 50 characters.

TokenXYZ

Structure for this object is specific for each particular token standard. This may be based on BRFC reference if said token standard hasn’t published a name yet or otherwise based upon a particular token’s name. Below are two example schemas:

brfc1234 {
  properties_1
  properties_2
  ...
}

stasToken {
  token_id // string. required
  script // string. required. hexadecimal script.
  ...
}

Inputs

A list of inputs object contains data needed to specify the required inputs which should be used.

Input {
  scriptSig // string. required.
  txid // string. required.
  vout // integer. required.
  value // integer. required.
  nSequence// number. optional.
}
scriptSigThe hexadecimal unlocking script for the input UTXO (or an empty string)
txidThe transaction index of the transaction containing the input UTXO.
voutThe index of the UTXO in the transaction.
valueThe amount of satoshis locked in the input UTXO.
nSequenceSpecific nSequence value required in transaction which will be created from the PaymentTerms. If set as non-default makes transaction not final (it goes to non-final mempool). More info: https://wiki.bitcoinsv.io/index.php/NLocktime_and_nSequence

Policies

An object containing some policy information like fees or spv envelope.

Policies {
  fees // dictionary. optional. Nested dictionary which include on Fee objects on 3rd level.
  SPVRequired // boolean. optional. default is false.
  lockTime // number. optional.  
}
feesDictionary containing “data” and “standard” keys which points to another dictionary with “mining“ and “relay” keys. “mining” and “relay” points to Fee object. It looks like this:
"fees": {
"data": {
"satoshis": ..,
"bytes": ..,
},
"standard": {
"satoshis": ..,
"bytes": ..

}
}
SPVRequiredPoints if it is required to provide merkle proof
lockTimeSpecific nLockTime value required in transaction which will be created from the PaymentTerms. If not set, default is 0 what means transaction will be mined by miner as soon as possible. Other value then zero request a delay. More info: https://wiki.bitcoinsv.io/index.php/NLocktime_and_nSequence

Mode (In Payment)

This object defines fields required by HybridPaymentMode. In this mode important data are chosen for payment option (paymentId) and a list of transactions which fulfil this option:

"ef63d9775da5" {
  optionId // string. ID of chosen payment options
  transactions // a list of raw transactions. required (if above depracated was not provided)
  ancestor // object. optional.
}
transactionsA list of valid, signed Bitcoin transactions that fully pays the PaymentTerms. The transaction is hex-encoded and must NOT be prefixed with “0x”. The order of transactions should match the order from PaymentTerms for this mode.
optionIdIdentification of chosen option from PaymentTerms.
ancestorsAncestor TX together with MerkleProof needed when SPV is used. More info about it you can find here.

Example:

{
  optionId: "choiceID1",
  transactions: [
    " RAW_TRANSACTION for 'choiceID1.transactions[0]' ",
    " RAW_TRANSACTION for 'choiceID1.transactions[1]' ",
  ],
  ancestors: {
    " TXID of RAW_TRANSACTION for 'choiceID1.transactions[1]' ": {
      /* This object has the ancestors of 'choiceID1.transactions[1]' */
    },
  }
}


Mode (In PaymentACK)

This object defines fields required by HybridPaymentMode:

{
  transactionIds // a list of transaction ids. required
  peerChannel // object. optional
}
transactionIdsList of transaction IDs from the Payment transactions which were broadcast by merchant.
peerChannelData which specify a created channel for secure direct communication. More info can be found here.

Example:

{
  transactions: [
    " TXID of transaction for 'choiceID1.transactions[0]' ",
    " TXID of transaction for 'choiceID1.transactions[1]' ",
  ],
  // Things like peer_channel should probably still be defined at the paymentAck root level. Different transactions should probably not have different peer_channel-s.
  peerChannel: {
    host: "peerchannels:25009",
    token: "token",
    channel_id: "channelid",
  },
}

API definition

Below is the table with messages requested from client (wallet) to merchant (server).

PaymentID parameter is assumed to be known as a result of request between client-server before DPP protocol operation (the first request/response on the diagram).

Message Endpoints Type/Subtype Response codes
PaymentTermsGET
/api/v1/payment/{paymentID}
application/json200 – contains PaymentTerms JSON object with all data used by the payee to construct a transaction
404 – returned if the paymentID has not been found
500 – returned if there is an unexpected internal error
PaymentPOST
/api/v1/payment/{paymentID}
application/json201 – contains PaymentACK JSON object
400 – returned if the user input is invalid, usually an issue with the paymentID
404 – returned if the paymentID has not been found
500 – returned if there is an unexpected internal error

For more info you can refer to: https://jadwahab.github.io/direct-payment-protocol/#/


URI Scheme

URI scheme for 4P protocol represents a scheme for downloading the PaymentTerms object; which is the beginning of the payment process.

The URI is to allow users to click on a link in a web page, email or scan a QR codes to initiate the payment protocol.

The scheme is following:

pay:?r=https://merchant.com/pay.php?h%3D2a8628fc2fbe

Localization

Payment hosts that support multiple languages should generate language-specific PaymentTerms, and either associate the language with the request or embed a language tag in the request’s merchantData. They should also generate a language-specific PaymentACK based on the original request.

For example: A greek-speaking customer browsing the Greek version of a payment host’s website clicks on a “Αγορά τώρα” link, which generates a PaymentTerms with merchantData set to “lang=el&basketId=11252”. The customer pays, their bitcoin client sends a Payment message, and the payment host’s website responds with PaymentACK.message “σας ευχαριστούμε”.

Certificates

The original BIP 70 which this spec is based on included signatures from X.509 certificates (the same certificates used for SSL / TLS / HTTPS). We assume the authentication happens at a separate layer and as such for simplicity we have removed authentication from BIP 270. Wallets should use other mechanisms to determine the name and identify of the recipient in a secure manner. Under the usual case on the web, BIP 270 messages will be sent and received over HTTPS, which uses X.509 certificates, and thus the wallet should simply show the domain name under most cases. HTTP (and insecure form of HTTPS) should not be supported.

Extensibility

We use JSON as JSON is naturally extensible. Any property of the objects not specified in this spec is a candidate to convey information for extensions.

Notes

Where message length limits are described in MB, or other units, they should be taken to be the SI form. Therefore 10MB means 10,000,000 bytes, and not 10MiB which would be 10,485,760 bytes.

A previous draft of DPP required scripts be formatted as a human-readable “isomorphic” ASM-formatted string, to simplify debugging. However ASM is a UI concept; it is best left to user-facing software to decide how display scripts readably rather than enshrining it in a network protocol.

ASM also has some disadvantages, including:

  • it is a more verbose serialization giving larger message sizes
  • correct serialization and deserialization is a tricky, arcane process which would raise the chance of implementations differing in corner cases
  • not all scripts have a representation as “isomorphic” ASM
  • it is ill-defined when BSV moves CScriptNum from 4-byte integers to bignums, because data pushes that can be represented as a CScriptNum are serialized in decimal, and all other data pushes are serialized as hexadecimal. Digit strings that are valid decimal and hexadecimal are therefore resolved merely on the basis of whether their interpretation as decimal can fit into a CScriptNum
  • ASM is ill-defined during any future enablement or transition of OpCodes

By contrast hexadecimal script is easy to implement and unambiguous.

History

ArtefactDescription
Erratan/a
Change Logn/a
Decision Logn/a

Relationships

RelationshipDescription
IP licences and dependenciesLicensing terms to be announced
Copyright© 2022 Bitcoin Association. All rights reserved. Unless otherwise specified, or required in the context of its implementation on BSV Blockchain, no part of this standard may be reproduced or utilised otherwise in any form or by any means, electronic or mechanical, including photocopying, or posting on the internet or an intranet, without prior written permission of Bitcoin Association.
Extendsn/a
Modifiesn/a
Deprecatesn/a
Depends Onn/a
Prior ArtFoundation:

BIP70
BIP270
BIP271
BIP272
BIP273: (not addressed → In my opinion it goes beyond BIP270, like it is about requesting invoice from customer to merchant, so before P4 starts. This is implemented by merchant’s individual API to which customer/wallet has to request for purchase order)
BIP274
BIP282
Existing Solutionn/a
Referencesn/a
Submit comments

This Standard is at the public review stage. To leave comments, feedbacks or suggestions please register below.

Already have an account?
Tags
Suggest new tags for this standard
or
Overview
Overview
Become a Contributor
If you wish to join us on this mission to make BSV the public blockchain of choice please fill in our preliminary registration form below. We look forward to having you on board.