Skip to content

Instantly share code, notes, and snippets.

@toby

toby/bip.md Secret

Last active January 29, 2016 01:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save toby/9e71811d387923a71a53 to your computer and use it in GitHub Desktop.
Save toby/9e71811d387923a71a53 to your computer and use it in GitHub Desktop.
Title: Allow zero value OP_RETURN in Payment Protocol
Author: Toby Padilla <tobypadilla@gmail.com>

Abstract

This BIP alters the Payment Protocol to allow for zero value OP_RETURN outputs in serialized PaymentRequests.

Motivation

The Payment Protocol (defined in BIP70) gives merchants a way to build sophisticated transactions by serializing one or more outputs in the form of a PaymentRequest. The PaymentRequest is then served over http/https to a customer's wallet where the serialized transaction can be executed.

While the Payment Protocol allows for any valid script in its outputs, it also ignores outputs with zero value. This means BIP70 implementations can encode an OP_RETURN script but must provide a greater than dust value for that output. The end result is a successful PaymentRequest transaction with an OP_RETURN but the value assigned to that output is lost forever.

This BIP allows for zero value OP_RETURN outputs in serialized PaymentRequests. The change means that OP_RETURN scripts will work as they were originally intended from within PaymentRequests without permanently destroying Bitcoin value. Zero value non-OP_RETURN scripts should continue to be ignored.

In addition to fixing the issue of destroyed value, this change opens up new use cases that were previously impossible.

While storing data on the blockchain is controversial, when used responsibly OP_RETURN provides a powerful mechanism for attaching metadata to a transaction. This BIP effectively decouples the creation of transactions containing OP_RETURN data from the execution of those transactions. The result are positive benefits for both merchants and wallets/customers.

By supporting this BIP, wallets can participate in current and future, unforeseen use cases that benefit from metadata stored in OP_RETURN. Until now OP_RETURN transactions have typically been created and submitted by custom software. If a wallet can process a PaymentRequest with OP_RETURN data as proposed by this BIP, it will support potentially sophisticated Bitcoin applications without the wallet developer having to have prior knowledge of that application.

An example might be a merchant that adds the hash of a plain text invoice to the checkout transaction. The merchant could construct the PaymentRequest with the invoice hash in an OP_RETURN and pass it to the customer's wallet. The wallet could then submit the transaction, including the invoice hash from the PaymentRequest. The wallet will have encoded a proof of purchase to the blockchain without the wallet developer having to coordinate with the merchant software or add features beyond this BIP.

Merchants and Bitcoin application developers benefit from this BIP because they can now construct transactions that include OP_RETURN data in a keyless environment. Again, prior to this BIP, transactions that used OP_RETURN (with zero value) needed to be constructed and executed in the same software. By separating the two concerns, this BIP allows merchant software to create transactions with OP_RETURN metadata on a server without storing public or private Bitcoin keys. This greatly enhances security where OP_RETURN applications currently need access to a private key to sign transactions.

Specification

The specification for this BIP is straightforward. BIP70 should be fully implemented with the following changes:

  • Outputs where the script is an OP_RETURN and the value is zero should be accepted by the wallet.

BIP70 has special handling for the case with multiple zero value outputs:

If the sum of outputs.amount is zero, the customer will be asked how much to pay, and the bitcoin client may choose any or all of the Outputs (if there are more than one) for payment. If the sum of outputs.amount is non-zero, then the customer will be asked to pay the sum, and the payment shall be split among the Outputs with non-zero amounts (if there are more than one; Outputs with zero amounts shall be ignored).

This behavior should be retained with the exception of OP_RETURN handling. In the case of a multiple output transaction where the sum of the output values is zero, the user should be prompted for a value and that value should be distributed over any or all outputs except the OP_RETURN output. In the case where the sum of outputs.amount is non-zero then any OP_RETURN outputs should not be ignored but no value should be assigned to them.

Payment requests also must contain at least one payable output (i.e. no payment requests with just an OP_RETURN).

Rationale

As with the discussion around vanilla OP_RETURN, the practice of storing data on the blockchain is controversial. While blockchain and network bloat is an undeniable issue, the benefits that come from attaching metadata to transactions has proven to be too powerful to dismiss entirely. In the absence of OP_RETURN support the Bitcoin ecosystem has seen alternative, less elegant and more wasteful methods employed for Blockchain data storage.

As it exists today, BIP70 allows for OP_RETURN data storage at the expense of permanently destroyed Bitcoin. Even fully removing support for OP_RETURN values in the Payment Protocol would still leave the door open to suboptimal data encoding via burning a larger than dust value to an output with a false address designed to encode data.

This BIP offers all of the same benefits that come from the OP_RETURN compromise. Mainly that OP_RETURN scripts are provably unspendable and thus can be pruned from the UTXO pool. Without supporting this BIP, wallets that support BIP70 will allow for wasteful data storage.

Compatibility

Since this BIP still supports OP_RETURN statements with a greater than zero value, it should be fully backwards compatible with any existing implementations.

@achow101
Copy link

I think it should still allow non-zero amounts in OP_RETURN for backwards compatibility. Is there any reason to reject non-zero amounts besides preventing users from burning coins?

@toby
Copy link
Author

toby commented Jan 26, 2016

@achow101 no, pretty much the only reason is to prevent burning. I think that's a worthy goal though. I'm curious how many implementations of > zero OP_RETURN payment requests exist in the wild. I'm doing it with my personal project http://key.run but I haven't seen it anywhere else.

@felipelalli
Copy link

@toby why do you consider to burn coins to be harmful?

@toby
Copy link
Author

toby commented Jan 26, 2016

@felipelalli because that value could be used to incentivize something else. Either the customer or the merchant would be better off with the money vs it going down a black hole.

@mrkent
Copy link

mrkent commented Jan 27, 2016

@toby, in the context of OP_RETURN, the burned coins is the price you pay for the publicly shared resource that is the blockchain. It makes sense that if you're storing data on the blockchain, everyone else should be rewarded for it (in the form of scarcer BTC). Otherwise, it'd cost nothing to fill up entire blocks with spam.

@toby
Copy link
Author

toby commented Jan 28, 2016

@mrkent thank you for the reply. I would argue that the increased utility of Bitcoin in the form of apps built with this proposed system would increase the overall value of Bitcoin much more than the tiny amount of burned value. Especially since it only becomes noticeable if lots of people are using it, hence something popular got built.

Also, OP_RETURN is designed to be as little burden on shared resources as possible. Since it's provably unspendable it can be pruned from the UTXO pool.

Otherwise, it'd cost nothing to fill up entire blocks with spam.

You still have to pay the mining fee, and in the case of this BIP will also have to have at least one payable output aside from the OP_RETURN.

@toby
Copy link
Author

toby commented Jan 29, 2016

@achow101 I've updated the PR and BIP to support greater than zero values as well as zero values. You and others brought up the same point, so I think it makes sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment