diff --git a/website/docs/basics/about-bch.md b/website/docs/basics/about-bch.md index 0d03f39a..3ce1a8b8 100644 --- a/website/docs/basics/about-bch.md +++ b/website/docs/basics/about-bch.md @@ -8,14 +8,14 @@ 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 BCH's transaction lifecycle, see the dedicated guide ['Transaction Lifecycle'](/docs/guides/lifecycle). +To learn more about the Bitcoin Basics refer to the book ['Mastering Bitcoin'][Mastering Bitcoin]. 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 Although BCH and BTC share the same Bitcoin fundamentals, both projects have significantly diverged in some areas since 2017. For example, Bitcoin Cash does not have Segwit or Taproot, instead Bitcoin Cash has had multiple upgrades specifically focused on improving the smart contract capabilities. Bitcoin Cash has re-enabled many useful opcodes, has introduce native introspection, has added CashTokens, has reworked the script limits and introduced BigInts. -So part that **has** significantly diverged between BTC and BCH is the *virtual machine* (VM), the environment in which smart contracts are evaluated. So the greatly improved VM specifically is what makes it possible to write powerful smart contracts on BCH in the first place! +So part that **has** significantly diverged between BTC and BCH is the *virtual machine* (VM), the environment in which smart contracts are evaluated. The Bitcoin Cash VM is also referred to as the **CashVM**. The greatly improved VM specifically is what makes it possible to write powerful smart contracts on BCH in the first place! On the overview of [all the BCH network upgrades][BCH upgrades], you'll notice the recent years have been fully focused on VM improvements. ## UTXO model Bitcoin Cash transactions work with in- and outputs. All current balances are so called *Unspent Transaction Outputs (UTXOs)*, which simply means they can be used as inputs for future spending transactions. @@ -39,7 +39,7 @@ Bitcoin Cash has had many script upgrades, including transaction introspection a Smart contracts on Bitcoin Cash only have access to the current transaction context, which enables 'local state'. This model allows transactions to be verified independently and efficiently. Because there is no global state that can impact the execution of these smart contracts, the results are deterministic and predictable. :::tip -The UTXO model where transactions only have access to the local transaction context enables parallel transaction validation and is the reason why Bitcoin Cash is hugely scalable! +The UTXO model where transactions only have access to the local transaction context enables parallel transaction validation and is the reason why Bitcoin Cash is hugely scalable with low fees! ::: ### Bitcoin Cash Script @@ -48,10 +48,13 @@ The locking and unlocking scripts of regular transactions and smart contracts on ### CashScript -CashScript is a high-level programming language for smart contracts on Bitcoin Cash that offers a strong abstraction for a smoother development experience. CashScript fully abstracts the management of items on the 'stack' from developers, allowing them to focus on their application logic instead of low-level details. +CashScript is a high-level programming language for smart contracts on Bitcoin Cash that offers a strong abstraction for a smoother development experience. CashScript fully abstracts the management of items on the 'stack' from contract developers, allowing them to focus on their application logic instead of low-level details. The CashScript syntax is based on Ethereum's smart contract language Solidity, but its functionality is very different since smart contracts on Bitcoin Cash differ greatly from smart contracts on Ethereum. :::info -Bitcoin's "Local State" versus Ethereum's "Global State" requires a very different mental model and way to structure smart contract applications! +Bitcoin Cash's "Local State" versus Ethereum's "Global State" requires a very different mental model and way to structure smart contract applications! ::: + +[Mastering Bitcoin]: https://github.com/bitcoinbook/bitcoinbook +[BCH upgrades]: https://upgradespecs.bitcoincashnode.org/ diff --git a/website/docs/compiler/compiler.md b/website/docs/compiler/compiler.md index b684a68d..4b6db41d 100644 --- a/website/docs/compiler/compiler.md +++ b/website/docs/compiler/compiler.md @@ -5,6 +5,10 @@ title: Compiler The CashScript compiler is called `cashc` and is used to compile CashScript `.cash` contract files into `.json` (or `.ts`) artifact files. These artifact files can be used to instantiate a CashScript contract with the help of the CashScript SDK. For more information on this artifact format refer to [Artifacts](/docs/compiler/artifacts). +:::info +Because of the separation of the compiler and the SDK, CashScript contracts can be integrated into other programming languages in the future. +::: + ## Command Line Interface The `cashc` command line interface is used to compile CashScript `.cash` files into `.json` (or `.ts`) artifact files. diff --git a/website/docs/guides/covenants.md b/website/docs/guides/covenants.md index b2320a94..acbbc122 100644 --- a/website/docs/guides/covenants.md +++ b/website/docs/guides/covenants.md @@ -147,7 +147,7 @@ Covenants can also use 'simulated state', where state is kept in the contract sc To demonstrate the concept of 'local state' we consider the Mecenas contract again, and focus on a drawback of this contract: you have to claim the funds at exactly the right moment or you're leaving money on the table. Every time you claim money from the contract, the `this.age` counter is reset, so the next claim is possible 30 days after the previous claim. So if we wait a few days to claim, **these days are basically wasted**. -Besides these wasted days it can also be inconvenient to claim at set intervals, rather than the "streaming" model that the Ethereum project [Sablier](https://www.sablier.finance/) employs. Instead of set intervals, you should be able to claim funds at any time during the "money stream". Using local state, we can approach a similar system with BCH. +Besides these wasted days it can also be inconvenient to claim at set intervals, rather than the "streaming" model that the Ethereum project [Sablier][Sablier] employs. Instead of set intervals, you should be able to claim funds at any time during the "money stream". Using local state, we can approach a similar system with BCH. ```solidity // Mutable NFT Commitment contract state @@ -328,3 +328,4 @@ We have discussed the main uses for covenants as they exist on Bitcoin Cash toda Keeping local state in NFTs and issuing NFTs as receipts are two strategies which can be used to create much more sophisticated decentralized applications. You can read more of these advanced CashTokens use cases in our [dedicated guide](/docs/guides/cashtokens#cashtokens-use-cases)! [bitcoin-covenants]: https://fc16.ifca.ai/bitcoin/papers/MES16.pdf +[Sablier]: https://www.sablier.finance/ diff --git a/website/docs/guides/lifecycle.md b/website/docs/guides/lifecycle.md index aa4cf8c7..7b7f8a01 100644 --- a/website/docs/guides/lifecycle.md +++ b/website/docs/guides/lifecycle.md @@ -37,7 +37,7 @@ The "first-seen rule" is a default mempool inclusion and relay rule for full nod 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. +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][double-spend-proofs] (DSPs). However DSPs unfortunately do not work for smart contract transactions. ## Unconfirmed Transaction Chains @@ -81,7 +81,7 @@ A "Chain Reorganization" or reorg for short is when the full nodes discard the c :::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. +A great resource to learn more details about reorgs is the ['Chain Reorganization'][chain-reorganization] page on the info website learn-me-a-bitcoin. ::: :::note @@ -90,3 +90,6 @@ Many exchanges however use a 6-block confirmation policy for Bitcoin Cash deposi ::: 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. + +[double-spend-proofs]: https://docs.bitcoincashnode.org/doc/dsproof-implementation-notes/ +[chain-reorganization]: https://learnmeabitcoin.com/technical/blockchain/chain-reorganization/ diff --git a/website/docs/guides/optimization.md b/website/docs/guides/optimization.md index 213b5fab..1bddc811 100644 --- a/website/docs/guides/optimization.md +++ b/website/docs/guides/optimization.md @@ -139,7 +139,13 @@ contract Example(){ In Cashscript, when defining multiple functions, a `selectorIndex` parameter is added under-the-hood to select which of the contract's functions you want to use, this wraps your functions in big `if-else` cases. However when combining multiple functions in one cases you will have to think about the function conditions and `if-else` branching yourself. -## Hand-optimizing Bytecode +## Advanced: Hand-optimizing Bytecode + +You can still use the CashScript TypeScript SDK while using a hand-optimized or hand-written contract, although this is considered advanced functionality. + +There's two ways to go about this, either you create a custom `Artifact` so you can still use the `Contract` class or you create a custom `Unlocker` to use in the transaction building directly. + +### Note on Premature Optimizations It's worth considering whether hand-optimizing the contract is necessary at all. If the contract works and there is no glaring inefficiency in the bytecode, perhaps the best optimization is to not to obsess prematurely about the transaction size with Bitcoin Cash's negligible fees. @@ -147,17 +153,15 @@ It's worth considering whether hand-optimizing the contract is necessary at all. ### Optimizing with the BitauthIDE -When optimizing the bytecode of your contract to ensure it is the smallest possible bytesize you'll likely want to use the [BitauthIDE](https://ide.bitauth.com) so you can see the stack changes for each executed OpCode. Low-level understanding can also give good intuition about the [optimization tips](#optimization-tips) for the CashScript code. +When optimizing the bytecode of your contract to ensure it is the smallest possible bytesize you'll likely want to use the [BitauthIDE][BitauthIDE] so you can see the stack changes for each executed OpCode. Low-level understanding can also give good intuition about the [optimization tips](#optimization-tips) for the CashScript code. -### Overwriting the Artifact +### Method 1) Custom Artifact To manually optimize a CashScript contract's bytecode, you need to overwrite the `bytecode` key of your contract artifact. If you manually overwrite the `bytecode` in the artifact, the auto generated 2-way-mapping generated by the compiler becomes obsolete. You are no longer compiling high-level CashScript code into BCH script, instead you are writing BCH script by hand. This causes the link of the BCH opcodes to your original CashScript code will be entirely lost for debugging. -You can still use the CashScript TypeScript SDK while using a hand-optimized or hand-written contract. - ```typescript interface Artifact { @@ -172,7 +176,33 @@ If you use hand-optimized `bytecode` in your Contract's artifact, the `debug` in ::: :::tip -You can create an `Artifact` for a fully hand-written contract so it becomes possible to use the contract with the nice features of the CashScript SDK! An example of this is [Cauldron_Swap_Test](https://github.com/mr-zwets/Cauldron_Swap_Test) which uses `Artifact bytecode` not produced by `cashc` at all but still uses the CashScript SDK. +You can create an `Artifact` for a fully hand-written contract so it becomes possible to use the contract with the nice features of the CashScript SDK! An example of this is [Cauldron_Swap_Test][Cauldron_Swap_Test] which uses `Artifact bytecode` not produced by `cashc` at all but still uses the CashScript SDK. ::: +### Method 2) Custom Unlockers + +In the [addInput() method][addInput()] on the TransactionBuilder you can provide a custom `Unlocker` + +```ts +transactionBuilder.addInput(utxo: Utxo, unlocker: Unlocker, options?: InputOptions): this +``` + +the `Unlocker` interface is the following: + +```ts +interface Unlocker { + generateLockingBytecode: () => Uint8Array; + generateUnlockingBytecode: (options: GenerateUnlockingBytecodeOptions) => Uint8Array; +} + +interface GenerateUnlockingBytecodeOptions { + transaction: Transaction; + sourceOutputs: LibauthOutput[]; + inputIndex: number; +} +``` + + [BitauthIDE]: https://ide.bitauth.com +[Cauldron_Swap_Test]: https://github.com/mr-zwets/Cauldron_Swap_Test +[addInput()]: /docs/sdk/transaction-builder#addinput diff --git a/website/docs/language/examples.md b/website/docs/language/examples.md index 80c12567..76431b21 100644 --- a/website/docs/language/examples.md +++ b/website/docs/language/examples.md @@ -2,7 +2,7 @@ title: Examples --- -An extensive collection of examples is available in the [GitHub repository](https://github.com/CashScript/cashscript/tree/master/examples). Below we discuss a few of these examples in more details and go through their functionality. This example page focuses on the CashScript syntax, while the [SDK Examples page](/docs/sdk/examples) in the SDK section focuses on use of the SDK to build an application. +An extensive collection of examples is available in the [GitHub repository][GitHub-CashScript-Examples]. Below we discuss a few of these examples in more details and go through their functionality. This example page focuses on the CashScript syntax, while the [SDK Examples page](/docs/sdk/examples) in the SDK section focuses on use of the SDK to build an application. ## HodlVault For better or worse, HODLing and waiting for price increases is one of the main things people want to do with their cryptocurrency. But it can be difficult to hold on to your cryptocurrency when the price is going down. So to prevent weak hands from getting the best of you, it's better to store your stash in a smart contract that enforces HODLing for you. @@ -90,7 +90,7 @@ contract Mecenas(bytes20 recipient, bytes20 funder, int pledge, int period) { ## AMM DEX -AMM DEX contract based on [the Cauldron DEX contract](https://www.cauldron.quest/_files/ugd/ae85be_b1dc04d2b6b94ab5a200e3d8cd197aa3.pdf), you can read more details about the contract design there. +AMM DEX contract based on [the Cauldron DEX contract][Cauldron-Whitepaper], you can read more details about the contract design there. The CashScript contract code has the big advantage of abstracting away any stack management, having variable names, explicit types and a logical order of operations (compared to the 'reverse Polish notation' of raw script). @@ -135,6 +135,9 @@ contract DexContract(bytes20 poolOwnerPkh) { } ``` -Compared to the manually written and hand-optimized opcodes version of the contract, the CashScript compiled bytecode has just 5 extra opcodes overhead (7 extra bytes). Furthermore, even contracts with hand-optimized bytecode can still be used with the CashScript SDK, [find out more in the optimization guide](/docs/guides/optimization#hand-optimizing-bytecode). +Compared to the manually written and hand-optimized opcodes version of the contract, the CashScript compiled bytecode has just 5 extra opcodes overhead (7 extra bytes). Furthermore, even contracts with hand-optimized bytecode can still be used with the CashScript SDK, [find out more in the optimization guide](/docs/guides/optimization#advanced-hand-optimizing-bytecode). More advanced examples on covenants, using NFTs to keep local state and issuing NFTs as receipts can be found in the [Covenants & Introspection Guide](/docs/guides/covenants). + +[GitHub-CashScript-Examples]: https://github.com/CashScript/cashscript/tree/master/examples +[Cauldron-Whitepaper]: https://www.cauldron.quest/_files/ugd/ae85be_b1dc04d2b6b94ab5a200e3d8cd197aa3.pdf diff --git a/website/docs/releases/release-notes.md b/website/docs/releases/release-notes.md index cb35740b..26bd0930 100644 --- a/website/docs/releases/release-notes.md +++ b/website/docs/releases/release-notes.md @@ -24,6 +24,10 @@ title: Release Notes - :hammer_and_wrench: Improve libauth template generation. - :bug: Fix bug where `SignatureTemplate` would not accept private key hex strings as a signer. +--- + +https://x.com/CashScriptBCH/status/1973692336782876974 + ## v0.11.5 #### CashScript SDK diff --git a/website/docs/sdk/electrum-network-provider.md b/website/docs/sdk/electrum-network-provider.md index bf216424..80a52766 100644 --- a/website/docs/sdk/electrum-network-provider.md +++ b/website/docs/sdk/electrum-network-provider.md @@ -2,11 +2,17 @@ title: Electrum Network Provider --- -The CashScript SDK needs to connect to the BCH network to perform certain operations, like retrieving the contract's balance, or sending transactions. By default the network provider is an `ElectrumNetworkProvider`. +The CashScript SDK needs to connect to the BCH network to perform certain operations, like retrieving the contract's balance, or sending transactions. The recommended network provider is the `ElectrumNetworkProvider`. -## ElectrumNetworkProvider +## Creating an ElectrumNetworkProvider -The ElectrumNetworkProvider uses [@electrum-cash/network][electrum-cash] to connect to the BCH network. Both `network` and `options` parameters are optional, and they default to mainnet with the `bch.imaginary.cash` electrum server. +The ElectrumNetworkProvider uses [@electrum-cash/network][electrum-cash] library to connect to the configured electrum server. The connection uses a single, trusted electrum server so it does no have any fallback logic and does not validate SPV proofs for chain inclusion. + +By default the `ElectrumNetworkProvider` creates a short-lived connection only when requests are pending. To configure this see the section on '[Manual Connection Management](#manual-connection-management)'. + +### Constructor + +Both `network` and `options` parameters are optional, and they default to `mainnet` with the `bch.imaginary.cash` electrum server. ```ts new ElectrumNetworkProvider(network?: Network, options?: Options) @@ -44,6 +50,9 @@ const hostname = 'chipnet.bch.ninja'; const provider = new ElectrumNetworkProvider('chipnet', { hostname }); ``` +## ElectrumNetworkProvider Methods + + ### getUtxos() ```ts async provider.getUtxos(address: string): Promise; @@ -143,5 +152,27 @@ provider.disconnect(): Promise; Disconnects from the electrum client, returns `true` if the client was connected, `false` if it was already disconnected. +## Using electrum-cash functionality + +To use more of the electrum-specific functionality which is not exposed in the `ElectrumNetworkProvider` you can simply call the methods on the electrum Client itself. + +### Custom Electrum Client + +When initializing an `ElectrumNetworkProvider` you have the option in the constructor to provide a custom electrum client. This way you can use one and the same indexer server for blockchain information but use it through two different interfaces. This allows you to access all underlying functionality of the [@electrum-cash/network][electrum-cash] library like address and blockHeight subscriptions. + +If intending to use electrum-cash subscriptions, make sure to set `manualConnectionManagement` to true, so the `ElectrumNetworkProvider` does not disconnect after each request. + +#### example + +```ts +import { ElectrumClient } from '@electrum-cash/network'; +import { ElectrumNetworkProvider } from 'cashscript'; + +const electrum = new ElectrumClient('CashScript Application', '1.4.1', 'chipnet.bch.ninja'); +const provider = new ElectrumNetworkProvider(Network.CHIPNET, { + electrum, manualConnectionManagement: true +}); +await electrum.connect(); +``` [electrum-cash]: https://www.npmjs.com/package/@electrum-cash/network diff --git a/website/docs/sdk/instantiation.md b/website/docs/sdk/instantiation.md index 275b66f7..9adcc3dc 100644 --- a/website/docs/sdk/instantiation.md +++ b/website/docs/sdk/instantiation.md @@ -4,11 +4,6 @@ title: Contract Instantiation Before interacting with a smart contract on the BCH network, the CashScript SDK needs to instantiate a `Contract` object. This is done by providing the contract's information and constructor arguments. After this instantiation, the CashScript SDK can interact with the BCH contract. -:::info -CashScript offers a TypeScript SDK, which can also be used easily in vanilla JavaScript codebases. -Because of the separation of the compiler and the SDK, CashScript contracts can be integrated into other languages in the future. -::: - ## Creating a Contract The `Contract` class is used to represent a CashScript contract in a JavaScript object. These objects can be used to retrieve information such as the contract's address and balance. Contract objects can be used to interact with the contract by generating an `Unlocker` by calling the contract's unlocker functions. @@ -17,16 +12,20 @@ The `Contract` class is used to represent a CashScript contract in a JavaScript new Contract( artifact: Artifact, constructorArgs: ConstructorArgument[], - options? : { + options : { provider: NetworkProvider, - addressType: 'p2sh20' | 'p2sh32', + addressType?: 'p2sh20' | 'p2sh32', } ) ``` A CashScript contract can be instantiated by providing an `Artifact` object, a list of constructor arguments, and optionally an options object configuring `NetworkProvider` and `addressType`. -An `Artifact` object is the result of compiling a CashScript contract. Compilation can be done using the standalone [`cashc` CLI](/docs/compiler) or programmatically with the `cashc` NPM package (see [CashScript Compiler](/docs/compiler#javascript-compilation)). If compilation is done using the `cashc` CLI with the `--format ts` option, you will get explicit types and type checking for the constructor arguments and function arguments. +An `Artifact` object is the result of compiling a CashScript contract. Compilation can be done using the standalone [`cashc` CLI](/docs/compiler) or programmatically with the `cashc` NPM package (see [CashScript Compiler](/docs/compiler#javascript-compilation)). + +:::tip +If compilation is done using the `cashc` CLI with the `--format ts` option to output TypeScript Artifacts, you will get explicit types and type checking for the constructor arguments and function arguments of the `Contract` class. +::: The `NetworkProvider` option is used to manage network operations for the CashScript contract. By default, a mainnet `ElectrumNetworkProvider` is used, but the network providers can be configured. See the docs on [NetworkProvider](/docs/sdk/network-provider). @@ -170,6 +169,10 @@ contract.unlock.(...args: FunctionArgument[]): Unlocker Once a smart contract has been instantiated, you can invoke a contract function on a smart contract UTXO to use the '[Transaction Builder](/docs/sdk/transaction-builder)' by calling the function name under the `unlock` member field of a contract object. To call these functions successfully, the provided parameters must match the function signature defined in the CashScript code. +:::tip +When using a TypeScript contract Artifact, you will get explicit types and type checking for the function name and arguments. +::: + These contract functions return an incomplete `transactionBuilder` object, which needs to be completed by providing outputs of the transaction. For more information see the [transaction-builder](/docs/sdk/transaction-builder) page. ```ts @@ -180,6 +183,3 @@ const contractUtxos = await contract.getUtxos(); transactionBuilder.addInput(contractUtxos[0], contract.unlock.spend()); ``` -:::tip -If the contract artifact is generated using the `cashc` CLI with the `--format ts` option, you will get explicit types and type checking for the function name and arguments. -::: diff --git a/website/docs/sdk/network-provider.md b/website/docs/sdk/network-provider.md index 72e32029..4110ef7b 100644 --- a/website/docs/sdk/network-provider.md +++ b/website/docs/sdk/network-provider.md @@ -2,7 +2,7 @@ title: Network Provider --- -The CashScript SDK needs to connect to the BCH network to perform certain operations, like retrieving the contract's balance, or sending transactions. By default the network provider is an `ElectrumNetworkProvider`, however for local development it is recommended to use a `MockNetworkProvider`. +The CashScript SDK needs to connect to the BCH network to perform certain operations, like retrieving the contract's balance, or sending transactions. The recommended network provider to use blockchain network functionality is the `ElectrumNetworkProvider`, however for local development it is recommended to use a `MockNetworkProvider`. :::tip CashScript NetworkProviders have a standardized interface, this allows different network providers to be used by the SDK and makes it easy to swap out dependencies. @@ -90,3 +90,13 @@ const txId = await provider.sendRawTransaction(txHex) A big strength of the NetworkProvider setup is that it allows you to implement custom providers. So if you want to use a new or different BCH indexer for network information, it is simple to add support for it by creating your own `NetworkProvider` adapter by implementing the [NetworkProvider interface](https://github.com/CashScript/cashscript/blob/master/packages/cashscript/src/network/NetworkProvider.ts). You can create a PR to add your custom `NetworkProvider` to the CashScript codebase to share this functionality with others. It is required to have basic automated tests for any new `NetworkProvider`. + +## Provider-Specific functionality + +Beyond the standardized `NetworkProvider` interface each provider can have its own provider-specific functionality. This can either be done by extending the `NetworkProvider` interface or by providing a more full-featured networking client to create the `NetworkProvider`. + +## Limitations + +If you look at the [Transaction Lifecycle](guides/lifecycle.md) guide then you'll see there are blockchain edge cases like chain re-organisations or double spends. Ideally the `NetworkProvider` interface would be able to provide more detailed `Utxo` chain information like whether the UTXO is unconfirmed or confirmed, the number of confirmations and the block-hash of the block which included the transaction creating the UTXO. + +Currently however the `NetworkProvider` interface does not include the details needed to understand whether blockchain state is confirmed, pending or ended up getting reversed. This means that in the case something does end up being reversed your application might not correctly be in sync with the actual network state. diff --git a/website/docs/sdk/other-network-providers.md b/website/docs/sdk/other-network-providers.md index 85429d98..a853a6bd 100644 --- a/website/docs/sdk/other-network-providers.md +++ b/website/docs/sdk/other-network-providers.md @@ -6,7 +6,7 @@ The CashScript SDK needs to connect to the BCH network to perform certain operat ## MockNetworkProvider ```ts -new MockNetworkProvider(options?: { updateUtxoSet: boolean }) +new MockNetworkProvider(options?: MockNetworkProviderOptions) ``` The `MockNetworkProvider` is a special network provider that allows you to evaluate transactions locally without interacting with the Bitcoin Cash network. This is useful when writing automated tests for your contracts, or when debugging your contract locally. @@ -14,8 +14,17 @@ The `MockNetworkProvider` is a special network provider that allows you to evalu The `MockNetworkProvider` has extra methods to enable this local emulation such as `.addUtxo()` and `.setBlockHeight()`. You can read more about the `MockNetworkProvider` and automated tests on the [testing setup](/docs/sdk/testing-setup) page. +```ts +interface MockNetworkProviderOptions { + updateUtxoSet?: boolean; + vmTarget?: VmTarget; +} +``` + The `updateUtxoSet` option is used to determine whether the UTXO set should be updated after a transaction is sent. If `updateUtxoSet` is `true` (default), the UTXO set will be updated to reflect the new state of the mock network. If `updateUtxoSet` is `false`, the UTXO set will not be updated. +The `vmTarget` option defaults to the current VM of `BCH_2025_05`, but this can be changed to test your contract against different BCH virtual machine targets. + #### Example ```ts const provider = new MockNetworkProvider(); @@ -63,7 +72,7 @@ new BitcoinRpcNetworkProvider(network: Network, url: string, options?: any) The `BitcoinRpcNetworkProvider` uses a direct connection to a BCH node. Note that a regular node does not have indexing, so any address of interest (e.g. the contract address) need to be registered by the node *before* sending any funds to those addresses. Because of this it is recommended to use a different network provider unless you have a specific reason to use the RPC provider. :::caution -The `BitcoinRpcNetworkProvider` does not currently support CashTokens. If you want to use CashTokens, please use the `ElectrumNetworkProvider` instead. +The `BitcoinRpcNetworkProvider` does not currently support CashTokens. If you want to use CashTokens, use the `ElectrumNetworkProvider` instead. ::: #### Example diff --git a/website/docs/sdk/transaction-builder.md b/website/docs/sdk/transaction-builder.md index 4e0d88e3..3ac07fb4 100644 --- a/website/docs/sdk/transaction-builder.md +++ b/website/docs/sdk/transaction-builder.md @@ -20,6 +20,7 @@ interface TransactionBuilderOptions { provider: NetworkProvider; maximumFeeSatoshis?: bigint; maximumFeeSatsPerByte?: number; + allowImplicitFungibleTokenBurn?: boolean; } ``` diff --git a/website/docs/sdk/transactions.md b/website/docs/sdk/transactions.md index 5b2ca52d..3d52400f 100644 --- a/website/docs/sdk/transactions.md +++ b/website/docs/sdk/transactions.md @@ -265,7 +265,7 @@ It is unsafe to debug transactions on mainnet using the BitAuth IDE as private k transaction.getVmResourceUsage(verbose: boolean = false): Array ``` -The `getVmResourceUsage()` function allows you to get the VM resource usage for the transaction. This can be useful for debugging and optimization. +The `getVmResourceUsage()` function allows you to get the VM resource usage for the transaction. This can be useful for debugging and optimization. The VM resource usage is calculated for each input individually so the result is an array of `VmResourceUsage` results corresponding to each of the transaction inputs. ```ts interface VmResourceUsage { @@ -281,7 +281,7 @@ interface VmResourceUsage { } ``` -The verbose mode logs the VM resource usage for each input to the console. +The verbose mode also logs the VM resource usage for each input as a table to the console. ``` VM Resource usage by inputs: diff --git a/website/docs/sdk/typescript-sdk.md b/website/docs/sdk/typescript-sdk.md new file mode 100644 index 00000000..873db08d --- /dev/null +++ b/website/docs/sdk/typescript-sdk.md @@ -0,0 +1,67 @@ +--- +title: TypeScript SDK +--- + +CashScript offers a TypeScript SDK, which makes it easy to build smart contract transactions, both in browser or on the server. +The CashScript SDK enables advanced debugging tooling for CashScript contracts, standardized network providers to get BCH blockchain information and a simple API for transaction building when using smart contracts. + +The TypeScript SDK has [full TypeScript integration](#full-typescript-integration) with the CashScript smart contract language. +The full type-safety enables clear APIs which communicates info about the expected argument to each function and method. +This in turn speeds up development time and allows for higher code quality with better safety guarantees. + +:::info +The SDK can also be used easily in vanilla JavaScript codebases, although the benefits of the type-safety will be lost. +::: + +## When to use the SDK + +The CashScript TypeScript SDK is designed to make it as easy as possible to create smart contract transactions for contracts written in CashScript (the smart contract language). So we highly recommend using the SDK when using CashScript to write your smart contracts. + +If you are not using the CashScript contract language, you can still use the CashScript SDK for transaction building and BCH networking functionality! This can be especially useful if you are familiar with the CashScript classes and want manual control over the input and outputs in a transaction. The SDK makes it easy to spend from P2PKH inputs and send to different types of outputs, including OP_RETURN data outputs. + +It's also possible the use the CashScript SDK for hand-optimized contract **not** written with the CashScript contract language, but this is considered [advanced usage](#advanced-non-cashscript-contracts). + +## The 4 SDK Classes + +The CashScript SDK consists of 4 classes, together they form one cohesive structure to build BCH smart contract applications. +The documentation also follows the structure of these 4 classes: + +- the `Contract` class +- the `TransactionBuilder` class +- the `NetworkProvider` class +- the `SignatureTemplate` class + +## SDK usage + +The usage of the 4 classes in your code is as follows: before using the SDK you create one or multiple contract artifacts compiled by `cashc`. Then to start using the SDK, you instantiate a `NetworkProvider`, which you then provide to instantiate a `Contract` from an `Artifact`. Once you have a `Contract` instance, you can use it in the `TransactionBuilder`. During transaction building you might need to generate a signature, in which case you would instantiate a `SignatureTemplate`. + +For an more complete example of the SDK flow, refer to the [SDK Example](./examples.md). + +#### example + +```ts +import { Contract, ElectrumNetworkProvider, TransactionBuilder, SignatureTemplate } from 'cashscript'; +import { P2pkhArtifact } from './artifact'; +import { contractArguments, aliceWif } from './somewhere'; + +const provider = new ElectrumNetworkProvider('chipnet'); + +const contract = new Contract(P2pkhArtifact, contractArguments, { provider }); + +const aliceSignatureTemplate = new SignatureTemplate(aliceWif); +const unlocker = contract.unlock.transfer(aliceSignatureTemplate) + +const transactionBuilder = new TransactionBuilder({ provider }); + +// then use the transactionBuilder to actually spend a UTXO with the contract unlocker +``` + +## Full TypeScript Integration + +The constructor of the `Contract` class takes in an `Artifact`, this is the output of the `cashc` compiler and can be configured to either output a JSON or TS file. To have the best TypeScript integration, we recommend generating the artifact in the `.ts` format and importing it into your TypeScript project from that `.ts` file. The type benefits are explained in more details in the documentation for the [Contract](./instantiation#constructor) class. + +## Advanced: non-CashScript Contracts + +You can also use the CashScript SDK without relying on the CashScript contract language and compiler. This way you can still leverage the a lot of the tooling while having full control over the raw BCH script so this can be hand-written or hand-optimized. + +There's two ways to go about this, either you create a custom `Artifact` so you can still use the `Contract` class or you create a custom `Unlocker` to use in the transaction building directly. These two methods for using hand optimized contract bytecode are discussed in the [optimization guide](/docs/guides/optimization#advanced-hand-optimizing-bytecode). diff --git a/website/sidebars.ts b/website/sidebars.ts index a5af5c50..1ffdd947 100644 --- a/website/sidebars.ts +++ b/website/sidebars.ts @@ -37,6 +37,7 @@ const sidebars: SidebarsConfig = { type: 'category', label: 'TypeScript SDK', items: [ + 'sdk/typescript-sdk', 'sdk/instantiation', 'sdk/transaction-builder', {