From d67001d44aaeb31b48a0bcffc4410325a0e4cf5c Mon Sep 17 00:00:00 2001 From: David Case <david@fyxgaming.com> Date: Fri, 1 Nov 2024 11:08:18 -0400 Subject: [PATCH] remove FillAllInputs from docs --- README.md | 14 +- .../create_simple_tx/create_simple_tx.md | 74 +++--- transaction/template/p2pkh/p2pkh_test.go | 250 ------------------ 3 files changed, 42 insertions(+), 296 deletions(-) diff --git a/README.md b/README.md index cc55964..7af183a 100644 --- a/README.md +++ b/README.md @@ -53,18 +53,22 @@ import ( func main() { tx := transaction.NewTransaction() - _ = tx.AddInputFrom( + unlockingScriptTemplate, _ := p2pkh.Unlock(priv, nil) + if err := tx.AddInputFrom( "11b476ad8e0a48fcd40807a111a050af51114877e09283bfa7f3505081a1819d", 0, - "76a914eb0bd5edba389198e73f8efabddfc61666969ff788ac6a0568656c6c6f", + "76a9144bca0c466925b875875a8e1355698bdcc0b2d45d88ac", 1500, - ) + unlockingScriptTemplate, + ); err!= nil { + log.Fatal(err.Error()) + } _ = tx.PayToAddress("1AdZmoAQUw4XCsCihukoHMvNWXcsd8jDN6", 1000) - decodedWif, _ := wif.DecodeWIF("KzH8frNSgsKtmPQ2oMFnwD3DK347PY3YJUzE1dCKNKLaWSfHaXGC") + priv, _ := ec.PrivateKeyFromWif("KznvCNc6Yf4iztSThoMH6oHWzH9EgjfodKxmeuUGPq5DEX5maspS") - if err := tx.FillAllInputs(context.Background(), &unlocker.Getter{PrivateKey: decodedWif.PrivKey}); err != nil { + if err := tx.Sign(); err != nil { log.Fatal(err.Error()) } log.Printf("tx: %s\n", tx) diff --git a/docs/examples/create_simple_tx/create_simple_tx.md b/docs/examples/create_simple_tx/create_simple_tx.md index 75809d7..3c81f1b 100644 --- a/docs/examples/create_simple_tx/create_simple_tx.md +++ b/docs/examples/create_simple_tx/create_simple_tx.md @@ -25,44 +25,35 @@ import ( // https://goplay.tools/snippet/bnsS-pA56ob func main() { // Create a new transaction - tx := transaction.NewTransaction() - - // Add the inputs - err := tx.AddInputFrom( - // Previous transaction ID (hex) - "11b476ad8e0a48fcd40807a111a050af51114877e09283bfa7f3505081a1819d", - // Previous transaction output index - 0, - // Previous transaction script (hex) - "76a9144bca0c466925b875875a8e1355698bdcc0b2d45d88ac", - // Previous transaction output value in satoshis - 1500, - ) - - if err!= nil { - log.Fatal(err.Error()) - } - - // Add the outputs - _ = tx.PayToAddress( - // Destination address - "1NRoySJ9Lvby6DuE2UQYnyT67AASwNZxGb", - // Value in satoshis - 1000, - ) - - // Fill all inputs with the given private key - decodedWif, _ := wif.DecodeWIF("KznvCNc6Yf4iztSThoMH6oHWzH9EgjfodKxmeuUGPq5DEX5maspS") - - // Sign the transaction - if err := tx.FillAllInputs( - // The default context which is empty but can be - // used to control cancellations and timeouts. - context.Background(), - &unlocker.Getter{PrivateKey: decodedWif.PrivKey}); err != nil { - log.Fatal(err.Error()) - } - log.Printf("tx: %s\n", tx) + tx := transaction.NewTransaction() + + // Add the inputs + unlockingScriptTemplate, _ := p2pkh.Unlock(priv, nil) + if err := tx.AddInputFrom( + "11b476ad8e0a48fcd40807a111a050af51114877e09283bfa7f3505081a1819d", + 0, + "76a9144bca0c466925b875875a8e1355698bdcc0b2d45d88ac", + 1500, + unlockingScriptTemplate, + ); err!= nil { + log.Fatal(err.Error()) + } + + // Add the outputs + _ = tx.PayToAddress( + // Destination address + "1NRoySJ9Lvby6DuE2UQYnyT67AASwNZxGb", + // Value in satoshis + 1000, + ) + + priv, _ := ec.PrivateKeyFromWif("KznvCNc6Yf4iztSThoMH6oHWzH9EgjfodKxmeuUGPq5DEX5maspS") + + // Sign the transaction + if err := tx.Sign(); err != nil { + log.Fatal(err.Error()) + } + log.Printf("tx: %s\n", tx) } ``` @@ -81,19 +72,20 @@ Main Function: - The output index (vout) in the referenced transaction. - A script (locking script) representing the locking conditions under which the output can be spent. - The number of satoshis from the output that is being spent. +- UnlockingScriptTemplate used to sign input `tx.PayToAddress(...)` adds an output to the transaction, specifying: - The recipient's Bitcoin SV address. - The amount of satoshis to send to that address. -`wif.DecodeWIF(...)` decodes a WIF-encoded private key. This is necessary for signing the transaction inputs. +`ec.PrivateKeyFromWif(...)` decodes a WIF-encoded private key. This is necessary for signing the transaction inputs. -`tx.FillAllInputs(...)` attempts to sign all inputs of the transaction using the private key provided. This is essential for validating the transaction on the network. +`tx.Sign(...)` attempts to sign all inputs of the transaction using the script templates provided. This is essential for validating the transaction on the network. The context passed `(context.Background())` is the default context which is empty but can be used to control cancellations and timeouts. Error Handling and Logging: -If `tx.FillAllInputs(...)` returns an error, the program logs the error and terminates using `log.Fatal(...)`. +If `tx.Sign(...)` returns an error, the program logs the error and terminates using `log.Fatal(...)`. If no error occurs, it logs the serialized form of the transaction, which is ready to be broadcasted to the network. diff --git a/transaction/template/p2pkh/p2pkh_test.go b/transaction/template/p2pkh/p2pkh_test.go index ea447b5..ba61568 100644 --- a/transaction/template/p2pkh/p2pkh_test.go +++ b/transaction/template/p2pkh/p2pkh_test.go @@ -128,253 +128,3 @@ func TestLocalUnlocker_ValidSignature(t *testing.T) { }) } } - -// type mockUnlockerGetter struct { -// t *testing.T -// unlockerFunc func(ctx context.Context, lockingScript *script.Script) (transaction.ScriptTemplate, error) -// } - -// func (m *mockUnlockerGetter) Unlocker(ctx context.Context, lockingScript *script.Script) (transaction.ScriptTemplate, error) { -// require.NotNil(m.t, m.unlockerFunc, "unlockerFunc not set in this test") -// return m.unlockerFunc(ctx, lockingScript) -// } - -// type mockUnlocker struct { -// t *testing.T -// script string -// } - -// func (m *mockUnlocker) UnlockingScript(ctx context.Context, tx *transaction.Transaction, params transaction.UnlockParams) (*script.Script, error) { -// uscript, err := script.NewFromASM(m.script) -// require.NoError(m.t, err) - -// return uscript, nil -// } - -// func TestLocalUnlocker_NonSignature(t *testing.T) { -// t.Parallel() -// tests := map[string]struct { -// tx *transaction.Transaction -// unlockerFunc func(ctx context.Context, lockingScript *script.Script) (transaction.Unlocker, error) -// expUnlockingScripts []string -// }{ -// "simple script": { -// tx: func() *transaction.Transaction { -// tx := transaction.NewTransaction() -// require.NoError(t, tx.AddInputFrom("45be95d2f2c64e99518ffbbce03fb15a7758f20ee5eecf0df07938d977add71d", 0, "52529387", 15564838601)) -// return tx -// }(), -// unlockerFunc: func(ctx context.Context, lockingScript *script.Script) (transaction.Unlocker, error) { -// asm, err := lockingScript.ToASM() -// require.NoError(t, err) - -// unlocker, ok := map[string]*mockUnlocker{ -// "OP_2 OP_2 OP_ADD OP_EQUAL": {t: t, script: "OP_4"}, -// }[asm] - -// require.True(t, ok) -// require.NotNil(t, unlocker) - -// return unlocker, nil -// }, -// expUnlockingScripts: []string{"OP_4"}, -// }, -// "multiple inputs unlocked": { -// tx: func() *transaction.Transaction { -// tx := transaction.NewTransaction() -// require.NoError(t, tx.AddInputFrom("45be95d2f2c64e99518ffbbce03fb15a7758f20ee5eecf0df07938d977add71d", 0, "52529487", 15564838601)) -// require.NoError(t, tx.AddInputFrom("45be95d2f2c64e99518ffbbce03fb15a7758f20ee5eecf0df07938d977add71d", 0, "52589587", 15564838601)) -// require.NoError(t, tx.AddInputFrom("45be95d2f2c64e99518ffbbce03fb15a7758f20ee5eecf0df07938d977add71d", 0, "5a559687", 15564838601)) -// return tx -// }(), -// unlockerFunc: func(ctx context.Context, lockingScript *script.Script) (transaction.ScriptTemplate, error) { -// asm, err := lockingScript.ToASM() -// require.NoError(t, err) - -// unlocker, ok := map[string]*mockUnlocker{ -// "OP_2 OP_2 OP_SUB OP_EQUAL": {t: t, script: "OP_FALSE"}, -// "OP_2 OP_8 OP_MUL OP_EQUAL": {t: t, script: "OP_16"}, -// "OP_10 OP_5 OP_DIV OP_EQUAL": {t: t, script: "OP_2"}, -// }[asm] - -// require.True(t, ok) -// require.NotNil(t, unlocker) - -// return unlocker, nil -// }, -// expUnlockingScripts: []string{"OP_FALSE", "OP_16", "OP_2"}, -// }, -// } - -// for name, test := range tests { -// t.Run(name, func(t *testing.T) { -// tx := test.tx -// require.Equal(t, len(tx.Inputs), len(test.expUnlockingScripts)) - -// ug := &mockUnlockerGetter{ -// t: t, -// unlockerFunc: test.unlockerFunc, -// } -// require.NoError(t, tx.FillAllInputs(context.Background(), ug)) -// for i, script := range test.expUnlockingScripts { -// asm, err := tx.Inputs[i].UnlockingScript.ToASM() -// require.NoError(t, err) - -// require.Equal(t, script, asm) -// } -// }) -// } -// } - -// -// func TestBareMultiSigValidation(t *testing.T) { -// txHex := "0100000001cfb38c76cadeb5b96c3863d9e298fe96e24e594b75f69c37aa709f45b76d1b25000000009200483045022100d83dc84d3ea3fb36b006f6887e1e16811c59fe9a9b79b84142874a90d5b834160220052967be98c26270de0082b0fecab5a40d5bc48d5034b6cdfc2b8e47210e1469414730440220099ffa89363f9a05f23a4fa318ddbefeeeec4b41f6abde7083a3be6696ed904902201722110a488df3780a260ba09b7de6363bfce7f6beec9819e9b9f47f6e978d8141ffffffff01a8840100000000001976a91432b996f742e774b0241be9007f831558ba06d20b88ac00000000" -// tx, err := transaction.NewTransactionFromHex(txHex) -// if err != nil { -// t.Error(err) -// return -// } -// -// // txid := tx.GetTxID() -// // fmt.Println(txid) -// -// var sigs = make([]*ec.Signature, 2) -// var sigHashTypes = make([]uint32, 2) -// var publicKeys = make([]*ec.PublicKey, 3) -// -// sigScript := tx.Inputs[0].UnlockingScript -// -// sig0Bytes := []byte(*sigScript)[2:73] -// sig0HashType, _ := binary.Uvarint([]byte(*sigScript)[73:74]) -// sig1Bytes := []byte(*sigScript)[75:145] -// sig1HashType, _ := binary.Uvarint([]byte(*sigScript)[145:146]) -// -// pk0, _ := hex.DecodeString("023ff15e2676e03b2c0af30fc17b7fb354bbfa9f549812da945194d3407dc0969b") -// pk1, _ := hex.DecodeString("039281958c651c013f5b3b007c78be231eeb37f130b925ceff63dc3ac8886f22a3") -// pk2, _ := hex.DecodeString("03ac76121ffc9db556b0ce1da978021bd6cb4a5f9553c14f785e15f0e202139e3e") -// -// publicKeys[0], err = ec.ParsePubKey(pk0, ec.S256()) -// if err != nil { -// t.Error(err) -// return -// } -// publicKeys[1], err = ec.ParsePubKey(pk1, ec.S256()) -// if err != nil { -// t.Error(err) -// return -// } -// publicKeys[2], err = ec.ParsePubKey(pk2, ec.S256()) -// if err != nil { -// t.Error(err) -// return -// } -// -// sigs[0], err = ec.ParseDERSignature(sig0Bytes, ec.S256()) -// if err != nil { -// t.Error(err) -// return -// } -// sigs[1], err = ec.ParseDERSignature(sig1Bytes, ec.S256()) -// if err != nil { -// t.Error(err) -// return -// } -// sigHashTypes[0] = uint32(sig0HashType) -// sigHashTypes[1] = uint32(sig1HashType) -// -// var previousTxSatoshis uint64 = 99728 -// var SourceTxScript, _ = script.NewFromHex("5221023ff15e2676e03b2c0af30fc17b7fb354bbfa9f549812da945194d3407dc0969b21039281958c651c013f5b3b007c78be231eeb37f130b925ceff63dc3ac8886f22a32103ac76121ffc9db556b0ce1da978021bd6cb4a5f9553c14f785e15f0e202139e3e53ae") -// var prevIndex uint32 -// var outIndex uint32 -// -// for i, sig := range sigs { -// sighash := signature.GetSighashForInputValidation(tx, sigHashTypes[i], outIndex, prevIndex, previousTxSatoshis, SourceTxScript) -// h, err := hex.DecodeString(sighash) -// if err != nil { -// t.Error(err) -// return -// } -// for j, pk := range publicKeys { -// valid := sig.Verify(util.ReverseBytes(h), pk) -// t.Logf("signature %d against pulbic key %d => %v\n", i, j, valid) -// } -// -// } -// -// } -// -// func TestP2SHMultiSigValidation(t *testing.T) { // NOT working properly! -// txHex := "0100000001d0219010e1f74ec8dd264a63ef01b5c72aab49a74c9bffd464c7f7f2b193b34700000000fdfd0000483045022100c2ffae14c7cfae5c1b45776f4b2d497b0d10a9e3be55b1386c555f90acd022af022025d5d1d33429fabd60c41763f9cda5c4b64adbddbd90023febc005be431b97b641473044022013f65e41abd6be856e7c7dd7527edc65231e027c42e8db7358759fc9ccd77b7d02206e024137ee54d2fac9f1dce858a85cb03fb7ba93b8e015d82e8a959b631f91ac414c695221021db57ae3de17143cb6c314fb206b56956e8ed45e2f1cbad3947411228b8d17f1210308b00cf7dfbb64604475e8b18e8450ac6ec04655cfa5c6d4d8a0f3f141ee419421030c7f9342ff6583599db8ee8b52383cadb4cf6fee3650c1ad8f66158a4ff0ebd953aefeffffff01b70f0000000000001976a91415067448220971206e6b4d90733d70fe9610631688ac56750900" -// tx, err := transaction.NewTransactionFromHex(txHex) -// if err != nil { -// t.Error(err) -// return -// } -// -// // txid := tx.GetTxID() -// // fmt.Println(txid) -// -// var sigs = make([]*ec.Signature, 2) -// var sigHashTypes = make([]uint32, 2) -// var publicKeys = make([]*ec.PublicKey, 3) -// -// sigScript := tx.Inputs[0].UnlockingScript -// -// sig0Bytes := []byte(*sigScript)[2:73] -// sig0HashType, _ := binary.Uvarint([]byte(*sigScript)[73:74]) -// sig1Bytes := []byte(*sigScript)[75:145] -// sig1HashType, _ := binary.Uvarint([]byte(*sigScript)[145:146]) -// -// pk0, _ := hex.DecodeString("021db57ae3de17143cb6c314fb206b56956e8ed45e2f1cbad3947411228b8d17f1") -// pk1, _ := hex.DecodeString("0308b00cf7dfbb64604475e8b18e8450ac6ec04655cfa5c6d4d8a0f3f141ee4194") -// pk2, _ := hex.DecodeString("030c7f9342ff6583599db8ee8b52383cadb4cf6fee3650c1ad8f66158a4ff0ebd9") -// -// publicKeys[0], err = ec.ParsePubKey(pk0, ec.S256()) -// if err != nil { -// t.Error(err) -// return -// } -// publicKeys[1], err = ec.ParsePubKey(pk1, ec.S256()) -// if err != nil { -// t.Error(err) -// return -// } -// publicKeys[2], err = ec.ParsePubKey(pk2, ec.S256()) -// if err != nil { -// t.Error(err) -// return -// } -// -// sigs[0], err = ec.ParseDERSignature(sig0Bytes, ec.S256()) -// if err != nil { -// t.Error(err) -// return -// } -// sigs[1], err = ec.ParseDERSignature(sig1Bytes, ec.S256()) -// if err != nil { -// t.Error(err) -// return -// } -// sigHashTypes[0] = uint32(sig0HashType) -// sigHashTypes[1] = uint32(sig1HashType) -// -// var previousTxSatoshis uint64 = 8785040 -// var SourceTxScript, _ = script.NewFromHex("5221021db57ae3de17143cb6c314fb206b56956e8ed45e2f1cbad3947411228b8d17f1210308b00cf7dfbb64604475e8b18e8450ac6ec04655cfa5c6d4d8a0f3f141ee419421030c7f9342ff6583599db8ee8b52383cadb4cf6fee3650c1ad8f66158a4ff0ebd953ae") -// var prevIndex uint32 = 1 -// var outIndex uint32 = 0 -// -// for i, sig := range sigs { -// sighash := signature.GetSighashForInputValidation(tx, sigHashTypes[i], outIndex, prevIndex, previousTxSatoshis, SourceTxScript) -// h, err := hex.DecodeString(sighash) -// if err != nil { -// t.Error(err) -// return -// } -// for j, pk := range publicKeys { -// valid := sig.Verify(util.ReverseBytes(h), pk) -// t.Logf("signature %d against pulbic key %d => %v\n", i, j, valid) -// } -// -// } -// -// }