|
| 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