Author

Topic: Merchant-pays-fee proposal for Bitcoin Payment Messages (Read 2406 times)

legendary
Activity: 1106
Merit: 1004
I just quickly saw Gavin's blog post and this forum entry.

I'm posting here because I wonder if there's any chance of considering adding the fee information in the PaymentRequest, sort of like I proposed here https://bitcointalksearch.org/topic/proposal-merchant-specified-transaction-fee-in-bitcoin-uri-119086

The receiver specifies a formula in the payment request for the fee to be payed. The client software calculates the fee, but doesn't bother showing all this to the user: it just says "do you confirm paying (total) to (receiver)?.

I know that adding a chained transaction also allows the merchant to add a fee, but I still prefer the solution of specifying via a PaymentRequest, since it decreases the amount of bandwidth that will be required to run a full node.

Just an idea.
hero member
Activity: 555
Merit: 654
Meh.

Lots of other ways that merchants could arrange to pay transaction fees, I don't think we need a hard fork to solve that problem.

E.g. : child-pays-for-parent.



I think child-pays-for-parent would solve the problem without a hard fork. I didn´t know it was already coded. If you decide to integrate it, I will review the code looking at DoS attacks.

The extensions proposed to the Payment protocol are interesting, but child-pays-for-parent is much simpler for the fee problem.
full member
Activity: 154
Merit: 100
Regardless, I think this highlights some shortcomings in the payment protocol as it stands. It's been designed with a focus on merchants and as such is overly limited in its use for different use-cases. At its heart, it provides a mechanism for building a specific type of transaction between two parties without the users having to mess around with raw transactions. If you think a little bigger, you can cover the case of arbitrary transaction building and signing between multiple (not just 2) parties which subsumes the use-cases already catered for.

The current idea is that the merchant specifies which outputs the user should pay to and expects the transaction to be returned complete and signed.

The idea I've just come up with is that a general transaction (not just outputs) is passed around being build over a number of exchanges without the client software needing to know anything about how the exchange should happen. Signatures are not necessarily required, so arbitrary transactions can be built between multiple clients and a single server, allowing users to review the final transaction before authorizing it.

The thing that gets passed around is a transaction and some details about how the client should further build the transaction - what it should add to the transaction or if it should sign it. Wrap this as before with other useful details like the url, pki-sign etc.

Code:
message BuildDetails {
    // max number of inputs to add. Thus zero prevents adding inputs, one allows
    // enforcement of SIGHASH_SINGLE, other values to prevent huge dust txns etc
    optional uint_64 maxInputs;

    // total value of the inputs you need to provide
    optional uint_64 inputsValue;


    // max number of outputs to add (thus zero prevents adding outputs etc)
    optional uint_64 maxOutputs;

    // total value of the outputs you need to provide
    optional uint_64 outputsValue;

    
    // whether you need to sign the inputs
    required boolean sign;

    // how to sign them
    optional uint_8 sigHash;
}

message TxBuilder {
    optional bytes transaction;
    required BuildDetails buildDetails;
}

Now, in the standard use-case, originally the merchant creates the outputs he wants and wraps them in a PaymentDetails object and signs it, creating a PaymentRequest.
He sends it to the user who's client interprets this to mean 'I should add some inputs to pay for those outputs, (and maybe add an output for my change), sign it, and then send it back to the url given'. This interpretation is all implicit and built in and thus is limiting.

With the TxBuilder approach the interpretation is explicit.
The merchant takes the outputs he wants as before and creates a transaction. He wants the user to provide inputs who's value matches his outputs, so he specifies the 'inputsValue' and he wants the transaction to be signed, so he specifies this too. He doesn't care about additional outputs (maybe he cares about not creating a huge transaction, so limits outputs to 1 - whatever).
The user's client can read the build details and determine that it wants him to provide input of a certain value, is free to add outputs how he pleases and should sign the result.

My solution to Sergio's use case is also possible now:
Merchant creates a Tx with the output for his payment (maybe not with his change output yet). He specifies the value that the inputs should total and specifies that the transaction should NOT be signed.

The user's client can easily determine what is required and inform the user of the details if need be (as no signature is needed, there is little harm either way). The user agrees and the client fills in the inputs, adds a change output for itself and sends the transaction back.
The merchant can then add his fee payment input and change output. He specifies 0 inputs or outputs are to be added, and specifies to sign the transaction with SIGHASH_ALL.

The users client can then display the details of the final transaction and ask if the user agrees to sign. If so, it returns the almost completed transaction to the merchant who signs it himself (or of course he signs it in the previous step and gives up his ability to refuse the transaction).

The merchant can finally issue an acknowledgement as before so that the user knows that the exchange is complete and its status.


EDIT: @Sergio, sorry for hijacking
legendary
Activity: 1428
Merit: 1093
Core Armory Developer
Wait, what's wrong with the merchant saying "You bill is 5.0 BTC.  We cover up to 0.01 fee, so you can send us 4.99".
full member
Activity: 154
Merit: 100
Lots of other ways that merchants could arrange to pay transaction fees, I don't think we need a hard fork to solve that problem.

Agreed

Or an extension to the payment protocol so the merchant provides an already-signed SIGHASH_SINGLE / SIGHASH_ANYONECANPAY input to pay the fee that the client includes as the first input in the transaction.

You've kind of missed the point. The problem Sergio is addressing is that the merchant needs to include an output for his change after paying the fee, and the payee needs to have an output for his own change. Thus you end up with 3 outputs. The merchant does not know what the change address is for the payee, so cannot create a transaction with all the outputs without asking the payee. SIGHASH_SINGLE can help because it allows you to add outputs but is crippled because you don't have a choice as to which output you are signing, in particular this isn't helpful if your funds are spread about a lot and have to use multiple inputs because now the input and output indices cannot possibly match.

Your solution assumes that the merchant has an unspent output with the exact amount needed for the fee. If instead he needs to use multiple inputs, then he can't use SIGHASH_SINGLE. If he does indeed have the exact amount in 1 unspent output, then there is no need to provide his payment first, he can simply add it after.

Also the merchant shouldn't already sign it because then he loses the power to reject the payment. The payee can take the fee amount off the amount owed and only pay the difference. The transaction will be valid but with a smaller (no fee) and the payee can broadcast it themselves.


I think the solution is simply have the payee provide the merchant with a partial transaction with all his details included (but not signed obviously!). It has each of his inputs and includes a single output for his own change so that the difference in value is the exact value of the thing he is purchasing. The merchant then can add the output for the actual payment, inputs to pay for the fee and another output for his own change. He sends this back to the payee who signs it and sends to the merchant who finally chooses whether to accept or decline. If he accepts he can sign it himself and broadcast.
legendary
Activity: 1652
Merit: 2301
Chief Scientist
Meh.

Lots of other ways that merchants could arrange to pay transaction fees, I don't think we need a hard fork to solve that problem.

E.g. : child-pays-for-parent.

Or an extension to the payment protocol so the merchant provides an already-signed SIGHASH_SINGLE / SIGHASH_ANYONECANPAY input to pay the fee that the client includes as the first input in the transaction.

hero member
Activity: 555
Merit: 654
One of the ideas in the Bitcoin Payment Messages (https://gist.github.com/gavinandresen/4120476) is that the merchant could pay for the fees of a transaction.

The idea of merchant-pays-fee could be solved by extending the transaction verification system. A new SIGHASH_MULTI flag is added. This flags takes a two argument, which is the output index to start from (outIndex) and the number of outputs to sign (numOuts).

This is what it does:

-   The output of txCopy is resized to the size to 2
-   All other txCopy outputs aside from the output at outIndex and the one at outIndex+1 are removed completely.
-   All other txCopy inputs aside from the current input are set to have an nSequence index of zero.

Think of this as "sign a subset of the outputs-- I don't care where the other outputs go".

When this flag is combined with SIGHASH_ANYONECANPAY, then the sender can:

Create a transaction with many inputs i(0),i(1),(i)2.. i(n-1).
For i(0).. i(n-1) the users sign them with SIGHASH_ANYONECANPAY | SIGHASH_MULTI (0,2)

Then the user puts two outputs: one for the merchant and another for change. He puts no fees.

When the merchant wants to add fees, he adds another input m(n) and a single output for the fee change.

To extend this protocol to allow a merchant to mix multiple transactions together and add a single fee tx, then another flag SIG_MULTIHASH could be used that specifies the HASH of the output script  (OutputHashStart), and the number of outputs. (numOuts)

Then clients would search for the outputs to hash when OP_CHECKSIG is executed.

The merchant can then combine tx(1) ... tx(n) into TX by only appending the transactions and adding a new input and a new output.

The only problem I see with the proposal is that if a transaction can be sliced to form valid transactions, then the algorithm that detects double-spends should be modified to discard a transaction tx y another transaction TX is received and contains tx in it.

Best regards, Sergio.
Jump to: