diff --git a/website/docs/basics/about-bch.md b/website/docs/basics/about-bch.md index 23434ff1..0d03f39a 100644 --- a/website/docs/basics/about-bch.md +++ b/website/docs/basics/about-bch.md @@ -8,7 +8,7 @@ Bitcoin Cash (ticker BCH) is one of the biggest cryptocurrencies. Bitcoin Cash i Bitcoin Cash shares many of the same fundamentals as Bitcoin (BTC) like the *Proof-of-Work* consensus algorithm and the *UTXO data-model*. However regarding smart contract programmability, Bitcoin Cash has significantly diverged from Bitcoin (BTC). We will go over the main differences between BCH and BTC, and then delve into the smart contract capabilities of Bitcoin Cash! :::info -To learn more about the Bitcoin Basics refer to the book ['Mastering Bitcoin'](https://github.com/bitcoinbook/bitcoinbook). The core of Bitcoin's design is still very much the same in Bitcoin Cash. +To learn more about the Bitcoin Basics refer to the book ['Mastering Bitcoin'](https://github.com/bitcoinbook/bitcoinbook). The core of Bitcoin's design is still very much the same in Bitcoin Cash. To learn more about BCH's transaction lifecycle, see the dedicated guide ['Transaction Lifecycle'](/docs/guides/lifecycle). ::: ## How BCH differs from BTC diff --git a/website/docs/compiler/script-limits.md b/website/docs/compiler/script-limits.md index d4548c95..3f0f747d 100644 --- a/website/docs/compiler/script-limits.md +++ b/website/docs/compiler/script-limits.md @@ -65,7 +65,7 @@ Bitcoin Cash allows multiple OP_RETURN outputs, but the total size of all data o Bitcoin Cash defines a "dust" threshold for output value. Outputs below this threshold are considered dust and will not be relayed by standard nodes. Provably unspendable outputs (OP_RETURN outputs) are exempt from this rule. -The dust threshold is calculated as: +The dust threshold for output value is calculated as: ```ts function calculateDust(outputSize: number): number { @@ -92,6 +92,10 @@ There's 4 types of standard output types: `P2PKH`, `P2SH` (which includes `P2SH2 The `lockingBytecode` standardness rules can be important for smart contract developers, and is why CashScript has helpers like `LockingBytecodeP2PKH`, `LockingBytecodeP2SH32` and `LockingBytecodeNullData`. ::: +### Minimum Relay Fee + +The Bitcoin Cash protocol does not strictly enforce minimum fees for transactions, minimum transaction fees are enforced as a standardness rule on the relay level. The minimum relay fee for BCH transactions is 1sat/byte (1000sats/kb). This is also the standard minimum fee set by most miners on the network. + ## Summary table | Limit type | Constraint | @@ -103,6 +107,7 @@ The `lockingBytecode` standardness rules can be important for smart contract dev | Max transaction size | 100,000 bytes for standardness (1MB for consensus) | | Max OP_RETURN data size | 220 bytes data payload (standardness) | | Dust threshold | based on output size (standardness) - commonly 1,000 sats is used as dust | +| Minimum relay fee | 1sat/byte (standardness) | | Output Standardness | `P2PKH`, `P2SH` (incl. `P2SH20` & `P2SH32`), `P2MS` and `OP_RETURN` data-outputs| For further details on transaction validation and standardness rules, see the [documentation on BCH transaction validation][standardness-docs]. diff --git a/website/docs/guides/adversarial.md b/website/docs/guides/adversarial.md new file mode 100644 index 00000000..607a5694 --- /dev/null +++ b/website/docs/guides/adversarial.md @@ -0,0 +1,134 @@ +--- +title: Adversarial Analysis +sidebar_label: Adversarial Analysis +--- + +In this guide we'll dive into "adversarial analysis" for smart contract systems. Adversarial analysis means to analyze your system from the point of a potential malicious 3rd party which might want to hamper or attack your system. This guide will build further on knowledge from the [the transaction lifecycle guide](/docs/guides/lifecycle). + +## The Happy Case + +As long as all Bitcoin Cash miners follow the first-seen rule then you can count on the idea that competing transaction chains can only occur due to accidental race conditions caused by simultaneous users. In the case of an attempted double spend, full nodes on the BCH network won't relay the transaction, and even if the transaction reaches the mempool of a miner, they would discard the transaction because of the first seen rule. + +:::tip +The "happy case" scenario is currently the standard lifecycle for transactions on the Bitcoin Cash network, also for DeFi transactions interacting with on-chain DEXes. +::: + +## The Adversarial Case + +The adversarial case is where 3rd parties intentionally double spend unconfirmed transactions in the contract system with the goal to extract value or to disrupt the experience for normal users. + +:::caution +In an adversarial environment where double spends occur, user-created transactions interacting with public are not certain to be confirmed. This means waiting for block confirmations is required to be sure the transaction isn't cancelled. +::: + +There is 2 categories to consider for adversarial double spends: + +1) Race-condition double spends (no miner help required) + +2) Late double spends (miner help required) + +### Race-condition Double Spends + +The first scenario of race-condition double spends do not benefit the adversarial 3rd party, instead the goal would just be griefing: to disrupt the flow for normal users. The double spend can cause the user-transaction to be cancelled even though from the user point-of-view it already looked like the transaction went through and achieved its goal. + +:::note +For an adversarial attack to pull off this time-sensitive attack, he would require extensive monitoring on the p2p network and quickly be able to generate and broadcast competing double spend transactions. +::: + +### Late Double Spends + +In the case of an late double spend (which does not try to exploit a race condition) the adversarial actor need help from a miner. +Either the adversarial actor needs to convince the miners to abandon their first seen rule or he needs to be mining himself to be able to construct his own block. + +:::caution +Both race-condition and late double spends can be used to grief the experience for normal users, however only late double spends can be used to extract economic value. +::: + +To convince existing miners to include the double spend transaction instead of the original, the malicious attacker will include a significantly higher mining fee than the original transaction. This can be seen as a 'miner bribe' being paid to discard the first-seen rule and to accept the double spend instead of the original. + +:::note +Attempting a double spend in this way does not incur risk to the adversarial party, either their transaction is not included and they don't pay any fee, or they successfully perform the double spend and they pay the high fee "miner bribe". +::: + +## Economic Value Extraction + +We will now consider what motive the adversarial actor might have to perform these bribes. The two classes of motives are either the profit motive for an economically motivated actor or causing on-chain disruption for a maliciously motivated actor. + +### Stale-state arbitrage + +If DEXes don't cleverly aggregate their prices across blocks, then it can be economical for adversarial actors to instead of building on the latest transaction in the unconfirmed transaction chain of a smart contract, to instead create a competing transaction chain building on an older state. By strategically creating a competing transaction chain they might be able to take advantage of an older price state/ratio which has not yet been confirmed in the blockchain. + +Because having a more advantageous (older) price state or ratio might be very profitable, it is worth it for the adversarial actor to pay the high fee "miner bribe" to attempt this double spend transaction. + +:::tip +We list some possible mitigations which smart contract systems can implement in the section on ['Avoiding MEV'](#avoiding-mev) +::: + + +## Miner-Extractable-Value (MEV) + +Miner-Extractable-Value (MEV) refers to the value (either in dollars or in BCH) which miners can "extract" by having the ability to decide transaction inclusion and the ability to prioritize or insert their own transactions in their new block. + +:::note +On Ethereum the acronym was changed to mean "Maximum-Extractable-Value" because ETH is now a proof-of-stake system and does not have miners. The modified concept still applies to the ETH block proposers (validators). +::: + +### MEV Differences from ETH + +MEV works quite differently on a UTXO-model blockchain than on an account-based chain. So even if you are very familiar with the MEV mechanisms on Ethereum it will still be helpful to consider how they do - or do not - apply to Bitcoin Cash. + +What is not possible to do on UTXO chains is a "sandwich" strategy where a miner would insert a transaction in the middle of a valid transaction chain. In UTXO each transaction explicitly consumes inputs of a previous transaction and creates outputs. Because of this it is not possible to "insert" a transaction in the middle of an unconfirmed chain and thus sandwich strategies are not possible. + +### Controlling Block-Construction + +The reason why block producers are better positioned than other economic actors such as on-chain traders or arbitrageurs is that they can prioritize their own transactions even if conflicting transactions exist in the mempool. + +Other actors who construct double spend transactions will face great difficulty in getting their transaction to propagate and in having to pay high mining fees to bribe miners to accept their double spend over the original transaction. + +## Expected Evolution of MEV + +Below we will extend the adversarial analysis by extrapolating the evolution of MEV on Bitcoin cash based on the example of more mature DeFi ecosystems like Ethereum. As mentioned at the start, the "happy case" scenario is currently the standard lifecycle for transactions on BCH. The analysis below is speculatively extrapolating how this could evolve in a mature DeFi ecosystem. + +### Abandoning First-Seen + +If over time "bribe" double spends start happening on BCH then we can expect over time that some miners will deflect from the convention and use custom transaction selection software to extract MEV from bribe transactions. Over time we can expect miners not just to prefer bribes when available but to actively build transactions to extract from or create value for DeFi protocols. + +:::tip +Adversarial analysis should take into account that "first-seen rule" is just a convention and a way to play nice, however it is not economically maximizing when double spends include miner bribes. +::: + +### Specialized Block-Builders + + +As described in the section on "stale-state arbitrage" economic actors ay be incentivized to strategically create a competing transaction chain which takes advantage of an older price state/ratio which has not yet been confirmed in the blockchain. Although miners are not specialized in the optimal construction of DeFi transactions in a block, miner would over time be likely to team up with teams/companies creating this type of software for them. + +:::note +Ethereum with its large amount of MEV has already seen the emergence of specialized 'block builder' as a new class of relevant economic actors separate from the block proposer (who signs the block). +::: + +## MEV Avoidance Strategies + +There's a few strategies which dapps can employ to avoid introducing unwanted MEV: + +### Batching Same-Block Trades + +For DEXes the solution to the 'stale-state arbitrage' problem is introducing a batching mechanism for same-block trades so they all execute at the same price. The drawback is that this mechanism requires extra contract complexity and careful design. The benefit of including such a MEV avoidance mechanism is that even at scale with many adversarial actors, economic extraction with double spends is not possible. + +:::tip +This strategy of batching same-block trades (or "joint-execution") is the key concept demonstrated by the [Jedex contract prototype](https://github.com/bitjson/jedex#demonstrated-concepts). +::: + +### Centralized Co-signing + +For contract systems relying on a continuously update on-chain oracle price feed, the problem of 'stale-state arbitrage' reappears. +However in this context the only known solution to adversarial actors exploiting stale state with a late double spend is to require centralized co-signing in the contract system. + +The drawback of this approach is that it introduces a central party to enforce honest, sequential actions to prevent late double spends. The approach introduces the need for interactivity and assumes that the central signing service does not collude or cannot be bribed, additionally it also introduces new possible security concerns. + +### Avoid Bounty Transactions + +Having anyone-can-claim bounty transactions in a smart contract system directly encourages the development of double spending technology, whether it is race-condition double spends, miner bribe double spends or miner-involved double spends. + +:::tip +To not incentivize the development of double-spending technologies, it is best to avoid anyone-can-claim bounty transactions in your smart contract system. +::: diff --git a/website/docs/guides/lifecycle.md b/website/docs/guides/lifecycle.md new file mode 100644 index 00000000..aa4cf8c7 --- /dev/null +++ b/website/docs/guides/lifecycle.md @@ -0,0 +1,92 @@ +--- +title: Transaction Lifecycle +sidebar_label: Transaction Lifecycle +--- + +This guide will explain the "transaction lifecycle" of a Bitcoin Cash transaction. We'll talk about what the mempool is and how block inclusion works. Further we'll discuss the possibility of unconfirmed transaction chains and conflicting transactions to cover the full transaction lifecycle! + +## Block Inclusion + +Bitcoin Cash has a block-time of 10 minutes, meaning that on average every 10 minutes a new block is found which adds a collection of transactions to the ledger. On Bitcoin Cash it is standard for transactions to be included in the very next mined block. + +:::tip +Commonly BCH miners are configured to accept transactions paying a minimum of 1 sat/byte, meaning a transaction of 500 bytes has to pay at least 500 satoshis in mining fee. +::: + +Miners choose which transactions to include in their block. Some miners might set a higher minimum fee or mine empty blocks so transactions can remain pending in the mempool even though a new block was mined. Under normal circumstances, a 1 sat/byte fee rate will be included in the next block but this is not guaranteed. + +:::note +Even if a miner sets a higher minimum fee for inclusion in his own blocks, 1 sat/byte is the standard minimum fee for nodes to relay your transaction around the network. This way it will get into the mempool of nodes across the BCH network. +::: + +## Mempool + +Before transactions are included in a block they are waiting for block inclusion in the mempool of the full nodes. Because transactions in the mempool are "seen" but not included in the blockchain yet, the latest state of the blockchain of who owns what is somewhat fuzzy. + +In a normal scenario it's only a matter of time before a BCH transaction in the mempool gets included in a block. Where things get more complex however is if there are **competing unconfirmed transactions**. In this scenario it is **not** necessarily the clear that a transaction is destined to be included in the blockchain. In other words, the latest state of the blockchain is still undecided. + +:::tip +This is why many BCH indexers will allow you to query UTXOs with the option to include or exclude unconfirmed transactions. By default indexers will include unconfirmed UTXOs/unconfirmed transactions in the query result. +::: + +## First-Seen Rule + +The "first-seen rule" is a default mempool inclusion and relay rule for full nodes which says that for any UTXO the first seen spending transaction is the one that gets included in the node's mempool and relayed. The default relay policies on Bitcoin Cash have been designed in such a way to maximally enable "0-conf" transactions meaning transactions with zero confirmations but which can still be considered reasonably secure. + +:::note +On BTC the mempool node default policy got changed to replace-by-fee, and tooling to submit your non-standard transaction directly to mining pools has become commonplace with ordinals. +::: + +The first-seen rule is subjective based on time, because of this different parts of the network might enforce this rule for conflicting transactions in case of a race condition. For P2PKH transactions a trustless notification system was developed called [double-spend-proofs](https://docs.bitcoincashnode.org/doc/dsproof-implementation-notes/) (DSPs). However DSPs unfortunately do not work for smart contract transactions. + +## Unconfirmed Transaction Chains + +Unconfirmed transactions can be chained after one another meaning that even an output of an unconfirmed transaction can already be spent in a new transaction. This means you can have competing unconfirmed transaction **chains** where child transactions are chained to an unconfirmed parent. A competing transaction for any of the chained unconfirmed transactions then presents a cancellation of the whole chain of dependent child transactions. + +There is no maximum to the length of an unconfirmed transaction chain on BCH, software of full nodes has been upgraded to allow for arbitrary length unconfirmed tx chains. This is very important for public covenants which might have many users interacting and transacting with the same smart contract UTXO. + +:::tip +On BCH it's possible to design smart contracts which use long unconfirmed transaction chains, avoiding the need to wait for blockchain confirmations. +::: + +## Competing Transactions + +When there are competing transactions (double spends) being propagated on the network, only one of the conflicting transactions can be included, the other transactions will in effect be cancelled. In the case of an unconfirmed transaction chain, any competing transaction for one of the transactions in this newly formed chain then presents a cancellation of all child transactions dependent on this parent transaction with a conflict. + +:::note +Unlike on Ethereum, on Bitcoin Cash you can never have a transaction which has to pay fees but does not get included in the blockchain. Either it gets included and the fee is paid, or it's like it never happened. +::: + +### Accidental Race-Conditions + +In open contract systems competing transactions can happen organically and by accident, when 2 different users who might be on different sides of the world, interact with your on-chain system at roughly the same time. This situation can be called "UTXO contention" because 2 users simultaneously try to spend the same anyone-can-spend covenant. + +:::tip +To design around UTXO-contention it is smart to always create multiple duplicate UTXOs for public covenants. This way each of the UTXOs represents a distinct "thread" in a multi-threaded system enabling simultaneous interactions. +::: + +### Intentional Double-Spends + +However, it is also possible double-spends are created intentionally. For example in the case of a DEX naively updating its price state, a rational economic actor might be incentivized to ignore the latest unconfirmed transaction chain and to **intentionally** create a competing unconfirmed transaction chain. This way they can interact with the smart contract at an earlier (more advantageous) price. + +:::caution +Smart contract developers developing applications at scale should consider the game-theoretic interaction of advanced, rational economic actors who might benefit from competing against instead of cooperating on building a transaction chain. +::: + +Refer to [the adversarial analysis guide](/docs/guides/adversarial) for a more in-depth guide covering the adversarial cases of intentional double spends and miner bribes. + +## Chain Reorgs + +A "Chain Reorganization" or reorg for short is when the full nodes discard the current chain tip of the blockchain and adopt a new longest chain. Because a chain reorg causes different blocks to be part of the canonical blockchain, it might be that different transactions got included than what was initially expected. + + +:::tip +A great resource to learn more details about reorgs is the ['Chain Reorganization'](https://learnmeabitcoin.com/technical/blockchain/chain-reorganization/) page on the info website learn-me-a-bitcoin. +::: + +:::note +2-block reorganisations are already super rare occurrences, so having 2+ confirmations is often enough for all practical purposes. +Many exchanges however use a 6-block confirmation policy for Bitcoin Cash deposits. +::: + +Chain reorgs don't always include all the same transactions, so some transactions can get un-included from the blockchain with a reorg. In this scenario, if no competing transaction was mined then the un-included transaction will just return to the mempool waiting for inclusion in a next block. diff --git a/website/docs/language/syntax-highlighting.md b/website/docs/language/syntax-highlighting.md index 463eac55..810880b7 100644 --- a/website/docs/language/syntax-highlighting.md +++ b/website/docs/language/syntax-highlighting.md @@ -5,9 +5,17 @@ title: Syntax Highlighting When developing smart contracts for CashScript it is useful to have the proper syntax highlighting in your code editor / IDE. If you use Visual Studio Code, there is a dedicated CashScript extension. For other editors it is recommended to install a Solidity highlighting plugin and associate it with `.cash` files in your editor, since the syntaxes of the two languages are very similar. ## Visual Studio Code (Recommended) -For Visual Studio Code (and derived editors like Cursor) we have an official [CashScript extension](https://marketplace.visualstudio.com/items?itemName=CashScript.cashscript-vscode). This extension works with `.cash` files and supports syntax highlighting, autocompletion, snippets and linting. +For Visual Studio Code (and derived editors like Cursor) we have an official [CashScript extension](https://marketplace.visualstudio.com/items?itemName=CashScript.cashscript-vscode). This extension works with `.cash` files and supports syntax highlighting, autocompletion, snippets and linting. Because of the first-class CashScript support, Visual Studio Code with this CashScript extension is the recommended way to develop CashScript contracts. -Because of the first-class CashScript support, Visual Studio Code with this CashScript extension is the recommended way to develop CashScript contracts. +To have the extension automatically suggested for any developer looking at your CashScript contract in VScode, add the following configuration in a `.vscode/extensions.json` file: + +```json title="~/.vscode/extensions.json" +{ + "recommendations": [ + "cashscript.cashscript-vscode", + ] +} +``` ## Cursor diff --git a/website/sidebars.js b/website/sidebars.js index a0e85883..d1c4b295 100755 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -56,11 +56,13 @@ module.exports = { label: 'Guides', items: [ 'guides/covenants', + 'guides/lifecycle', 'guides/cashtokens', 'guides/infrastructure', 'guides/walletconnect', 'guides/debugging', - 'guides/optimization' + 'guides/optimization', + 'guides/adversarial', ], }, {