@bsv/sdk 1.1.1 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/src/transaction/MerklePath.js +2 -1
- package/dist/cjs/src/transaction/MerklePath.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/transaction/MerklePath.js +2 -1
- package/dist/esm/src/transaction/MerklePath.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/transaction/MerklePath.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/transaction/MerklePath.ts +2 -1
- package/src/transaction/__tests/Transaction.test.ts +2 -2
- package/docs/concepts/42.md +0 -35
- package/docs/concepts/BEEF.md +0 -38
- package/docs/concepts/CHAIN_SPV.md +0 -38
- package/docs/concepts/FEE.md +0 -35
- package/docs/concepts/HASHES.md +0 -19
- package/docs/concepts/HOW_TX.md +0 -60
- package/docs/concepts/OP.md +0 -38
- package/docs/concepts/README.md +0 -14
- package/docs/concepts/TEMPLATES.md +0 -42
- package/docs/concepts/TX_SIG.md +0 -34
- package/docs/concepts/TX_VALID.md +0 -35
- package/docs/examples/EXAMPLE_BUILDING_CUSTOM_TX_BROADCASTER.md +0 -91
- package/docs/examples/EXAMPLE_COMPLEX_TX.md +0 -162
- package/docs/examples/EXAMPLE_ECIES.md +0 -37
- package/docs/examples/EXAMPLE_ENCRYPT_DECRYPT_MESSAGE.md +0 -52
- package/docs/examples/EXAMPLE_FEE_MODELING.md +0 -199
- package/docs/examples/EXAMPLE_HD_WALLETS.md +0 -71
- package/docs/examples/EXAMPLE_MESSAGE_SIGNING.md +0 -63
- package/docs/examples/EXAMPLE_SCRIPT_TEMPLATES.md +0 -170
- package/docs/examples/EXAMPLE_SIMPLE_TX.md +0 -145
- package/docs/examples/EXAMPLE_TYPE_42.md +0 -108
- package/docs/examples/EXAMPLE_UTXOS_TX.md +0 -85
- package/docs/examples/EXAMPLE_VERIFYING_BEEF.md +0 -62
- package/docs/examples/EXAMPLE_VERIFYING_ROOTS.md +0 -97
- package/docs/examples/EXAMPLE_VERIFYING_SPENDS.md +0 -69
- package/docs/examples/GETTING_STARTED_NODE_CJS.md +0 -71
- package/docs/examples/GETTING_STARTED_REACT.md +0 -119
- package/docs/examples/README.md +0 -19
- package/docs/low-level/AES_SYMMETRIC_ENCRYPTION.md +0 -40
- package/docs/low-level/ECDH.md +0 -64
- package/docs/low-level/NUMBERS_POINTS.md +0 -116
- package/docs/low-level/README.md +0 -13
- package/docs/low-level/TX_SIG.md +0 -132
- package/docs/low-level/TYPE_42.md +0 -53
- package/docs/low-level/USING_ECDSA.md +0 -30
- package/docs/low-level/USING_HASHES_AND_HMACS.md +0 -79
- package/docs/low-level/USING_PRIVATE_PUBLIC_KEYS.md +0 -70
- package/docs/low-level/USING_SCRIPTS.md +0 -71
- package/docs/low-level/images/symmetric_encryption_diagram.png +0 -0
package/docs/concepts/HOW_TX.md
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
# How are Transactions Built with Inputs and Outputs?
|
|
2
|
-
|
|
3
|
-
Transactions are one of the fundamental entities within the blockchain, acting as the mechanism through which value is transferred across the network. Understanding how transactions are built using inputs and outputs is crucial for developers, as this process encompasses the core of creating, signing, and sending transactions within applications.
|
|
4
|
-
|
|
5
|
-
## Understanding Transactions
|
|
6
|
-
|
|
7
|
-
A **transaction** in BSV is a record that transfers some outputs containing Bitcoins from one state to the next. However, unlike traditional banking systems, these transactions aren't direct debits or credits to an account. Instead, they reference outputs created by previous transactions as thrir inputs and create new outputs as future spendable coins.
|
|
8
|
-
|
|
9
|
-
### Transaction Structure
|
|
10
|
-
|
|
11
|
-
Each transaction consists of the following components:
|
|
12
|
-
|
|
13
|
-
- **Version**: Indicates the ruleset under which the transaction is validated or which overlay it belongs to.
|
|
14
|
-
- **Inputs**: List of references to outputs from previous transactions, showing where the bitcoins being sent were previously stored.
|
|
15
|
-
- **Outputs**: List of allocations of bitcoins, specifying the amount and conditions under which they can be spent in the future.
|
|
16
|
-
- **Lock Time**: An optional setting that specifies the earliest time or block number at which the transaction can be valid.
|
|
17
|
-
|
|
18
|
-
Transactions can also be attached to a **Merkle proof** to provide proof of inclusion in a particular block, after they have been processed.
|
|
19
|
-
|
|
20
|
-
## Inputs and Outputs
|
|
21
|
-
|
|
22
|
-
Inputs and outputs are the essential elements that make up a transaction. Understanding their structure and usage is key to mastering transaction creation and manipulation using the BSV SDK.
|
|
23
|
-
|
|
24
|
-
### Transaction Inputs
|
|
25
|
-
|
|
26
|
-
A **Transaction Input** includes the following fields:
|
|
27
|
-
|
|
28
|
-
- **Source Transaction ID**: The transaction ID (TXID) from which the input bitcoins are derived.
|
|
29
|
-
- **Source Output Index**: Specifies which output from the referenced transaction is to be spent.
|
|
30
|
-
- **Unlocking Script**: Contains signatures or other unlocking solutions that allows referenced previous output to be spent.
|
|
31
|
-
- **Sequence**: A number that can be used to allow transaction inputs to be updated before finalization, if it's less than 0xFFFFFFFF.
|
|
32
|
-
|
|
33
|
-
Inputs connect a new transaction back to the point in the blockchain where the bitcoins were previously recorded as outputs.
|
|
34
|
-
|
|
35
|
-
### Transaction Outputs
|
|
36
|
-
|
|
37
|
-
A **Transaction Output** consists of:
|
|
38
|
-
|
|
39
|
-
- **Satoshis**: The amount of BSV being transferred.
|
|
40
|
-
- **Locking Script**: Defines the conditions under which the output can be spent, such as requiring a digital signature from the recipient's public key.
|
|
41
|
-
|
|
42
|
-
Outputs transfer the ownership of satoshi commodity tokens or colloquially, coins, so their new owner can use them as inputs in future transactions.
|
|
43
|
-
|
|
44
|
-
## Constructing a Transaction
|
|
45
|
-
|
|
46
|
-
Creating a transaction involves several clear steps, utilizing inputs and outputs to dictate where bitcoins are moving from and to:
|
|
47
|
-
|
|
48
|
-
1. **Define Outputs**: Decide the amount of BSV to transfer and the conditions under which the transfer can later be spent.
|
|
49
|
-
2. **Select Inputs**: Identify previous transaction outputs to spend that have enough balance to cover the outputs and the transaction fee.
|
|
50
|
-
3. **Calculate Fees**: Estimate the necessary transaction fee based on transaction size, where you will be broadcasting, and the level of service priority you require.
|
|
51
|
-
4. **Generate Change**: If inputs exceed the sum of outputs and fees, create change output(s) sending the excess back to the sender without re-using keys.
|
|
52
|
-
5. **Unlock Inputs**: Utilize the private keys or other mechanisms associated with the inputs you're spending to unlock each one, thereby authorizing the bitcoins to be spent.
|
|
53
|
-
6. **Complete Unlocking**: In cases of multi-party transactions, pass the transaction around to all needed parties for unlocking.
|
|
54
|
-
7. **Broadcast**: Send the final signed transaction to the BSV network for inclusion in a block, and register it with overlay networks as required.
|
|
55
|
-
|
|
56
|
-
Each of these steps is facilitated by the BSV SDK, which provides comprehensive tools and templates to handle the complexities of transaction creation, from generating cryptographic signatures to managing network broadcast clients.
|
|
57
|
-
|
|
58
|
-
## Conclusion
|
|
59
|
-
|
|
60
|
-
The BSV SDK empowers developers to build robust applications on the network by abstracting the complexities of transaction creation. By understanding how transactions are structured and built through inputs and outputs, developers can leverage the full potential of the BSV blockchain, ensuring secure, efficient, and scalable applications. You can check out an example of creating transactions [in this tutorial!](../examples/EXAMPLE_COMPLEX_TX.md)
|
package/docs/concepts/OP.md
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
# Opcodes and Their Functionality Within Bitcoin Script
|
|
2
|
-
|
|
3
|
-
## Introduction
|
|
4
|
-
BSV is underpinned by a powerful scripting language that plays a crucial role in securing transactions. This language, which defines the conditions under which coins can be spent, relies heavily on "opcodes" — operational codes that manipulate and evaluate data. This document aims to demystify the functionality of these opcodes, providing examples of their use.
|
|
5
|
-
|
|
6
|
-
## Securing Coins with Script Predicates
|
|
7
|
-
Scripts secure coins through predicates. A predicate is essentially a condition that must be met for coins to be spent. In Bitcoin, these conditions are defined using a scripting language that determines how and when the coins can be transferred. The scripts ensure that only the rightful owner of the coins can spend them by satisfying the conditions laid down in the script attached to each coin or output.
|
|
8
|
-
|
|
9
|
-
## Script Execution Environment: Stacks and Scripts
|
|
10
|
-
Bitcoin's scripting system operates in a stack-based execution environment. This means that the script processes data using two primary structures:
|
|
11
|
-
- **Main stack:** Where most operations are performed.
|
|
12
|
-
- **Alt stack:** Used occasionally to provide additional stack flexibility.
|
|
13
|
-
|
|
14
|
-
Scripts in Bitcoin are divided into two parts:
|
|
15
|
-
1. **Unlocking script:** Provided by the spender of the coins, this script supplies the data needed to satisfy the conditions of the locking script.
|
|
16
|
-
2. **Locking script:** Placed by the recipient in a transaction output, this script sets the conditions under which the coins can be spent.
|
|
17
|
-
|
|
18
|
-
The execution begins with the unlocking script, which places data on the stack. Following this, the locking script is appended and continues to operate on the same stack. The spend is considered valid if, at the end of execution, the top of the stack holds a "true" value (non-zero).
|
|
19
|
-
|
|
20
|
-
## Understanding Opcodes
|
|
21
|
-
Opcodes are the operational codes used within a script to perform specific functions on the data in the stacks. Each opcode manipulates stack data to perform operations such as addition, subtraction, logical comparisons, cryptographic hashes, signature checks, and more. After executing an opcode, the results are pushed back onto the stack, altering its state for subsequent operations.
|
|
22
|
-
|
|
23
|
-
### Examples of Common Opcodes
|
|
24
|
-
- **OP_ADD:** Pops the top two items off the stack, adds them, and pushes the result back onto the stack.
|
|
25
|
-
- **OP_EQUAL:** Pops the top two items, compares them, and pushes `1` (true) if they are equal, or `0` (false) otherwise.
|
|
26
|
-
- **OP_HASH256:** Pops the top item, computes its double SHA-256 hash, and pushes the result back onto the stack.
|
|
27
|
-
- **OP_CHECKSIG:** Pops a public key and a signature from the stack and checks if the signature is valid for the given public key and wider transaction; pushes `1` if the signature is valid.
|
|
28
|
-
|
|
29
|
-
These opcodes are foundational for enabling complex scripting capabilities in BSV, allowing for the creation of various types of transactions including multi-signature wallets, escrow arrangements, sCrypt smart contracts, and much more.
|
|
30
|
-
|
|
31
|
-
## Combining Opcodes to Secure Coins
|
|
32
|
-
The true power of scripting comes from the combination of opcodes to form complex predicates. These predicates secure the coins by requiring that certain conditions be met before the coins can be spent. For example, a script might require that a transaction be signed by multiple parties (multi-signature), or that a certain amount of time elapse before the coins can be spent (timelocks).
|
|
33
|
-
|
|
34
|
-
### Implementing Cryptographic Primitives
|
|
35
|
-
Opcodes also implement various cryptographic primitives such as digital signatures and hashing. These primitives are essential for maintaining the security and integrity of transactions on the blockchain. For instance, the `OP_CHECKSIG` opcode is crucial for verifying that a transaction is authorized by the holder of the private keys associated with the coins being spent.
|
|
36
|
-
|
|
37
|
-
## Conclusion
|
|
38
|
-
By understanding the functionality of opcodes within the Bitcoin scripting language, users and developers can appreciate the flexibility and security that Bitcoin scripts provide. You can check out [this example](../examples/EXAMPLE_VERIFYING_SPENDS.md) of how to validate spends within the BSV SDK.
|
package/docs/concepts/README.md
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# Conceptual Topics
|
|
2
|
-
|
|
3
|
-
These documents cover high-level conceptual information that will augment developers' understanding of the code-level SDK documentation:
|
|
4
|
-
|
|
5
|
-
- [What is BEEF and why is it useful?](BEEF.md)
|
|
6
|
-
- [What is a Transaction Signature?](TX_SIG.md)
|
|
7
|
-
- [What is Type-42 and How Does it Enable Private Signatures?](./42.md)
|
|
8
|
-
- [What are Script Templates Used for?](TEMPLATES.md)
|
|
9
|
-
- [How are Transactions Built with Inputs and Outputs?](HOW_TX.md)
|
|
10
|
-
- [The Role of Chain Trackers within the SPV Ecosystem](CHAIN_SPV.md)
|
|
11
|
-
- [How Does Transaction Fee Modeling Work?](FEE.md)
|
|
12
|
-
- [How are Bitcoin Transactions Validated?](TX_VALID.md)
|
|
13
|
-
- [Opcodes and Their Functionality Within Bitcoin Script](OP.md)
|
|
14
|
-
- [What are Hashes and Why are they Important in Bitcoin?](HASHES.md)
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# What are Script Templates Used for?
|
|
2
|
-
|
|
3
|
-
Script templates play a critical role in facilitating the creation and management of scripts that control the locking and unlocking of UTXOs (transaction outputs or tokens in BSV). These scripts are integral to implementing the various transaction protocols on the blockchain, adhering to Bitcoin's original vision while enhancing security, scalability, and efficiency.
|
|
4
|
-
|
|
5
|
-
## The Role of Scripts in BSV
|
|
6
|
-
|
|
7
|
-
Scripts are pieces of code that define the conditions under which funds can be spent on the blockchain. Every transaction on the BSV network includes two kinds of scripts:
|
|
8
|
-
- **Locking Scripts**: These scripts set conditions under which coins can be spent. They are included in the output of a transaction.
|
|
9
|
-
- **Unlocking Scripts**: These scripts satisfy the conditions set by the locking scripts to spend the funds in a subsequent transaction. They are found in the input of a transaction.
|
|
10
|
-
|
|
11
|
-
The purpose of these scripts is to ensure that only authorized parties can access and transact the funds by meeting predefined conditions, which may include providing a digital signature or solving a computational challenge. Any conceivable set of constraints can be programmed into a locking script.
|
|
12
|
-
|
|
13
|
-
## Concept of Script Templates
|
|
14
|
-
|
|
15
|
-
A script template is a predefined framework that simplifies the process of creating otherwise-potentially-complex locking and unlocking scripts. It abstracts away the underlying script construction details, allowing developers to create scripts without having to write low-level code for every new scenario. The template provides methods and properties to generate scripts dynamically based on the transaction context and the specific input parameters provided.
|
|
16
|
-
|
|
17
|
-
### Components of a Script Template
|
|
18
|
-
A script template generally includes the following:
|
|
19
|
-
|
|
20
|
-
1. **Lock Method**: This method generates a locking script based on given parameters, such as a public key hash or other conditions defined by the transaction type (e.g., P2PKH—Pay to Public Key Hash).
|
|
21
|
-
|
|
22
|
-
2. **Unlock Method**: This method creates an unlocking script, which usually involves generating a digital signature and potentially other data required to unlock the funds according to the locking script's conditions.
|
|
23
|
-
|
|
24
|
-
3. **Estimate Length**: This utility provides an estimation of the unlocking script's length, which can be crucial for transaction fee calculation.
|
|
25
|
-
|
|
26
|
-
## Importance of Script Templates
|
|
27
|
-
|
|
28
|
-
### Simplification and Standardization
|
|
29
|
-
Script templates standardize the creation of scripts, ensuring consistency and reducing errors in script generation. They provide a high-level interface for commonly used script patterns, like P2PKH, reducing the need for repetitive, error-prone coding.
|
|
30
|
-
|
|
31
|
-
### Security Enhancements
|
|
32
|
-
By abstracting the details of script creation, script templates help in minimizing security risks associated with manual script handling. Robust templates can ensure that scripts are generated in a secure manner, adhering to the necessary cryptographic standards and best practices. Templates can also be audited for increased security, which will benefit everyone who relies upon it.
|
|
33
|
-
|
|
34
|
-
### Scalability and Efficiency
|
|
35
|
-
Script templates enable developers to quickly implement and deploy blockchain solutions on a large scale. They reduce the complexity involved in script creation, allowing developers to focus on building applications rather than dealing with the intricacies of script coding.
|
|
36
|
-
|
|
37
|
-
### Flexibility
|
|
38
|
-
Templates are designed to be flexible and extensible, accommodating various transaction types and conditions without significant modifications to the underlying codebase. This flexibility is crucial for adapting to evolving use cases and requirements in the BSV ecosystem.
|
|
39
|
-
|
|
40
|
-
## Conclusion
|
|
41
|
-
|
|
42
|
-
Script templates are fundamental tools within the BSV SDK that streamline the development of on-chain use-cases by providing robust, secure, and efficient methods for handling transaction scripts. They encapsulate the complexity of script creation and ensure that developers can focus on higher-level application logic, thereby accelerating the development process and enhancing the capabilities of their implementations. To get started with script templates in the TypeScript SDK, [check out this tutorial!](../examples/EXAMPLE_SCRIPT_TEMPLATES.md)
|
package/docs/concepts/TX_SIG.md
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# What are Transaction Signatures?
|
|
2
|
-
|
|
3
|
-
Transaction signatures play a crucial role in securing transactions and establishing trust between parties. These digital signatures serve as a powerful tool for validating the authenticity and integrity of spends on the blockchain. This document delves into the concept of transaction signatures, breaking down their components, functionality, and significance in a way that's (hopefully) accessible to a fairly broad audience.
|
|
4
|
-
|
|
5
|
-
## Introduction to Digital Signatures
|
|
6
|
-
|
|
7
|
-
Before diving into transaction signatures, it's essential to understand the basics of digital signatures. A digital signature is akin to a fingerprint; it is a unique mark that an individual can use to sign digital documents or transactions. Just as a handwritten signature authenticates the identity of the signer and their consent to the document's terms, a digital signature ensures that a digital document or transaction is authentic and hasn't been tampered with after the signature was made.
|
|
8
|
-
|
|
9
|
-
## Components of Transaction Signatures
|
|
10
|
-
|
|
11
|
-
Transaction signatures in BSV are a special type of digital signature. They consist of several key components:
|
|
12
|
-
|
|
13
|
-
- **r and s values**: These two values constitute the core of the ECDSA (Elliptic Curve Digital Signature Algorithm) signature. They are derived from the private key of the sender and the transaction data. Together, they verify that the owner of the corresponding public key has authorized the transaction.
|
|
14
|
-
- **SIGHASH flags**: Transaction signatures also include SIGHASH flags, which specify how much of the transaction data is covered by the signature. These flags allow signers to control which parts of the transaction they are committing to when they sign it, and which ones might be updated later.
|
|
15
|
-
|
|
16
|
-
## Understanding SIGHASH Flags
|
|
17
|
-
|
|
18
|
-
SIGHASH flags provide flexibility in how transactions are signed, offering several options:
|
|
19
|
-
|
|
20
|
-
- **SIGHASH_ALL**: This is the default mode, where the signature covers all the inputs and outputs of the transaction. It indicates the signer's commitment to the exact details of the transaction, including the amount and script associated with each output.
|
|
21
|
-
- **SIGHASH_NONE**: With this flag, the signature covers all inputs but no outputs, allowing others to add or modify outputs. This could be used in scenarios where the signer is indifferent to where the funds are going.
|
|
22
|
-
- **SIGHASH_SINGLE**: This mode signs only one input and one output, the one with the same index as the signed input. It is useful for transactions with multiple participants, allowing each to sign only for their part.
|
|
23
|
-
- **SIGHASH_ANYONECANPAY**: This flag can be combined with the others and indicates that the signature covers only the current input, allowing others to add more inputs to the transaction.
|
|
24
|
-
|
|
25
|
-
## The Role of Transaction Signatures
|
|
26
|
-
|
|
27
|
-
Transaction signatures serve two primary purposes on the BSV network:
|
|
28
|
-
|
|
29
|
-
1. **Authentication**: By signing a transaction with their private key, the sender proves they hold the private keys needed by the locking script that secures the funds they're attempting to spend.
|
|
30
|
-
2. **Integrity**: Once a transaction is signed, any alteration to the parts that were signed would invalidate the signature. This property ensures that once a transaction is broadcasted to the network, it cannot be tampered with or altered by malicious actors.
|
|
31
|
-
|
|
32
|
-
## Conclusion
|
|
33
|
-
|
|
34
|
-
Transaction signatures are at the heart of the security and trust model of blockchain technology. They enable the secure transfer of digital assets between parties without the need for a central authority. By understanding the components and functionality of transaction signatures, users and developers can better appreciate the sophisticated mechanisms that keep the BSV network secure and trustworthy. You can learn more about how transaction signatures work within the TypeScript BSV SDK [here](../low-level/TX_SIG.md).
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# How are Bitcoin Transactions Validated?
|
|
2
|
-
|
|
3
|
-
Understanding the intricacies of Bitcoin transaction validation is crucial for developers building systems that receive and process them within the ecosystem. This document will delve into the foundational concepts surrounding Bitcoin transactions, peer-to-peer exchange, and Simplified Payment Verification (SPV), as well as the critical validation processes that underpin the BSV network's scaling model.
|
|
4
|
-
|
|
5
|
-
## Introduction
|
|
6
|
-
|
|
7
|
-
Bitcoin transactions are the lifeblood of the network, enabling the transfer of value between participants without the need for central intermediaries. Each transaction on the Bitcoin SV blockchain is verified through a series of cryptographic checks and balances that ensure its authenticity and compliance with network rules.
|
|
8
|
-
|
|
9
|
-
### Key Concepts
|
|
10
|
-
|
|
11
|
-
- **Transactions:** These are data structures that encode the transfer of value between participants in the network.
|
|
12
|
-
- **Peer-to-Peer Exchange:** Direct interaction between participants' wallets without the need for a central authority, in which transactions and associated merkle proofs are sent back and forth.
|
|
13
|
-
- **SPV (Simplified Payment Verification):** A method for validating transactions that does not require downloading the entire blockchain, facilitating more scalable applications.
|
|
14
|
-
|
|
15
|
-
## The Transaction Validation Process
|
|
16
|
-
|
|
17
|
-
Validating a Bitcoin transaction involves several critical steps that confirm its legitimacy and adherence to the rules set by the network. Here's a breakdown of the validation process:
|
|
18
|
-
|
|
19
|
-
1. **Script Execution:**
|
|
20
|
-
- Each input in a transaction has an unlocking script that must successfully execute and validate against the locking script of the output it is spending.
|
|
21
|
-
- The result of this script execution must be true, indicating that the conditions to spend the output are met.
|
|
22
|
-
|
|
23
|
-
2. **Transaction Outputs vs. Inputs:**
|
|
24
|
-
- The total value of outputs must not exceed the total value of inputs, ensuring that no new money is created out of thin air, except for the coinbase transaction, which includes the block reward.
|
|
25
|
-
- Check that the transaction includes enough fee to be included in a block, as miners prioritize transactions with higher fees.
|
|
26
|
-
|
|
27
|
-
3. **Merkle Path Verifications:**
|
|
28
|
-
- Each input must be traceable back to a transaction included in a block, verified through a Merkle path.
|
|
29
|
-
- This ensures that each input used is legitimate and recognized by the network as having been previously confirmed.
|
|
30
|
-
|
|
31
|
-
4. **Checking Locktime and Sequence:**
|
|
32
|
-
- Transactions may include locktime and sequence numbers that impose conditions on the earliest time or block height at which a transaction can be added to the blockchain.
|
|
33
|
-
- Proper handling of these parameters ensures that transactions are processed in a timely and orderly manner.
|
|
34
|
-
|
|
35
|
-
You can check out an example using the TypeScript SDK where a transaction is verified according to these rules [here](../examples/EXAMPLE_VERIFYING_BEEF.md).
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
# Example: Building a Custom Transaction Broadcast Client
|
|
2
|
-
|
|
3
|
-
This guide walks through the necessary steps for building a custom transaction broadcast client.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
⚠️ It's important to notice that SDK is already providing broadcaster implementation that communicates with TAAL's ARC instance. This example is for educational purposes only.
|
|
8
|
-
|
|
9
|
-
A transaction broadcast client is a crucial component in any Bitcoin SV application, allowing it to communicate with the Bitcoin SV network. Implementing a transaction broadcaster can be accomplished using the clearly defined Broadcast interface.
|
|
10
|
-
|
|
11
|
-
Our task will be to create a broadcaster that connects with the What's on Chain service. This broadcaster is particularly designed for browser applications and utilizes the standard Fetch API for HTTP communications with the relevant API endpoints.
|
|
12
|
-
|
|
13
|
-
## Getting Started
|
|
14
|
-
|
|
15
|
-
In order to build a compliant broadcast client, we first need to import the interfaces to implement.
|
|
16
|
-
|
|
17
|
-
```ts
|
|
18
|
-
import { Transaction, BroadcastResponse, BroadcastFailure, Broadcaster } from '@bsv/sdk'
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
Next, we create a new class that implements the Broadcaster interface which requires a broadcast function.
|
|
22
|
-
|
|
23
|
-
We will be implementing a What's on Chain (WOC) broadcaster that runs in a browser context and uses [window.fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) to send a POST request to the WOC broadcast API endpoint.
|
|
24
|
-
|
|
25
|
-
```ts
|
|
26
|
-
import { Transaction } from '@bsv/sdk'
|
|
27
|
-
import type { Broadcaster } from '@bsv/sdk/src/transaction/Broadcaster'
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Represents an WOC transaction broadcaster.
|
|
31
|
-
*/
|
|
32
|
-
export default class WOC implements Broadcaster {
|
|
33
|
-
network: 'main' | 'test'
|
|
34
|
-
URL: string
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Constructs an instance of the WOC broadcaster.
|
|
38
|
-
*
|
|
39
|
-
* @param {string} network - which network to use (testnet or mainnet)
|
|
40
|
-
*/
|
|
41
|
-
constructor(network: 'main' | 'test') {
|
|
42
|
-
this.network = network
|
|
43
|
-
this.URL = `https://api.whatsonchain.com/v1/bsv/${network}/tx/raw`
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Broadcasts a transaction via WOC.
|
|
48
|
-
* This method will assume that window.fetch is available
|
|
49
|
-
*
|
|
50
|
-
* @param {Transaction} tx - The transaction to be broadcasted.
|
|
51
|
-
* @returns {Promise<BroadcastResponse | BroadcastFailure>} A promise that resolves to either a success or failure response.
|
|
52
|
-
*/
|
|
53
|
-
async broadcast(tx: Transaction): Promise<BroadcastResponse | BroadcastFailure> {
|
|
54
|
-
const txhex = tx.toHex()
|
|
55
|
-
|
|
56
|
-
const requestOptions = {
|
|
57
|
-
method: 'POST',
|
|
58
|
-
headers: {
|
|
59
|
-
'Content-Type': 'application/json'
|
|
60
|
-
},
|
|
61
|
-
body: JSON.stringify({ txhex })
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
try {
|
|
65
|
-
let data: any = {}
|
|
66
|
-
|
|
67
|
-
// Use fetch in a browser environment
|
|
68
|
-
const response = await window.fetch(`${this.URL}`, requestOptions)
|
|
69
|
-
data = await response.json()
|
|
70
|
-
|
|
71
|
-
if (data.txid as boolean || response.ok as boolean || response.status === 200) {
|
|
72
|
-
return {
|
|
73
|
-
status: 'success',
|
|
74
|
-
txid: data?.txid,
|
|
75
|
-
message: data?.messages
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
} catch (e) {
|
|
79
|
-
// TODO: Implement error handling as needed
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
Now, you can make use of this broadcast client when sending transactions with the `.broadcast()` method:
|
|
86
|
-
|
|
87
|
-
```typescript
|
|
88
|
-
await exampleTX.broadcast(new WOC('main'))
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
The result will be one of the SDK's standard `BroadcastResponse` or `BroadcastFailure` types, indicating the status of your transaction.
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
# Example: Creating Transactions with Inputs, Outputs and Templates
|
|
2
|
-
|
|
3
|
-
In Bitcoin, transactions contain inputs and outputs. The outputs are locked with scripts, and the inputs redeem these scripts by providing the correct unlocking solutions. This guide will show you how to create transactions that make use of custom inputs, outputs, and the associated script templates. For a more straightforward example, check out [how to create a simpler transaction](./EXAMPLE_SIMPLE_TX.md).
|
|
4
|
-
|
|
5
|
-
## Transaction Input and Outputs
|
|
6
|
-
|
|
7
|
-
All Bitcoins are locked up in Bitcoin transaction outputs. These outputs secure the coins by setting constraints on how they can be consumed in future transaction inputs. This security mechanism makes use of "scripts" — programs written in a special predicate language. There are many types of locking programs, embodying the multitude of BSV use-cases. The BSV SDK ships with a script templating system, making it easy for developers to create various types of scripts and abstracting away the complexity for end-users. You can learn about script templates [in the example](./EXAMPLE_SCRIPT_TEMPLATES.md).
|
|
8
|
-
|
|
9
|
-
## Creating a Transaction
|
|
10
|
-
|
|
11
|
-
To create a transaction with the SDK, you can either use the constructor:
|
|
12
|
-
|
|
13
|
-
- Use the constructor and pass in arrays of inputs and outputs, or
|
|
14
|
-
- Construct a blank transaction, then call the `addInput` and `addOutput` methods
|
|
15
|
-
|
|
16
|
-
```typescript
|
|
17
|
-
const tx = new Transaction(version, inputsArray, outputsArray, lockTime)
|
|
18
|
-
// or
|
|
19
|
-
const tx = new Transaction()
|
|
20
|
-
.addInput(inputA)
|
|
21
|
-
.addInput(inputB)
|
|
22
|
-
.addOutput(outputA)
|
|
23
|
-
tx.version = version
|
|
24
|
-
tx.lockTime = lockTime
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
Note that the version and lock time parameters are optional.
|
|
28
|
-
|
|
29
|
-
## Adding Inputs and Outputs
|
|
30
|
-
|
|
31
|
-
When constructing a Bitcoin transaction, inputs and outputs form the core components that dictate the flow of bitcoins. Here’s how to structure and add them to a transaction:
|
|
32
|
-
|
|
33
|
-
### Transaction Inputs
|
|
34
|
-
|
|
35
|
-
An input in a Bitcoin transaction represents the bitcoins being spent. It's essentially a reference to a previous transaction's output. Inputs have several key components:
|
|
36
|
-
|
|
37
|
-
- **`sourceTransaction` or `sourceTXID`**: A reference to either the source transaction (another Transaction instance), its TXID. Referencing the transaction itself is always preferred because it exposes more information to the library about the outputs it contains.
|
|
38
|
-
- **`sourceOutputIndex`**: A zero-based index indicating which output of the referenced transaction is being spent.
|
|
39
|
-
- **`sequence`**: A sequence number for the input. It allows for the replacement of the input until a transaction is finalized. If omitted, the final sequence number is used.
|
|
40
|
-
- **`unlockingScript`**: This script proves the spender's right to access the bitcoins from the spent output. It typically contains a digital signature and, optionally, other data like public keys.
|
|
41
|
-
- **`unlockingScriptTemplate`**: A template that provides a method to dynamically generate the unlocking script.
|
|
42
|
-
|
|
43
|
-
Next, we'll add an R-puzzle input into this transaction using the `RPuzzle`` template.
|
|
44
|
-
|
|
45
|
-
#### Example: Adding an Input
|
|
46
|
-
|
|
47
|
-
```typescript
|
|
48
|
-
const sourceTransaction = Transaction.fromHex('...')
|
|
49
|
-
const puz = new RPuzzle()
|
|
50
|
-
const k = new BigNumber(1)
|
|
51
|
-
const unlockingScriptTemplate = puz.unlock(k)
|
|
52
|
-
let txInput = {
|
|
53
|
-
sourceTransaction,
|
|
54
|
-
sourceOutputIndex: 0,
|
|
55
|
-
unlockingScriptTemplate
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const myTx = new Transaction()
|
|
59
|
-
myTx.addInput(txInput)
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
### Transaction Outputs
|
|
63
|
-
|
|
64
|
-
Outputs define where the bitcoins are going and how they are locked until the next spend. Each output includes:
|
|
65
|
-
|
|
66
|
-
- **`satoshis`**: The amount of satoshis (the smallest unit of Bitcoin) being transferred. This value dictates how much value the output holds.
|
|
67
|
-
- **`lockingScript`**: A script that sets the conditions under which the output can be spent. It's a crucial security feature, often requiring a digital signature that matches the recipient's public key.
|
|
68
|
-
- **`change`**: An optional boolean flag indicating if the output is sending change back to the sender.
|
|
69
|
-
|
|
70
|
-
We will now add an R-puzzle output to a transaction, making use of the script template.
|
|
71
|
-
|
|
72
|
-
#### Example: Adding an Output
|
|
73
|
-
|
|
74
|
-
```typescript
|
|
75
|
-
// We must first obtain an R-value for the template
|
|
76
|
-
const pubkey = PublicKey.fromString('...')
|
|
77
|
-
pubkey.x.umod(c.n).toArray()
|
|
78
|
-
r = r[0] > 127 ? [0, ...r] : r
|
|
79
|
-
const puz = new RPuzzle()
|
|
80
|
-
const lockingScript = puz.lock(r)
|
|
81
|
-
|
|
82
|
-
let txOutput = {
|
|
83
|
-
satoshis: 1000, // Amount in satoshis
|
|
84
|
-
lockingScript,
|
|
85
|
-
change: false // Not a change output, it has a defined number of satoshis
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
myTx.addOutput(txOutput)
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
## Change and Fee Computation
|
|
92
|
-
|
|
93
|
-
The transaction fee is the difference between the total inputs and total outputs of a transaction. Miners collect these fees as a reward for including transactions in a block. The amount of the fee paid will determine the quality of service provided my miners, subject to their policies.
|
|
94
|
-
|
|
95
|
-
If the total value of the inputs exceeds the total value you wish to send (plus the transaction fee), the excess amount is returned to you as "change." Change is sent back to a destination controlled by the sender, ensuring that no value is lost. When you set the `change` property on an output to `true`, you don't need to define a number of satoshis. This is because the library computes the number of satoshis for you, when the `.fee()` method is called.
|
|
96
|
-
|
|
97
|
-
In summary:
|
|
98
|
-
|
|
99
|
-
1. After all funding sources and recipient outputs are added, add at least one output where `change` is `true`, so that you capture what's left over after you send. Set up a locking script you control so that you can later spend your change.
|
|
100
|
-
|
|
101
|
-
2. Then, call the `.fee()` method to compute the change amounts across all change outputs, and leave the rest to the miner. You can specify a custom fee model if you wish, but the default should suffice for most use-cases.
|
|
102
|
-
|
|
103
|
-
In our above code, we already added a change output — now, we can just compute the fees before transaction signing.
|
|
104
|
-
|
|
105
|
-
```typescript
|
|
106
|
-
// Compute the correct amounts for change outputs and leave the rest for the Bitcoin miners
|
|
107
|
-
myTx.fee()
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
## Signing and Signature Validity
|
|
111
|
-
|
|
112
|
-
Once you've defined your inputs and outputs, and once your change has been computed, the next step is to sign your transaction. There are a few things you should note when signing:
|
|
113
|
-
|
|
114
|
-
- Only inputs with an unlocking template will be signed. If you provided an unlocking script yourself, the library assumes the signatures are already in place.
|
|
115
|
-
- If you change the inputs or outputs after signing, certain signatures will need to be re-computd, depending on the SIGHASH flags used.
|
|
116
|
-
- If your templates support it, you can produce partial signatures before serializing and sending to other parties. This is especially useful for multi-signature use-cases.
|
|
117
|
-
|
|
118
|
-
With these considerations in mind, we can now sign our transaction. The `RPuzzle` unlocking templates we configured earlier will be used in this process.
|
|
119
|
-
|
|
120
|
-
```typescript
|
|
121
|
-
// Set the input unlocking scripts based on the script templates
|
|
122
|
-
myTx.sign()
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
## Serialization and Broadcast
|
|
126
|
-
|
|
127
|
-
After a transaction is signed, it can be broadcast to the BSV Mining Network, or to relevant Overlay Networks through the SDK.
|
|
128
|
-
|
|
129
|
-
```typescript
|
|
130
|
-
await tx.broadcast()
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
Alternatively, if you don't want to use the SDK's built-in broadcasting system, you can simply serialize your transaction into a hex string as follows:
|
|
134
|
-
|
|
135
|
-
```typescript
|
|
136
|
-
// Serialize your transaction
|
|
137
|
-
myTx.toHex()
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
## SPV and Serialization Formats
|
|
141
|
-
|
|
142
|
-
Simplified Payment Verification is a mechanism that enables the recipient of a transaction to verify its legitimacy by providing necessary information, like input transactions and their associated merkle proofs.
|
|
143
|
-
|
|
144
|
-
Earlier in this guide, we mentioned that you can either reference a `sourceTXID` or, preferably, a `sourceTransaction` when linking transaction inputs. The reason why it's preferable to link the entire source transaction is because serializing the transaction in an SPV-compliant way generally requires more information about the outputs being spent.
|
|
145
|
-
|
|
146
|
-
When properly linked, you can serialize your transactions in the SPV formats as follows:
|
|
147
|
-
|
|
148
|
-
```typescript
|
|
149
|
-
// Note: Requires use of sourceTransaction instead of sourceTXID for inputs
|
|
150
|
-
myTx.toHexBEEF()
|
|
151
|
-
// or
|
|
152
|
-
myTx.toHexEF()
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
This enables the transactions to be verified properly by recipients, using the `.verify()` method:
|
|
156
|
-
|
|
157
|
-
```typescript
|
|
158
|
-
const incomingTX = Transaction.fromHexBEEF('...')
|
|
159
|
-
incomingTX.verify() // Provide a source of BSV block headers to verify
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
Recipients, with nothing other than a source of BSV block headers, can verify that the transaction properly unlocks and redeems its inputs, thereby creating its outputs. To learn more about setting up a chain tracker with a source of block headers, check out the Pulse example (link to be provided once completed).
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
# Example: Using ECIES Encryption
|
|
2
|
-
|
|
3
|
-
Electrum ECIES is a protocol for exchanging encrypted data between parties. It has been commonly used in many applications, and while the SDK's native [Message Encryption functionality](EXAMPLE_ENCRYPT_DECRYPT_MESSAGE.md) is the preferred approach for new applications (due to its use of GCM over CBC and aditional layers of security described below), legacy systems still use ECIES and this guide will demonstrate how it can be done.
|
|
4
|
-
|
|
5
|
-
## Message Encryption
|
|
6
|
-
|
|
7
|
-
In ECIES, a message can be encrypted directly to the public key of the recipient, either from your private key or from a random private key. The public key can either be included or excluded from the message. Check out the below examples:
|
|
8
|
-
|
|
9
|
-
```typescript
|
|
10
|
-
import { ECIES, PrivateKey, Utils } from '@bsv/sdk'
|
|
11
|
-
|
|
12
|
-
const alicePrivateKey = PrivateKey.fromString('77e06abc52bf065cb5164c5deca839d0276911991a2730be4d8d0a0307de7ceb', 16)
|
|
13
|
-
const bobPrivateKey = PrivateKey.fromString('2b57c7c5e408ce927eef5e2efb49cfdadde77961d342daa72284bb3d6590862d', 16)
|
|
14
|
-
const message = Utils.toArray('this is my ECDH test message', 'utf8')
|
|
15
|
-
|
|
16
|
-
const ecdhMessageEncryptedAlice = ECIES.electrumEncrypt(message, alicePrivateKey.toPublicKey(), bobPrivateKey, true)
|
|
17
|
-
console.log(Utils.toUTF8(ECIES.electrumDecrypt(ecdhMessageEncryptedAlice, bobPrivateKey, alicePrivateKey.toPublicKey())))
|
|
18
|
-
// 'this is my ECDH test message'
|
|
19
|
-
|
|
20
|
-
const ecdhMessageEncryptedBob = ECIES.electrumEncrypt(message, bobPrivateKey.toPublicKey(), alicePrivateKey, true)
|
|
21
|
-
console.log(Utils.toUTF8(ECIES.electrumDecrypt(ecdhMessageEncryptedBob, alicePrivateKey, bobPrivateKey.toPublicKey())))
|
|
22
|
-
// 'this is my ECDH test message'
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
Here, we start by declaring two private keys. Then, ...
|
|
26
|
-
|
|
27
|
-
## Considerations
|
|
28
|
-
|
|
29
|
-
This guide has shown how to use Electrum ECIES encryption. While this approach has been used by many legacy systems, the SDK's native encryption has the following benefits:
|
|
30
|
-
|
|
31
|
-
- **Additional Security Layer**: The native SDK implentation, based on [BRC-78](https://github.com/bitcoin-sv/BRCs/blob/master/peer-to-peer/0078.md), employs an additional layer of security by utilizing a one-off ephemeral key for the encryption process. Even if the key for a particular message is discovered, it does not compromise the private keys of either of the parties. Different keys are used for every message, adding an additional step for attackers.
|
|
32
|
-
|
|
33
|
-
- **Incompatibility with BRC-43 Invoice Numbers**: The native approach is fully compatible with [BRC-43](https://brc.dev/43) invoice numbers, and the [BRC-2](https://brc.dev/2) encryption process, making it possible for users of the [BRC-56 standard wallet](https://brc.dev/56) able to natively use the system under their MetaNet identities. ECIES is not compatible with these standards.
|
|
34
|
-
|
|
35
|
-
- **Use of GCM over CBC**: While this is not a security risk, GCM supports range-based encryption and decryption. This may make it better than CBC if you need to send parts of a large encrypted dataset over the network.
|
|
36
|
-
|
|
37
|
-
Despite these drawbacks, Electrum ECIES still remains a fundamentally secure and robust encryption scheme.
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
# Example: Message Encryption and Decryption
|
|
2
|
-
|
|
3
|
-
This guide walks you through the steps of encrypting and decrypting messages.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
Understanding the ins-and-outs of message encryption and decryption is key to implementing secure communication. The implemented functions allow a sender to encrypt messages that only the intended recipient can decrypt, thus preserving the privacy of the message exchange.
|
|
8
|
-
|
|
9
|
-
### Encrypting a Message
|
|
10
|
-
To get started, you will first want to import the required functions / classes.
|
|
11
|
-
|
|
12
|
-
```ts
|
|
13
|
-
import { PrivateKey, EncryptedMessage, Utils } from '@bsv/sdk'
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
Next, you will want to configure who the sender is, the recipient, and what message you would like to encrypt.
|
|
17
|
-
|
|
18
|
-
```ts
|
|
19
|
-
const sender = new PrivateKey(15)
|
|
20
|
-
const recipient = new PrivateKey(21)
|
|
21
|
-
const recipientPub = recipient.toPublicKey()
|
|
22
|
-
const message: number[] = Utils.toArray('Did you receive the Bitcoin payment?', 'utf8')
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
Now you are ready to generate the ciphertext using the `encrypt` function. This function will return an array of bytes so you will need to convert it using `toUTF` if you would like it as a string of text.
|
|
26
|
-
|
|
27
|
-
```ts
|
|
28
|
-
const encrypted: number[] = EncryptedMessage.encrypt(message, sender, recipientPub)
|
|
29
|
-
const ciphertextMessage: string = Utils.toUTF8(encrypted)
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### Decrypting a Message
|
|
33
|
-
|
|
34
|
-
To get back your plaintext message, use the `decrypt` function and then transform it as needed.
|
|
35
|
-
|
|
36
|
-
```ts
|
|
37
|
-
const decrypted: number[] = EncryptedMessage.decrypt(encrypted, recipient)
|
|
38
|
-
const plaintextMessage: string = Utils.toUTF8(decrypted)
|
|
39
|
-
// console.log(plaintextMessage) -> 'Did you receive the Bitcoin payment?'
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Considerations
|
|
43
|
-
|
|
44
|
-
As you leverage encryption and decryption in your applications, it's crucial to remember:
|
|
45
|
-
|
|
46
|
-
- **Key management**: Private keys should always be kept safe and never exposed. This library insures that intermediate keys generated for message encryption always use random nonces to mitigate key-reuse attack vectors.
|
|
47
|
-
|
|
48
|
-
- **Key of recipient:** The decryption stage using the recipient's key is always done on the recipient's end. As such, the recipient key used is the public key provided by the recipient, and is just generated in the above example for testing purposes.
|
|
49
|
-
|
|
50
|
-
- **Interpretation of decrypted data**: The decrypted byte array may need to be transformed back into a string, depending on the nature of the original message. There are several utility functions exported, such as toUTF8, that can be leveraged as needed.
|
|
51
|
-
|
|
52
|
-
This is just a simple example of how encryption and decryption can be implemented for secure message exchange in your applications. The exact method of implementation might vary based on your application’s specifics.
|