What if I told you that there was a way to have extremely reliable "zero-conf" near-instant transactions on BCH? What if I told you that the software changes required to achieve this feat were straightforward and wouldn't even require a hard fork upgrade? You'd be interested, right?
Background
So it turns out that there are three forms of double-spending attacks possible on Bitcoin Cash:
fast respend
reverse respend
miner bribe
Fast Respend: This is what most people think of when they think of a double-spend attempt. The fraudster has a special wallet that broadcasts one transaction that the merchant sees and accepts as valid. Immediately after sending that transaction, the fraudster sends another transaction that sends the same coins back to himself. By optimizing the way the transactions are broadcast, the fraudster can sometimes get his coins back, and the merchant is unaware until the next block is mined containing the fraud transaction.
Reverse Respend: This is a form of attack in which the fraudster sends a very low fee fraud transaction prior to making the "valid" transaction. If the fee is low enough, the transaction will not propagate, and the merchant will not see it, but a miner will. Thus the merchant will accept the later, "valid" transaction which will be propagated to the rest of the network. If the miner who received the first transaction finds the next block, and if they operate under the standard "first seen" rule, then they will mine the fraud transaction.
Miner Bribe (aka illicit RBF): This final form of attack requires a complicit miner. In this attack, the fraudster pays the merchant using a "valid" transaction, then broadcasts another transaction that sends the coins back to himself, but paying a significantly higher fee than the first transaction, thus "bribing" the complicit miner to mine the higher-fee transaction instead of the legitimate transaction.
Good News / Bad News
The good news is that we already have a good solution to the "fast respend" fraud attempt in the form of double-spend proofs. These work roughly as follows: if a node sees two conflicting versions of the same transaction, it creates a cryptographic proof of the existence of the conflict, and broadcasts this proof to other nodes. This doesn't prevent the "fraud" transaction from confirming, but it does alert the merchant that the attempt has taken place. Since this form of attack requires the conflicting transaction to be broadcast practically simultaneously with the "legitimate" transaction, the merchant should see the fraud proof within a few seconds of the attempt, and be able to prevent the fraud from succeeding.
The bad news is that the other forms of double-spend attempts remain mostly unsolved. The reverse-respend attempt has been mitigated somewhat by working with miners and node operators to have a consistent minfee / relay acceptance policy, but this requires a lot of coordination among miners and is a partial solution at best.
The "miner bribe" attack remains completely unsolved. It is the goal of "pre-consensus" engineering projects like Avalanche to solve this remaining form of double-spend attempts -- but Avalanche is a very complex engineering problem to solve, and is highly controversial.
Arriving at a Solution
When trying to creatively solve a problem, a very common framework is to "break a rule" -- to challenge existing norms and fundamental assumptions to see if, by breaking an assumption, the "problem" suddenly goes away.
And that's when it hit me. It turns out that half of the problem with zero-conf results from an old assumption - a "loose end" left by Satoshi. If we could unmake this assumption, we could fix zero-conf for almost all usecases.
By unmaking this assumption, we arrive at a solution to the "reverse-respend" and "miner bribe" problems that is elegant, simple, and foolproof. The solution is bone-headed simple to deploy - and it wouldn't even require a hard fork. This solution would eliminate - not mitigate - these forms of double-spend attempts.
The result would be that any transaction broadcast and seen by the network could be assumed to always propagate, to always eventually confirm, and to never be replaced by another transaction. Combined with double-spend proofs to handle the edge case of conflicting transactions broadcast simultaneously, this solution would allow us to realize the original goals of Bitcoin as a fire and forget system where users could safely broadcast transactions and trust that they would be confirmed.
Before I tell you the solution, I'm going to warn you: you might not like this solution at first. It might offend certain preconceptions about how Bitcoin "should" work. I implore you to try to have an open mind to this solution, before you reject it out of hand. First I'll give you the simple version of the solution, and then we can discuss pros and cons, and some ways it might be tweaked.
The Solution
And the solution is: a consensus-level transaction fee.
In its simplest form, this would be a fee requirement (ostensibly "satoshis per byte") set as a consensus rule. If any transaction fails to pay sufficient fee, it's invalid. If any transaction overpays the fee, it's invalid. All transactions pay the same fee per byte. All of them. No more, no less. If a miner takes a "bribe fee" or accepts an "underfee," then their block is rejected by the network.
Already I can feel your objections to this proposal! Wait just a couple more paragraphs before rejecting it. Stop to consider what this change would buy us:
Reverse respend and miner bribes are eliminated as a way to defraud. Combined with double-spend proofs, this closes the door on zero-conf fraud. Unconfirmed transactions would become practically bulletproof. Propagation issues due to policy conflicts likewise vanish.
Incredibly simple implementation. Compared to super-complex "preconsensus" plans like Avalanche or subchains, this would be a change that could be implemented in a minimal number of lines of code.
Soft-fork change. This change would be a soft-fork to the network, and would therefore be able to be implemented with lower risk of network disruption.
Eliminates malformed fee overpayments. This is a tiny benefit that is still worth mentioning. Every so often we hear of a transaction confirming that paid a gigantic fee because something in the sending wallet broke or someone was hand-crafting a txn and screwed up. None of these transactions would be valid under a consensus fee approach.
Eliminates low-fee stuck payments. A similar problem sometimes happens with custom wallets where the user includes an insufficient fee and the transaction hangs in limbo for weeks. Such a transaction would always be invalid and would never be accepted by the network.
Removes the incentive for miners to choke capacity. If there is a consensus fee rule, then there is no incentive for miners to artificially limit capacity to try to juke up fees. By setting a consensus fee rule we make it clear to miners that the only way to increase their marginal revenue is to accept more transactions.
Here's how the network would feel under a consensus-fee regime:
Alice sends Bob some BCH. Maybe Bob is a brick-and-mortar merchant, or maybe he sells digital assets for immediate download.
When Bob sees the transaction, he checks to make sure it's paying the consensus fee. Assuming it is, he rebroadcasts it to ensure that many network nodes see and propagate it; then he waits a few seconds to see if a double-spend proof arrives. Once Bob is reasonably confident that Alice didn't broadcast an alternate transaction, Bob can safely let Alice have the merchandise or let her download the digital asset. The double-spend proofs give Bob confidence that "honest nodes" haven't seen another version of the transaction, and he knows that Alice cannot trick or bribe miners into mining a higher-paying (or lower-paying) version of the transaction.
This is "zero conf" the way we always wanted it to work. No messy "preconsensus" needed.
Exchanges Excluded
The one place a consensus fee wouldn't help is exchanges. A consensus fee wouldn't change the confirmation requirement for exchanges, because while the consensus fee does prevent miners from being bribed or tricked by low-fee txns, it doesn't prevent a dishonest miner from sending his coins to an exchange and then spending them back to himself by mining a replacement transaction that also pays the consensus fee.
Since miners can still perform transaction replacement of their own transactions (or those of accomplices), the consensus fee probably doesn't allow instant purchases of high-value goods like gold, homes, bags of cash, or luxury cars; however, it's unclear that there exists any requirement for "instant" sales of Lambos. If you're buying a car, or a home, or a truckful of gold bars, the process is already sufficiently lengthy to allow for confirmations.
Problems with a Consensus Fee
The following is an incomplete list of some of the issues with this approach.
Begins to break down under "always full blocks" assumptions. If blocks are always full, with a large backlog, it's possible that unconfirmed transactions could get dropped. A consensus fee can't solve the problem of a dropped transaction. Obviously, one of BCH's engineering goals is to never run into the situation of always-full-blocks with transactions that drop from the mempool -- and it's arguable that all blockchains "fail" in this condition -- they just "fail differently."
May exclude very low-value microtransactions or non-financial uses of the blockchain. Depending on your point of view, this may be a bug, or it may be a feature (I lean towards "feature"). If the community feels this is sufficiently problematic, it could possibly be solved by creating a "tiered" fee structure in which a certain amount of block space is allocated for low-value txns that meet certain criteria (ie. "Non Financial Transaction" flag).
Could result in a future split over fee levels. If BCH is wildly successful, it's possible that some users may feel strongly that fees should be lower, or higher, or that there should be more or fewer fee tiers. Maintaining consensus over "the fair fee" isn't problematic when the coin is undervalued and the chain is underutilized, but could become contentious under conditions of success. I file this under "risks worth taking" aka "good problems to have" since it's a problem that would only manifest under extremely good outcomes for BCH.
Will require changes to all wallets and node software. This is the biggest technical impediment in my view. While the changes are simple to make (make sure the app pays the right fee), they will have to be made to all applications that use the BCH blockchain, else those apps may allow the creation of invalid (pays too much / too little) transactions.
When you consider the benefits -- that is, effectively "solving" the double-spending problem in an absurdly simple manner -- without resorting to complicated, esoteric, and controversial solutions like subchains or Avalanche -- I think the problems are very small by comparison. With a consensus fee - plus double-spend proofs - we close the loopholes to double-spending elegantly and simply. These are small prices to pay to achieve our vision of safe, secure instant merchant transactions, and much less disruptive than "preconsensus."
The Catch?
Which brings me to my greatest potential issue with this proposal, and that is that it may offend people's ideas about the way Bitcoin "should" work - namely, that the change to a consensus fee instead of a "fee market" doesn't "feel like" Bitcoin.
I want to challenge that assumption.
Let's not lose sight of the fact that Bitcoin Cash divorced itself from the BTC development strategy literally because BTC had the goal of "creating a fee market" by having "always full blocks." BCH has a stretch goal of having "never full blocks" with "always low fees." As a matter of social contract, we tell everyone that nobody should ever have to pay more than (for example) 1sat/byte. Why not incorporate that social contract into a consensus rule, and reap the rewards?
If BCH is able to keep block size relatively unconstrained, then there should never be a need to pay more than the recommended fee/byte. And as we've seen, there are problems to allowing lower-than-recommended fees (transactions that don't propagate, reverse respend vulnerabilities). Fees on BCH are like Goldilocks porridge: if the network is running correctly according to our engineering goals, fees should never be above or below the recommendation. We are already having to coordinate a network-wide minfee anyway to prevent propagation problems. Why not incorporate our engineering objectives into a consensus rule, and reap the rewards?
We should realize that block size doesn't exist in a vacuum: it is directly related to required fee. If BCH starts to fill up blocks, then we all agree the first order of business is to increase block size as far as the engineering will allow; and only then to allow fees to increase. So we should only have to increase the consensus fee once we've exhausted engineering limits -- again, this is a "good problem" that can only occur because we've been incredibly successful.
And if we should find ourselves in the incredibly enviable position of being so successful that we fill blocks up to their known engineering limits with fee-paying transactions, then at that point we might be able to deploy a "flex consensus fee" much the same way that we think about a "flexible max block size." While I've presented the "really simple" version of a flat consensus fee for the purpose of simplicity, we should realize that a lot of variations on this theme could exist, like a tiered fee structure, reduced fees for consolidation or CashFusion txns, etc. I could even envision a world where the fee is set in conjunction with an oracle that prices the fee/byte in "stablecoin" values, so that it's always the same "price per byte" irrespective of the market value of BCH.
I Don't Like Command-And-Control Either
There's a certain type of BCH user that is automatically opposed to anything that feels like a "command economy." I'm sensitive to this point of view. But a consensus fee isn't Big Brother telling you the price of a loaf of bread. Here's why.
I want you to imagine a world where you go to a Starbucks and there are no prices on the board. Instead, you're supposed to bid for your coffee in a blind auction. When placing your bid, you should take into consideration factors like: the size of your coffee, the time of day, the number of other people in line ahead of you, and how urgent your coffee is. You should make sure to consider the possibility that a busload of rich tourists might arrive at any moment who will outbid everyone in the room, and factor that possibility into your bid.
Is Starbucks "wrong" for having centralized control over its menu pricing? Is Starbucks rejecting the free-market? Would a "wild-west free-market" approach be better? Of course not. Personally I've never been happy with the idea that the cost to execute a Bitcoin transaction is some sort of unknowable mystery. I think most users would love the idea of a known "price menu" for their transactions.
The idea that transaction fees needed to be a competitive auction for a fundamentally scarce bit of block space was an idea foisted on Bitcoin from the outside by the people who wanted to make transactions expensive. If you operate under the philosophy that blocks should not be artificially constrained, then you reach the conclusion that it should be possible to have a fixed price for block space; and if the natural limits to block space are ever reached, then at that point the price can be raised. if needed.
The fact is that consensus is required among all participants of a blockchain. We have consensus rules that limit how much block space is allocated, that limit how much miners can mint in each block, and how much random data can be attached to each transaction. We can also decide on a fair price per transaction that, like the block size, can be adjusted up (or down) if circumstances require.
And let's not take our eyes off the prize: look what we gained!? We eliminated the miner bribe and reverse respend attacks!
Wouldn't it be nice to simply not need Avalanche or other "preconsensus" approaches, because we fixed the problem elegantly in a way that improved user experience overall?
TL;DR
Let's have a bigger conversation about the potential benefits of a consensus-level fee system!
Indeed I don't like it at all.
The problem is correctly described and your proposal is well articulated, so thank you for this quality post. However, I dont think that a consensus-level transaction fee is a good idea.
In my opinion, fees are the ultimate thing that guarantee censorship resistance of the chain. I really like this text written by Eric Voskuil that explains why.
The reason why miners will always want to include a transaction in a block is the fee it pays. If a transaction is blacklisted by authorities (e.g. because it is indentified as a darknet market transaction), then miners have no incentive to confirm it without a big fee to compensate them for the risk. This type of attack could appear sooner than we think, as some groups of miners start to follow regulators.
If you implement a fee level in the protocol, users will still be able to pay more, as a side fee. ViaBTC already does this for BTC transactions. But this side-fee market weakens users' privacy dramatically.
Besides, this is also why, as others have said here, your proposal does not solve the "Miner Bribe" doublespend.
I don't think such a change is worth it.