Author

Topic: Commit your "replaced" transactions into your new R-value (Read 120 times)

copper member
Activity: 906
Merit: 2258
Quote
but what you just said about first seen
That name "first seen" was not invented by me. You can read more about "first seen rule" in many places. For example: https://en.bitcoin.it/wiki/Replace_by_fee

Quote
does that mean we can disable double spending by having a standard global rule, correct?
Well, if something is included in a block, then you cannot double-spend it, without reorganizing the chain, and this rule is already standardized. The whole topic is about handling transactions, before they are confirmed. You can read more about the history of replacing transactions in the link above.

Quote
with your ideas we could scale Bitcoin beyond any previously thought to be possible limits?
Well, some people proposed some similar solutions in the past, so it is rather based on existing ideas, than invented from scratch. For example, you can read more about cut-through in this topic: https://bitcointalksearch.org/topic/transaction-cut-through-281848

Also, commitments were mentioned in different places, for example here: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-November/022176.html
Quote
Sign-to-contract looks like:

 * generate a secret random nonce r0
 * calculate the public version R0 = r0*G
 * calculate a derived nonce r = r0 + SHA256(R0, data), where "data"
   is what you want to commit to
 * generate your signature using public nonce R=r*G as usual
copper member
Activity: 1330
Merit: 899
🖤😏
I'm a noob in under the hood of blockchain technicals, but what you just said about first seen, does that mean we can disable double spending by having a standard global rule, correct?

Correct me if I'm wrong, with your ideas we could scale Bitcoin beyond any previously thought to be possible limits?
copper member
Activity: 906
Merit: 2258
Quote
But then this requires interested parties to know exactly what the data is to verify it.
Exactly. If you don't have that data, then there is always no match.

Quote
So how would somebody in the public discover a commitment?
If some node received some old transaction, and then it receives the new one, then that node can check, if the old transaction is committed to the new one. If it is, then things are replaced. If not, then it is possible to create some "first-seen" rule, and reject it.

Quote
Would it be something like Silent Payments where all incoming transactions must be parsed to see if they have a commitment value?
You don't have to check everything. If Alice->Charlie is the first transaction you see, then Alice->Bob and Bob->Charlie will have lower fee, so they will be rejected upfront, because of that. However, if you see Alice->Bob transaction and Bob->Charlie transaction first, then Alice->Charlie is a double-spend from your perspective. And then, you can check that commitment to see, that it was intended by the user.

Quote
And what's to stop a person from making an invalid commit?
The same, what's to stop a person from making an invalid transaction. Commitments are hard to match, and easy to non-match. You need exactly the right data in the right format, to have a match, in all other cases, the node will use the rules which exist today. Which also means, if commitments will not be standardized, then there will be a lot of non-matching cases, and then nodes will behave as today. So, if you want to have any node policy, then you are forced to standardize it, and stick to some upfront-agreed format, because in other case, you will have non-match, and treat invalid commitment in the same way, as empty commitment, or no commitment at all.

Quote
Maybe by using the data to make a hash for the r-value for the first RBF transaction, then using that r-value to make a new r-value for the next transaction, etc.
In general, I can imagine it in a tree-like structure. Which means, if Alice->Bob and Bob->Charlie will be joined into Alice->Charlie, then of course Alice->Charlie and Charlie->Daniel could be later joined into Alice->Daniel, if it will be unconfirmed for a long enough time. Which means, it is possible to build quite long chains. And to make things simple, it should be tree-based, to access each participant with logarithmic complexity, instead of linear.
legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
Nice.

I sorta get how this works (I think), since you just pick a format to represent the data in, then hash the data into a 256-bit nonce - which would make it deterministic in the process - and use that for R calculation. But then this requires interested parties to know exactly what the data is to verify it.

So how would somebody in the public discover a commitment? Would it be something like Silent Payments where all incoming transactions must be parsed to see if they have a commitment value?

And what's to stop a person from making an invalid commit? Maybe by using the data to make a hash for the r-value for the first RBF transaction, then using that r-value to make a new r-value for the next transaction, etc.
copper member
Activity: 906
Merit: 2258
This is just an idea, and I think in general, it should be standardized, but I will share it now, to inform people, what is possible.

The first thing to note is that full-RBF is more and more active. It allows fully replacing things, which are unconfirmed. Which means, you can no longer trust any unconfirmed transactions, because they are, well, unconfirmed.

However, some people still want to have some kind of "first-seen", or some other way of knowing, what happened first. For now, many nodes and block explorers just trace all transactions, so you can see the full history of "replaced by", for example on mempool.space.

But still, if you optimize a chain of transactions Alice->Bob->Charlie into Alice->Charlie, then Bob probably wants to have any way of seeing later, that he "owned" some coins, and that he was in the middle of this chain. For some purposes, it may be important, so this post will tell you, how to achieve that.

The first thing to note, is that your R-value in any of your signature, regardless of the type of address you use, can be safely used to make commitments. Which means, each time you have any signature anywhere, in your input, in your output, in your witness, just anywhere, it means you have two options: pick a random R-value, or tweak it, and create a strong, cryptographically-based connection, between your R-value, and any data you want to commit, without pushing that data on-chain.

So, what should be put inside such commitment? Probably the best thing to do, is to put some proof, that Bob was between Alice and Charlie, and he received something from Alice, and later agreed to pass it into Charlie. If such proof will be present, then future nodes could apply any mempool policy, to allow double-spending some unconfirmed transaction, only if the earlier recipient agreed to do so.

The only way, that can safely cover all cases, is just putting both Alice->Bob and Bob->Charlie transactions into such commitment. Because the commitment is never pushed on-chain, that should not be a problem, and can be done with zero additional on-chain bytes, so also zero additional on-chain fees. However, there are probably better ways to do that, for example UTXO-based, or signature-based, but this post is just an idea, that is yet to be clarified, and which didn't pass testing phase yet (but I think it is worth sharing, and also some people asked me to share it earlier anyway, also to show some people, what kind of ideas I have in store).

That kind of system can be scaled in a way of binary tree, similar to merkle root. Which means, if we standardize it as "two transactions, to proof what was inside", then it can be expanded when needed. Which means, if we have the first proof that only Bob was inside, we need two transactions: Alice->Bob, and Bob->Charlie. But if we want to prove, that Daniel was between Alice and Bob, then it can be included into the commitment of the Alice->Bob transaction! Which means, things can be nested in a tree-like structure, and to know, what is inside, the only thing that is needed, is some matching inputs and outputs in both committed transactions. If the commitment matches used sighashes, it should be sufficient as a proof. Which means, in SIGHASH_ALL, everything should match exactly, but in case of other sighashes, it could be weaker, because it should be compatible with the way things were signed.

There are more things to handle, like "how the commitment should look like, exactly, byte-by-byte" or "what to do with invalid commitments" or "what if nothing is committed, and R-value is just random", but I think this description above should give you more information to ask more questions, and I think they will lead this topic better than me, trying to guess upfront, what is the most interesting for the audience. Thoughts?
Jump to: