Skip to content

Commit 511d54e

Browse files
committed
Generate READMEs for all examples
1 parent 7dcbf51 commit 511d54e

File tree

21 files changed

+1657
-0
lines changed

21 files changed

+1657
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Address From WIF Example
2+
3+
This example demonstrates how to derive a Bitcoin SV address from a Wallet Import Format (WIF) private key string using the `ec` and `script` packages.
4+
5+
## Overview
6+
7+
The `address_from_wif` example showcases:
8+
1. Importing a private key from its WIF string representation using `ec.PrivateKeyFromWif`.
9+
2. Getting the corresponding public key from the private key using `privateKey.PubKey()`.
10+
3. Generating a P2PKH (Pay-to-Public-Key-Hash) address object from this public key using `script.NewAddressFromPublicKey`.
11+
4. Printing the serialized private key, the string representation of the derived address, and its public key hash.
12+
13+
## Code Walkthrough
14+
15+
### Deriving Address from WIF
16+
17+
```go
18+
// Import private key from WIF string
19+
privKey, _ := ec.PrivateKeyFromWif("Kxfd8ABTYZHBH3y1jToJ2AUJTMVbsNaqQsrkpo9gnnc1JXfBH8mn")
20+
21+
// Log the serialized private key (hexadecimal)
22+
log.Printf("Private key (hex): %x\n", privKey.Serialize())
23+
24+
// Get the public key associated with the private key
25+
pubKey := privKey.PubKey()
26+
27+
// Create a new address object from the public key
28+
// The 'true' argument typically indicates if it's for mainnet (compressed pubkey used for address)
29+
address, _ := script.NewAddressFromPublicKey(pubKey, true)
30+
31+
// Print the address string and the underlying public key hash
32+
fmt.Printf("Address: %s\n", address.AddressString)
33+
fmt.Printf("Public Key Hash: %s\n", address.PublicKeyHash) // Or however you wish to display the hash
34+
```
35+
36+
This section shows the step-by-step process:
37+
- `ec.PrivateKeyFromWif` parses the WIF string and returns an `*ec.PrivateKey` object.
38+
- `privKey.PubKey()` returns the corresponding `*ec.PublicKey`.
39+
- `script.NewAddressFromPublicKey(pubKey, true)` takes the public key and a boolean (often indicating network or if the key should be compressed for address generation) to produce an `*script.Address` object. This object contains the familiar base58check encoded address string and the raw public key hash.
40+
41+
## Running the Example
42+
43+
To run this example:
44+
45+
```bash
46+
go run address_from_wif.go
47+
```
48+
The output will display the hexadecimal representation of the private key, the derived P2PKH address string, and the public key hash component of the address.
49+
50+
**Note**:
51+
- The WIF string is hardcoded. In a real application, this would come from a secure source.
52+
- The example derives a P2PKH address, which is the most common address type.
53+
- The boolean argument `true` in `NewAddressFromPublicKey` typically signifies that the address should be generated for the main network, often implying the use of a compressed public key for the hash.
54+
55+
## Integration Steps
56+
57+
To derive an address from a WIF in your application:
58+
1. Obtain the WIF string for the private key.
59+
2. Use `priv, err := ec.PrivateKeyFromWif(wifString)` to get the private key object. Handle any errors.
60+
3. Get the public key: `pubKey := priv.PubKey()`.
61+
4. Generate the address: `addr, err := script.NewAddressFromPublicKey(pubKey, isMainnet)`, where `isMainnet` is true for mainnet addresses. Handle errors.
62+
5. You can then use `addr.AddressString` for display or in transactions, and `addr.PublicKeyHash` if you need the raw hash.
63+
64+
## Additional Resources
65+
66+
For more information, see:
67+
- [Package Documentation - EC primitives](https://pkg.go.dev/github.com/bsv-blockchain/go-sdk/primitives/ec)
68+
- [Package Documentation - Script](https://pkg.go.dev/github.com/bsv-blockchain/go-sdk/script)
69+
- [Generate HD Key Example](../generate_hd_key/) (for creating master keys from which WIFs can be derived)

docs/examples/aes/README.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# AES Encryption/Decryption Example
2+
3+
This example demonstrates basic AES (Advanced Encryption Standard) GCM (Galois/Counter Mode) encryption and decryption using the `aesgcm` package.
4+
5+
## Overview
6+
7+
The `aes` example showcases:
8+
1. Defining a hexadecimal AES key.
9+
2. Encrypting a plaintext byte slice (`[]byte("0123456789abcdef")`) using `aesgcm.AESEncrypt`.
10+
3. Decrypting the resulting ciphertext using `aesgcm.AESDecrypt` with the same key.
11+
4. Printing the decrypted data.
12+
13+
## Code Walkthrough
14+
15+
### Encrypting and Decrypting Data
16+
17+
```go
18+
package main
19+
20+
import (
21+
"encoding/hex"
22+
"fmt"
23+
24+
aes "github.com/bsv-blockchain/go-sdk/primitives/aesgcm"
25+
)
26+
27+
func main() {
28+
// Define an AES key (must be 16, 24, or 32 bytes for AES-128, AES-192, or AES-256 respectively)
29+
key, _ := hex.DecodeString("000102030405060708090a0b0c0d0e0f") // 16 bytes for AES-128
30+
31+
plaintext := []byte("0123456789abcdef")
32+
33+
// Encrypt the data
34+
encryptedData, err := aes.AESEncrypt(plaintext, key)
35+
if err != nil {
36+
fmt.Println("Encryption error:", err)
37+
return
38+
}
39+
fmt.Printf("Encrypted data (hex): %x\n", encryptedData)
40+
41+
// Decrypt the data
42+
decryptedData, err := aes.AESDecrypt(encryptedData, key)
43+
if err != nil {
44+
fmt.Println("Decryption error:", err)
45+
return
46+
}
47+
fmt.Printf("Decrypted data: %s\n", decryptedData)
48+
}
49+
```
50+
51+
This section shows:
52+
- Initialization of a 16-byte AES key.
53+
- Encryption of a sample plaintext using `aes.AESEncrypt`. This function handles nonce generation and prepends it to the ciphertext.
54+
- Decryption of the ciphertext using `aes.AESDecrypt`. This function extracts the nonce from the ciphertext and performs decryption.
55+
56+
## Running the Example
57+
58+
To run this example:
59+
60+
```bash
61+
go run aes.go
62+
```
63+
The output will show the hexadecimal representation of the encrypted data, followed by the successfully decrypted original message.
64+
65+
**Note**:
66+
- The key used is hardcoded. In real applications, keys should be securely generated and managed.
67+
- The `aesgcm` package uses AES in GCM mode, which provides both confidentiality and authenticity.
68+
- The nonce is generated internally by `AESEncrypt` and prepended to the ciphertext. `AESDecrypt` expects this format.
69+
70+
## Integration Steps
71+
72+
To use AES GCM encryption/decryption in your application:
73+
74+
**For Encryption:**
75+
1. Obtain or generate a secure AES key of appropriate length (16, 24, or 32 bytes).
76+
2. Call `ciphertext, err := aesgcm.AESEncrypt(plaintextBytes, key)`.
77+
3. Store or transmit the `ciphertext`.
78+
79+
**For Decryption:**
80+
1. Obtain the same AES key used for encryption.
81+
2. Call `plaintextBytes, err := aesgcm.AESDecrypt(ciphertext, key)`.
82+
3. The `plaintextBytes` will contain the original data if decryption is successful.
83+
84+
Ensure proper key management practices are followed.
85+
86+
## Additional Resources
87+
88+
For more information, see:
89+
- [Package Documentation - aesgcm](https://pkg.go.dev/github.com/bsv-blockchain/go-sdk/primitives/aesgcm)
90+
- NIST Special Publication 800-38D for GCM mode.
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Authenticated Messaging Example
2+
3+
This example demonstrates how to use the `auth` package for establishing a secure, authenticated communication channel between two peers.
4+
5+
## Overview
6+
7+
The `authenticated_messaging` example showcases:
8+
1. Creating and connecting two `Peer` instances using an in-memory transport.
9+
2. Deriving identity keys for each peer.
10+
3. Sending an encrypted and signed message from one peer to another.
11+
4. Receiving and decrypting the message on the recipient's side.
12+
5. Sending a reply back to the original sender.
13+
14+
## Code Walkthrough
15+
16+
### Setting Up Peers and Transport
17+
18+
```go
19+
// Create two transport pairs
20+
aliceTransport := NewMemoryTransport()
21+
bobTransport := NewMemoryTransport()
22+
23+
// Connect the transports
24+
aliceTransport.Connect(bobTransport)
25+
bobTransport.Connect(aliceTransport)
26+
27+
// Create two wallets with random keys
28+
// ... (wallet creation code) ...
29+
30+
// Create peers
31+
alicePeer := auth.NewPeer(&auth.PeerOptions{
32+
Wallet: aliceWallet,
33+
Transport: aliceTransport,
34+
})
35+
36+
bobPeer := auth.NewPeer(&auth.PeerOptions{
37+
Wallet: bobWallet,
38+
Transport: bobTransport,
39+
})
40+
```
41+
42+
This section explains the initial setup of in-memory transport, wallets, and peer instances for Alice and Bob.
43+
44+
### Sending and Receiving Messages
45+
46+
```go
47+
// Get identity keys
48+
// ... (identity key retrieval code) ...
49+
50+
// Set up message listeners
51+
alicePeer.ListenForGeneralMessages(func(senderPublicKey *ec.PublicKey, payload []byte) error {
52+
fmt.Printf("Alice received message from %s: %s\n", senderPublicKey.Compressed(), string(payload))
53+
return nil
54+
})
55+
56+
bobPeer.ListenForGeneralMessages(func(senderPublicKey *ec.PublicKey, payload []byte) error {
57+
fmt.Printf("Bob received message from %s: %s\n", senderPublicKey.Compressed(), string(payload))
58+
59+
// Reply to Alice
60+
err := bobPeer.ToPeer(context.Background(), []byte("Hello back, Alice!"), senderPublicKey, 5000)
61+
if err != nil {
62+
log.Printf("Bob failed to reply: %v", err)
63+
}
64+
return nil
65+
})
66+
67+
// Alice sends a message to Bob
68+
err = alicePeer.ToPeer(context.Background(), []byte("Hello, Bob!"), bobIdentityResult.PublicKey, 5000)
69+
if err != nil {
70+
log.Fatalf("Failed to send message: %v", err)
71+
}
72+
```
73+
74+
This section details how peers listen for messages and how Alice sends an initial message to Bob, who then replies. The `ToPeer` method handles encryption and signing.
75+
76+
## Running the Example
77+
78+
To run this example:
79+
80+
```bash
81+
go run authenticated_messaging.go
82+
```
83+
84+
**Note**: This example uses an in-memory transport (`MemoryTransport`) for simplicity. In a real-world application, you would use a network-based transport like WebSockets. It also uses a `MinimalWalletImpl` which is a mock; a full wallet implementation would be required for production use.
85+
86+
## Integration Steps
87+
88+
To integrate authenticated messaging into your application:
89+
1. Implement `auth.Transport` for your chosen communication protocol (e.g., WebSockets, HTTP).
90+
2. Ensure both peers have a fully implemented `wallet.Interface`.
91+
3. Initialize `auth.Peer` for each communicating party with their respective wallets and the chosen transport.
92+
4. Use `peer.ToPeer()` to send authenticated messages and `peer.ListenForGeneralMessages()` to receive them.
93+
94+
## Additional Resources
95+
96+
For more information, see:
97+
- [Package Documentation](https://pkg.go.dev/github.com/bsv-blockchain/go-sdk/auth)
98+
- [Identity Client Example](../identity_client/)
99+
- [Websocket Peer Example](../websocket_peer/)
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Create Transaction with Inscription Example
2+
3+
This example demonstrates how to use the `transaction` and `script` packages to create a Bitcoin SV transaction that includes an "inscription" output, embedding arbitrary data (like an image) onto the blockchain.
4+
5+
## Overview
6+
7+
The `create_tx_with_inscription` example showcases:
8+
1. Creating a new transaction.
9+
2. Adding an input from a previous transaction (UTXO).
10+
3. Reading data from a file (an image in this case).
11+
4. Determining the MIME type of the data.
12+
5. Using `tx.Inscribe()` to create an OP_RETURN output formatted as a BRC-43 (1Sat Ordinals style) inscription. This output contains the file data and its content type.
13+
6. Adding a change output.
14+
7. Signing the transaction.
15+
16+
## Code Walkthrough
17+
18+
### Creating and Signing the Inscription Transaction
19+
20+
```go
21+
// Create a new transaction and add an input
22+
priv, _ := ec.PrivateKeyFromWif("KznpA63DPFrmHecASyL6sFmcRgrNT9oM8Ebso8mwq1dfJF3ZgZ3V")
23+
unlocker, _ := p2pkh.Unlock(priv, nil)
24+
tx := transaction.NewTransaction()
25+
_ = tx.AddInputFrom( /* UTXO details */ unlocker)
26+
27+
// Read image data and get content type
28+
data, _ := os.ReadFile("1SatLogoLight.png")
29+
contentType := mime.TypeByExtension(".png")
30+
31+
// Create a P2PKH locking script for the inscription output itself (where the 1 satoshi for the inscription goes)
32+
add, _ := script.NewAddressFromPublicKey(priv.PubKey(), true)
33+
inscriptionLockingScript, _ := p2pkh.Lock(add)
34+
35+
// Inscribe the data
36+
err = tx.Inscribe(&script.InscriptionArgs{
37+
LockingScript: inscriptionLockingScript, // Who owns this inscription
38+
Data: data,
39+
ContentType: contentType,
40+
})
41+
// ... handle error ...
42+
43+
// Add a change output
44+
changeAdd, _ := script.NewAddressFromString("17ujiveRLkf2JQiGR8Sjtwb37evX7vG3WG")
45+
changeScript, _ := p2pkh.Lock(changeAdd)
46+
tx.AddOutput(&transaction.TransactionOutput{
47+
LockingScript: changeScript,
48+
Satoshis: 0, // Will be calculated if tx.FeePerKB > 0
49+
Change: true,
50+
})
51+
52+
// Sign the transaction
53+
err = tx.Sign()
54+
// ... handle error ...
55+
56+
fmt.Println(tx.String()) // Print the raw transaction hex
57+
```
58+
59+
This section shows the process of:
60+
- Setting up a private key and deriving an unlocker for the input.
61+
- Adding a spendable input (UTXO).
62+
- Reading the content of `1SatLogoLight.png` and its MIME type.
63+
- Creating a P2PKH locking script that will "own" the inscription.
64+
- Calling `tx.Inscribe()` which constructs the specific OP_FALSE OP_IF ... OP_ENDIF script sequence for the inscription, placing the data and content type within it. This method adds the inscription output to the transaction.
65+
- Adding a standard P2PKH change output.
66+
- Signing all inputs of the transaction.
67+
68+
## Running the Example
69+
70+
To run this example:
71+
1. Ensure you have the `1SatLogoLight.png` file in the same directory as `create_tx_with_inscription.go`.
72+
2. Execute the Go program:
73+
```bash
74+
go run create_tx_with_inscription.go
75+
```
76+
The output will be the hexadecimal representation of the signed transaction.
77+
78+
**Note**:
79+
- The example uses a hardcoded private key and UTXO details. For a real transaction, you would use your own keys and unspent outputs.
80+
- The transaction created by this example is not broadcast to the network. You would need to use a broadcasting service to do that.
81+
- The `tx.Inscribe()` method creates a 1-satoshi output locked with `inscriptionLockingScript`, followed by the inscription OP_RETURN output.
82+
- The change output amount will be automatically calculated if `tx.FeePerKB` is set to a value greater than 0 before signing. If `tx.FeePerKB` is 0 (the default), the change output will receive any remaining satoshis after accounting for inputs and other outputs (like the 1-satoshi inscription output).
83+
84+
## Integration Steps
85+
86+
To create an inscription transaction in your application:
87+
1. Obtain a spendable UTXO and the corresponding private key.
88+
2. Create a `transaction.NewTransaction()`.
89+
3. Add the input using `tx.AddInputFrom()` or similar, providing an appropriate `UnlockingScriptGetter`.
90+
4. Prepare your data (`[]byte`) and determine its `contentType` (MIME string).
91+
5. Create the `LockingScript` that will be associated with the 1-satoshi output for the inscription (i.e., who owns the inscription). This is typically a P2PKH script.
92+
6. Call `tx.Inscribe(&script.InscriptionArgs{LockingScript: yourLockingScript, Data: data, ContentType: contentType})`.
93+
7. Add any other outputs, including a change output (`tx.AddOutput(&transaction.TransactionOutput{LockingScript: changeScript, Change: true})`).
94+
8. Set transaction fee parameters if desired (e.g., `tx.FeePerKB = fee_models.DefaultFee().FeeKB`).
95+
9. Sign the transaction using `tx.Sign()`.
96+
10. Broadcast the resulting `tx.String()` (hex) or `tx.Bytes()`.
97+
98+
## Additional Resources
99+
100+
For more information, see:
101+
- [Package Documentation - Transaction](https://pkg.go.dev/github.com/bsv-blockchain/go-sdk/transaction)
102+
- [Package Documentation - Script](https://pkg.go.dev/github.com/bsv-blockchain/go-sdk/script)
103+
- [Create Transaction with OP_RETURN Example](../create_tx_with_op_return/)
104+
- BRC-43 (Ordinals Inscriptions on BSV) specification.

0 commit comments

Comments
 (0)