diff --git a/docs/how-to-deploy-and-call-a-contract/call-deployed.md b/docs/how-to-deploy-and-call-a-contract/call-deployed.md index 0330cc57d..63017e3b8 100644 --- a/docs/how-to-deploy-and-call-a-contract/call-deployed.md +++ b/docs/how-to-deploy-and-call-a-contract/call-deployed.md @@ -28,7 +28,7 @@ export class Counter extends SmartContract { // Increment counter. this.increment() - // Ensure next output will contain this contracts code w + // Ensure next output will contain this contracts code with // the updated count property. const amount: bigint = this.ctx.utxo.value const outputs: ByteString = this.buildStateOutput(amount) + this.buildChangeOutput() diff --git a/docs/how-to-write-a-contract/how-to-write-a-contract.md b/docs/how-to-write-a-contract/how-to-write-a-contract.md index 0c28cf465..7fcee37eb 100644 --- a/docs/how-to-write-a-contract/how-to-write-a-contract.md +++ b/docs/how-to-write-a-contract/how-to-write-a-contract.md @@ -16,13 +16,13 @@ class Equations extends SmartContract { @prop() diff: bigint - + constructor(sum: bigint, diff: bigint) { super(...arguments) this.sum = sum this.diff = diff } - + @method() public unlock(x: bigint, y: bigint) { assert(x + y == this.sum, 'incorrect sum') @@ -84,7 +84,7 @@ static c: bigint @prop(true) static c: bigint = 1n -// good, `UINT_MAX` is a compile-time constant, and no need to typed explicitly +// good, `UINT_MAX` is a compile-time constant (CTC), and no need to typed explicitly static readonly UINT_MAX = 0xffffffffn // valid, but not good enough, `@prop()` is not necessary for the CTC @@ -162,17 +162,16 @@ A detailed example is shown below. ```ts class PublicMethodDemo extends SmartContract { - @method() public foo() { - // valid, last statement is `assert();` statement - assert(true); + // valid, last statement is `assert()` statement + assert(true); } @method() public foo() { - // valid, `console.log` calling will be ignored when verifying the last `assert` statement - assert(true); // + // valid, `console.log` calls will be ignored when verifying the last `assert()` statement + assert(true); // console.log(); console.log(); } @@ -197,7 +196,7 @@ class PublicMethodDemo extends SmartContract { @method() public foo() { - // invalid, the last statement of public method should be an `assert` function call + // invalid, the last statement of every public method should be an `assert()` statement } @method() @@ -208,7 +207,7 @@ class PublicMethodDemo extends SmartContract { @method() public foo() { - // invalid, the last statement in the for statement body doesn't end with `assert()` statement. + // invalid, the last statement in the `for` statement body doesn't end with `assert()` for (let index = 0; index < 3; index++) { assert(true); z + 3n; @@ -217,17 +216,17 @@ class PublicMethodDemo extends SmartContract { @method() public foo() { - // invalid, not each conditional branch end with `assert()` statement. + // invalid, because each conditional branch does not end with `assert()` if(z > 3n) { assert(true) } else { - + } } @method() public foo() { - // invalid, not each conditional branch end with `assert()` statement. + // invalid, because each conditional branch does not end with `assert()` if(z > 3n) { assert(true) } @@ -593,7 +592,7 @@ for (let $i = 0; $i < $maxLoopCount; $i++) { * the initial value must be `0` or `0n`, the operator `<` (no `<=`), and increment `$i++` (no pre-increment `++$i`). * `$maxLoopCount` must be a [CTC](#compile-time-constant) or a CTC expression, for example: -```ts +```ts const N = 4 // valid, `N` is a CTC @@ -665,7 +664,7 @@ abs(a: bigint): bigint { ## Compile-time Constant -A compile-time constant, CTC for short, is a special variable whose value can be determined at compile time. A CTC must be defined in one of the following ways. +A compile-time constant, or CTC for short, is a special variable whose value can be determined at compile time. A CTC must be defined in one of the following ways: * A number literal like: @@ -696,7 +695,7 @@ class X { ```ts export class MyLib extends SmartContractLib { - + constructor() { super(...arguments) } diff --git a/docs/how-to-write-a-contract/scriptcontext.md b/docs/how-to-write-a-contract/scriptcontext.md index 2e37dccd9..2fa056ece 100644 --- a/docs/how-to-write-a-contract/scriptcontext.md +++ b/docs/how-to-write-a-contract/scriptcontext.md @@ -7,9 +7,12 @@ sidebar_position: 2 In the UTXO model, the context of validating a smart contract is the UTXO containing it and the transaction spending it, including its inputs and outputs. In the following example, when the second of input of transaction `tx1` (2 inputs and 2 outputs) is spending the second output of `tx0` (3 inputs and 3 outputs), the context for the smart contract in the latter output is roughly the UTXO and `tx1` circled in red. ![](../../static/img/scriptContext.jpg) -The context only contains local information, different from account-based blockchains whose context consists of the global state of the entire blockchain (as in Ethereum). A single shared global state across all smart contracts kills scalability, since they all have to be sequentially processed due to potential race conditions. +The context only contains local information. +This is different from account-based blockchains (like Ethereum) where context consists of the global state of the entire blockchain. +A single shared global state across all smart contracts jeopardizes scalability because transactions must be sequentially processed, resulting in potential race conditions. This context is expressed in the `ScriptContext` interface. + ```ts export interface ScriptContext { /** version number of [transaction]{@link https://wiki.bitcoinsv.io/index.php/Bitcoin_Transactions#General_format_of_a_Bitcoin_transaction} */ @@ -86,7 +89,6 @@ class TimeLock extends SmartContract { } ``` - ### Access inputs and outputs The inputs and outputs of the spending transaction are not directly included in `ScriptContext`, but their hashes/digests. To access them, we can build them first and validate the hash to the expected digest, which ensures they are actually from the spending transaction. @@ -129,12 +131,11 @@ Through the `hashPrevouts` field of `ScriptContext`, we can access the hash of P > If the `ANYONECANPAY` flag is not set, `hashPrevouts` is the double SHA256 of the serialization of all input outpoints; > Otherwise, hashPrevouts is a uint256 of `0x0000......0000`. -But we can access the full prevouts via `this.prevouts`. +But we can access the full prevouts via `this.prevouts`. - If the `ANYONECANPAY` flag is not set, the hash of `this.prevouts` is equal to `this.ctx.hashPrevouts`. - Otherwise, `this.prevouts` will be empty. - ### SigHash Type [SigHash type](https://wiki.bitcoinsv.io/index.php/SIGHASH_flags) decides which part of the spending transaction is included in `ScriptContext`. @@ -163,10 +164,22 @@ For more information, please refer to [this detailed guide](../advanced/sighash- ### Serialization -You have the option to convert `this.ctx` into a `SigHashPreimage` object through serialization. This can be achieved by invoking the `this.ctx.serialize()` method. The output object adheres to the format utilized during the signing or verification of transactions. +You have the option to convert `this.ctx` into a `SigHashPreimage` object through serialization. This can be achieved by invoking the `this.ctx.serialize()` method. The output object adheres to the format utilized during the signing or verification of transactions. + +``` +nVersion of the transaction (4-byte little endian) +hashPrevouts (32-byte hash) +hashSequence (32-byte hash) +outpoint (32-byte hash + 4-byte little endian) +scriptCode of the input (serialized as scripts inside CTxOuts) +value of the output spent by this input (8-byte little endian) +nSequence of the input (4-byte little endian) +hashOutputs (32-byte hash) +nLocktime of the transaction (4-byte little endian) +sighash type of the signature (4-byte little endian) +``` -![](../../static/img/sighashpreimage0.png) -[Format: Source](https://github.com/bitcoin-sv/bitcoin-sv/blob/master/doc/abc/replay-protected-sighash.md#digest-algorithm) +[Source](https://github.com/bitcoin-sv/bitcoin-sv/blob/master/doc/abc/replay-protected-sighash.md#digest-algorithm) A noteworthy application of a serialized preimage can be found in the creation of custom SigHash flags. An example is the [SIGHASH_ANYPREVOUT](https://github.com/sCrypt-Inc/boilerplate/blob/master/src/contracts/sighashAnyprevout.ts#L34), which showcases this process. diff --git a/docs/overview.md b/docs/overview.md index 89bea994d..ce3466495 100644 --- a/docs/overview.md +++ b/docs/overview.md @@ -20,8 +20,8 @@ Smart contracts on Bitcoin are based on the UTXO model, which is very different Each bitcoin transaction consists of some inputs and outputs. An output contains: -- The amount of bitcoins it contains. -- bytecodes (called the `locking script`). +- The amount of bitcoins (satoshis) it contains. +- bytecodes (the `locking script`). while an input contains: - A reference to the previous transaction output. @@ -44,7 +44,7 @@ In a regular Bitcoin payment to a [Bitcoin address](https://wiki.bitcoinsv.io/in ## Learn `sCrypt` -Jump over to the [Installation](./installation.md) section to learn how to create an `sCrypt` project. +Jump over to the [Installation](./installation.md) section to learn how to create an `sCrypt` project. :::tip You can also follow this [Youtube series](https://www.youtube.com/playlist?list=PL0Kn1t30VSpGcbwN-bcbU1-x0fRAoq-GI). diff --git a/docs/reference/classes/WhatsonchainProvider.md b/docs/reference/classes/WhatsonchainProvider.md index 0faf5bb8a..fece101d4 100644 --- a/docs/reference/classes/WhatsonchainProvider.md +++ b/docs/reference/classes/WhatsonchainProvider.md @@ -2,8 +2,7 @@ # Class: WhatsonchainProvider -The WhatsonchainProvider is backed by [whatsonchain][https://whatsonchain.com](https://whatsonchain.com), -which is the popular blockchain exxplorer for Bitcoin. +The WhatsonchainProvider is backed by [WhatsOnChain](https://whatsonchain.com), a popular Bitcoin blockchain explorer. ## Hierarchy diff --git a/docs/tokens/tutorials/ordi-oracle.md b/docs/tokens/tutorials/ordi-oracle.md index 6fd1829cf..d5c5b21e0 100644 --- a/docs/tokens/tutorials/ordi-oracle.md +++ b/docs/tokens/tutorials/ordi-oracle.md @@ -5,7 +5,7 @@ sidebar_position: 5 # Tutorial 5: Ordinals Oracle ## Overview -Bitcoin smart contracts can decide whether satoshis in a UTXO are valid, but cannot directly determine whether the [1SatOrdinals](https://docs.1satordinals.com/) tokens in a UTXO are valid. By inspecting a UTXO, a contract can know how many satoshis in it since they are validated by miners on chain. However, the contract cannot be sure how many Ordinals tokens are in it or if it contains a said NFT, since they are validated by an external indexer off chain outside of miners. In many practical applications, verifying the Ordinals tokens carried in certain transaction inputs is necessary, such as token swap and token sale. [Oracles](../../tutorials/oracle.md) must be introduced to provide additional verification for the authenticity and integrity of the Ordinals tokens required when calling a contract. +Bitcoin smart contracts can decide whether satoshis in a UTXO are valid, but cannot directly determine whether the [1SatOrdinals](https://docs.1satordinals.com/) tokens in a UTXO are valid. By inspecting a UTXO, a contract can know how many satoshis are in it since they are validated by miners on chain. However, the contract cannot be sure how many Ordinals tokens are in it or if it contains a specific NFT, since they are validated by an external indexer off chain outside of miners. In many practical applications, verifying the Ordinals tokens carried in certain transaction inputs is necessary, such as token swap and token sale. [Oracles](../../tutorials/oracle.md) must be introduced to provide additional verification for the authenticity and integrity of the Ordinals tokens required when calling a contract. This tutorial will introduce how to use the [WitnessOnChain](https://api.witnessonchain.com) oracle to validate transaction inputs referencing UTXOs containing Ordinals NFTs and BSV20 tokens. @@ -73,7 +73,7 @@ export class OracleDemoBsv20 extends SmartContract { inscriptionId: ByteString @prop() amt: bigint - + ... } ``` @@ -117,4 +117,3 @@ We first retrieve the token outpoint from `this.prevouts`. We parse the message Congratulations! You have successfully completed a tutorial about how to validate 1SatOrdinals inputs with Oracle. The full example [contract](https://github.com/sCrypt-Inc/boilerplate/blob/master/src/contracts/oracleDemoBsv20.ts) and its corresponding [test](https://github.com/sCrypt-Inc/boilerplate/blob/master/tests/oracleDemoBsv20.test.ts) can be found in our [boilerplate repo](https://github.com/sCrypt-Inc/boilerplate). - diff --git a/docs/tutorials/auction.md b/docs/tutorials/auction.md index 692e094cd..85d01bcde 100644 --- a/docs/tutorials/auction.md +++ b/docs/tutorials/auction.md @@ -42,7 +42,7 @@ Initialize all the `@prop` properties in the constructor. Note that we don't nee ```ts constructor(auctioneer: PubKey, auctionDeadline: bigint) { super(...arguments) - // the initial bidder is the auctioneer himeself + // the initial bidder is the auctioneer himself this.bidder = auctioneer this.auctioneer = auctioneer this.auctionDeadline = auctionDeadline diff --git a/static/img/sighashpreimage0.png b/static/img/sighashpreimage0.png deleted file mode 100644 index f5599e383..000000000 Binary files a/static/img/sighashpreimage0.png and /dev/null differ