txscript: turn into own module, use v2

This commit is contained in:
Oliver Gugger 2023-12-19 14:12:48 +01:00 committed by Olaoluwa Osuntokun
parent 3000c455f8
commit 55a463a35f
26 changed files with 379 additions and 304 deletions

View file

@ -21,7 +21,7 @@ can be found at https://en.bitcoin.it/wiki/Script
## Installation and Updating
```bash
$ go get -u github.com/btcsuite/btcd/txscript
$ go get -u github.com/btcsuite/btcd/txscript/v2
```
## Examples

View file

@ -10,8 +10,8 @@ import (
"os"
"testing"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcd/chaincfg/v2"
"github.com/btcsuite/btcd/wire/v2"
)
var (

View file

@ -13,8 +13,8 @@ import (
"strings"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcd/chainhash/v2"
"github.com/btcsuite/btcd/wire/v2"
)
// ScriptFlags is a bitmask defining additional operations or tests that will be

View file

@ -9,7 +9,7 @@ import (
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/schnorr"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcd/wire/v2"
"github.com/stretchr/testify/require"
)

View file

@ -9,8 +9,8 @@ import (
"crypto/sha256"
"testing"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcd/chainhash/v2"
"github.com/btcsuite/btcd/wire/v2"
)
// TestBadPC sets the pc to a deliberately bad result then confirms that Step

View file

@ -9,12 +9,12 @@ import (
"encoding/hex"
"fmt"
"github.com/btcsuite/btcd/address/v2"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcd/chaincfg/v2"
"github.com/btcsuite/btcd/chainhash/v2"
"github.com/btcsuite/btcd/txscript/v2"
"github.com/btcsuite/btcd/wire/v2"
)
// This example demonstrates creating a script which pays to a bitcoin address.
@ -26,14 +26,14 @@ func ExamplePayToAddrScript() {
// the address type. It is also required for the upcoming call to
// PayToAddrScript.
addressStr := "12gpXQVcCL2qhTNQgyLVdCFG2Qs2px98nV"
address, err := btcutil.DecodeAddress(addressStr, &chaincfg.MainNetParams)
addr, err := address.DecodeAddress(addressStr, &chaincfg.MainNetParams)
if err != nil {
fmt.Println(err)
return
}
// Create a public key script that pays to the address.
script, err := txscript.PayToAddrScript(address)
script, err := txscript.PayToAddrScript(addr)
if err != nil {
fmt.Println(err)
return
@ -91,8 +91,8 @@ func ExampleSignTxOutput() {
return
}
privKey, pubKey := btcec.PrivKeyFromBytes(privKeyBytes)
pubKeyHash := btcutil.Hash160(pubKey.SerializeCompressed())
addr, err := btcutil.NewAddressPubKeyHash(pubKeyHash,
pubKeyHash := address.Hash160(pubKey.SerializeCompressed())
addr, err := address.NewAddressPubKeyHash(pubKeyHash,
&chaincfg.MainNetParams)
if err != nil {
fmt.Println(err)
@ -131,7 +131,7 @@ func ExampleSignTxOutput() {
redeemTx.AddTxOut(txOut)
// Sign the redeeming transaction.
lookupKey := func(a btcutil.Address) (*btcec.PrivateKey, bool, error) {
lookupKey := func(a address.Address) (*btcec.PrivateKey, bool, error) {
// Ordinarily this function would involve looking up the private
// key for the provided address, but since the only thing being
// signed in this example uses the address associated with the
@ -187,7 +187,7 @@ func ExampleSignTxOutput() {
func ExampleScriptTokenizer() {
// Create a script to use in the example. Ordinarily this would come from
// some other source.
hash160 := btcutil.Hash160([]byte("example"))
hash160 := address.Hash160([]byte("example"))
script, err := txscript.NewScriptBuilder().AddOp(txscript.OP_DUP).
AddOp(txscript.OP_HASH160).AddData(hash160).
AddOp(txscript.OP_EQUALVERIFY).AddOp(txscript.OP_CHECKSIG).Script()

38
txscript/go.mod Normal file
View file

@ -0,0 +1,38 @@
module github.com/btcsuite/btcd/txscript/v2
go 1.23.2
require (
github.com/btcsuite/btcd/address/v2 v2.0.0
github.com/btcsuite/btcd/btcec/v2 v2.3.2
github.com/btcsuite/btcd/chaincfg/v2 v2.0.0
github.com/btcsuite/btcd/chainhash/v2 v2.0.0
github.com/btcsuite/btcd/wire/v2 v2.0.0
github.com/btcsuite/btclog v1.0.0
github.com/davecgh/go-spew v1.1.1
github.com/stretchr/testify v1.10.0
golang.org/x/crypto v0.40.0
)
require (
github.com/decred/dcrd/crypto/blake256 v1.1.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/sys v0.35.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
// TODO(guggero): Remove this as soon as we have a tagged version of address.
replace github.com/btcsuite/btcd/address/v2 => ../address
// TODO(guggero): Remove this as soon as we have a tagged version of btcec.
replace github.com/btcsuite/btcd/btcec/v2 => ../btcec
// TODO(guggero): Remove this as soon as we have a tagged version of chaincfg.
replace github.com/btcsuite/btcd/chaincfg/v2 => ../chaincfg
// TODO(guggero): Remove this as soon as we have a tagged version of chainhash.
replace github.com/btcsuite/btcd/chainhash/v2 => ../chainhash
// TODO(guggero): Remove this as soon as we have a tagged version of wire.
replace github.com/btcsuite/btcd/wire/v2 => ../wire

20
txscript/go.sum Normal file
View file

@ -0,0 +1,20 @@
github.com/btcsuite/btclog v1.0.0 h1:sEkpKJMmfGiyZjADwEIgB1NSwMyfdD1FB8v6+w1T0Ns=
github.com/btcsuite/btclog v1.0.0/go.mod h1:w7xnGOhwT3lmrS4H3b/D1XAXxvh+tbhUm8xeHN2y3TQ=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U0x++OzVrdms8=
github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View file

@ -11,8 +11,8 @@ import (
"math"
"sync"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcd/chainhash/v2"
"github.com/btcsuite/btcd/wire/v2"
)
// calcHashPrevOuts calculates a single hash of all the previous outputs

View file

@ -9,7 +9,7 @@ import (
"testing"
"time"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcd/wire/v2"
"github.com/davecgh/go-spew/spew"
)

View file

@ -14,12 +14,11 @@ import (
"hash"
"strings"
"golang.org/x/crypto/ripemd160"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcd/chainhash/v2"
"github.com/btcsuite/btcd/wire/v2"
"golang.org/x/crypto/ripemd160"
)
// An opcode defines the information related to a txscript opcode. opfunc, if

View file

@ -5,11 +5,11 @@ import (
"errors"
"fmt"
"github.com/btcsuite/btcd/address/v2"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcd/chaincfg/v2"
"github.com/btcsuite/btcd/wire/v2"
"golang.org/x/crypto/ripemd160"
)
@ -156,7 +156,7 @@ func (s PkScript) Script() []byte {
}
// Address encodes the script into an address for the given chain.
func (s PkScript) Address(chainParams *chaincfg.Params) (btcutil.Address, error) {
func (s PkScript) Address(chainParams *chaincfg.Params) (address.Address, error) {
_, addrs, _, err := ExtractPkScriptAddrs(s.Script(), chainParams)
if err != nil {
return nil, fmt.Errorf("unable to parse address: %v", err)

View file

@ -4,7 +4,7 @@ import (
"bytes"
"testing"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcd/wire/v2"
)
// TestParsePkScript ensures that the supported script types can be parsed

View file

@ -11,15 +11,15 @@ import (
"errors"
"fmt"
"io/fs"
"math"
"os"
"path/filepath"
"strconv"
"strings"
"testing"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcd/chainhash/v2"
"github.com/btcsuite/btcd/wire/v2"
)
const (
@ -294,12 +294,14 @@ func parseTxInvalidTestFlags(flagStr string) (ScriptFlags, bool, error) {
return flags, badTx, nil
}
// maxSatoshi mirrors btcutil.MaxSatoshi so checkTxSanity can validate output
// ranges without importing btcutil and creating an import cycle.
const maxSatoshi = 21e6 * 1e8
// checkTxSanity performs the subset of context-free transaction checks needed
// by the tx_invalid BADTX vectors without importing blockchain and creating an
// import cycle from txscript tests.
func checkTxSanity(tx *btcutil.Tx) error {
msgTx := tx.MsgTx()
func checkTxSanity(msgTx *wire.MsgTx) error {
if len(msgTx.TxIn) == 0 {
return errors.New("transaction has no inputs")
}
@ -316,12 +318,12 @@ func checkTxSanity(tx *btcutil.Tx) error {
if satoshi < 0 {
return errors.New("negative output value")
}
if satoshi > btcutil.MaxSatoshi {
if satoshi > maxSatoshi {
return errors.New("output exceeds max satoshi")
}
totalSatoshi += satoshi
if totalSatoshi < 0 || totalSatoshi > btcutil.MaxSatoshi {
if totalSatoshi < 0 || totalSatoshi > maxSatoshi {
return errors.New("total output exceeds max satoshi")
}
}
@ -334,7 +336,7 @@ func checkTxSanity(tx *btcutil.Tx) error {
seen[txIn.PreviousOutPoint] = struct{}{}
}
if isCoinBaseTx(tx) {
if isCoinBaseTx(msgTx) {
slen := len(msgTx.TxIn[0].SignatureScript)
if slen < 2 || slen > 100 {
return errors.New("coinbase script length out of range")
@ -351,8 +353,7 @@ func checkTxSanity(tx *btcutil.Tx) error {
return nil
}
func isCoinBaseTx(tx *btcutil.Tx) bool {
msgTx := tx.MsgTx()
func isCoinBaseTx(msgTx *wire.MsgTx) bool {
if len(msgTx.TxIn) != 1 {
return false
}
@ -377,7 +378,7 @@ func TestCheckTxSanityTooBig(t *testing.T) {
))
tx.AddTxOut(wire.NewTxOut(0, nil))
if err := checkTxSanity(btcutil.NewTx(tx)); err == nil {
if err := checkTxSanity(tx); err == nil {
t.Fatal("expected oversized transaction to fail sanity checks")
}
}
@ -563,7 +564,7 @@ func testScripts(t *testing.T, tests [][]interface{}, useSigCache bool) {
var (
witness wire.TxWitness
inputAmt btcutil.Amount
inputAmt int64
)
// When the first field of the test data is a slice it contains
@ -583,7 +584,7 @@ func testScripts(t *testing.T, tests [][]interface{}, useSigCache bool) {
continue
}
inputAmt, err = btcutil.NewAmount(
inputAmt, err = newAmount(
witnessData[len(witnessData)-1].(float64),
)
if err != nil {
@ -773,7 +774,7 @@ testloop:
continue
}
tx, err := btcutil.NewTxFromBytes(serializedTx)
tx, err := newTxFromBytes(serializedTx)
if err != nil {
t.Errorf("bad test (arg 2 not msgtx %v) %d: %v", err,
i, test)
@ -869,7 +870,7 @@ testloop:
})
}
for k, txin := range tx.MsgTx().TxIn {
for k, txin := range tx.TxIn {
prevOut := prevOutFetcher.FetchPrevOutput(
txin.PreviousOutPoint,
)
@ -881,7 +882,7 @@ testloop:
// These are meant to fail, so as soon as the first
// input fails the transaction has failed. (some of the
// test txns have good inputs, too..
vm, err := NewEngine(prevOut.PkScript, tx.MsgTx(), k,
vm, err := NewEngine(prevOut.PkScript, tx, k,
flags, nil, nil, prevOut.Value, prevOutFetcher)
if err != nil {
continue testloop
@ -939,7 +940,7 @@ testloop:
continue
}
tx, err := btcutil.NewTxFromBytes(serializedTx)
tx, err := newTxFromBytes(serializedTx)
if err != nil {
t.Errorf("bad test (arg 2 not msgtx %v) %d: %v", err,
i, test)
@ -1026,7 +1027,7 @@ testloop:
})
}
for k, txin := range tx.MsgTx().TxIn {
for k, txin := range tx.TxIn {
prevOut := prevOutFetcher.FetchPrevOutput(
txin.PreviousOutPoint,
)
@ -1035,7 +1036,7 @@ testloop:
k, i, test)
continue testloop
}
vm, err := NewEngine(prevOut.PkScript, tx.MsgTx(), k,
vm, err := NewEngine(prevOut.PkScript, tx, k,
flags, nil, nil, prevOut.Value, prevOutFetcher)
if err != nil {
t.Errorf("test (%d:%v:%d) failed to create "+
@ -1137,7 +1138,7 @@ func executeTaprootRefTest(t *testing.T, testCase taprootJsonTest) {
if err != nil {
t.Fatalf("unable to decode hex: %v", err)
}
tx, err := btcutil.NewTxFromBytes(txHex)
tx, err := newTxFromBytes(txHex)
if err != nil {
t.Fatalf("unable to decode hex: %v", err)
}
@ -1160,7 +1161,7 @@ func executeTaprootRefTest(t *testing.T, testCase taprootJsonTest) {
}
prevOutFetcher.AddPrevOut(
tx.MsgTx().TxIn[i].PreviousOutPoint, &txOut,
tx.TxIn[i].PreviousOutPoint, &txOut,
)
if i == testCase.Index {
@ -1174,10 +1175,10 @@ func executeTaprootRefTest(t *testing.T, testCase taprootJsonTest) {
}
makeVM := func() *Engine {
hashCache := NewTxSigHashes(tx.MsgTx(), prevOutFetcher)
hashCache := NewTxSigHashes(tx, prevOutFetcher)
vm, err := NewEngine(
prevOut.PkScript, tx.MsgTx(), testCase.Index,
prevOut.PkScript, tx, testCase.Index,
flags, nil, hashCache, prevOut.Value, prevOutFetcher,
)
if err != nil {
@ -1188,7 +1189,7 @@ func executeTaprootRefTest(t *testing.T, testCase taprootJsonTest) {
}
if testCase.Success != nil {
tx.MsgTx().TxIn[testCase.Index].SignatureScript, err = hex.DecodeString(
tx.TxIn[testCase.Index].SignatureScript, err = hex.DecodeString(
testCase.Success.ScriptSig,
)
if err != nil {
@ -1205,7 +1206,7 @@ func executeTaprootRefTest(t *testing.T, testCase taprootJsonTest) {
witness = append(witness, witElem)
}
tx.MsgTx().TxIn[testCase.Index].Witness = witness
tx.TxIn[testCase.Index].Witness = witness
vm := makeVM()
@ -1217,7 +1218,7 @@ func executeTaprootRefTest(t *testing.T, testCase taprootJsonTest) {
}
if testCase.Failure != nil {
tx.MsgTx().TxIn[testCase.Index].SignatureScript, err = hex.DecodeString(
tx.TxIn[testCase.Index].SignatureScript, err = hex.DecodeString(
testCase.Failure.ScriptSig,
)
if err != nil {
@ -1234,7 +1235,7 @@ func executeTaprootRefTest(t *testing.T, testCase taprootJsonTest) {
witness = append(witness, witElem)
}
tx.MsgTx().TxIn[testCase.Index].Witness = witness
tx.TxIn[testCase.Index].Witness = witness
vm := makeVM()
@ -1297,3 +1298,35 @@ func TestTaprootReferenceTests(t *testing.T) {
t.Fatalf("unable to execute taproot test vectors: %v", err)
}
}
func newAmount(f float64) (int64, error) {
// The amount is only considered invalid if it cannot be represented
// as an integer type. This may happen if f is NaN or +-Infinity.
switch {
case math.IsNaN(f):
fallthrough
case math.IsInf(f, 1):
fallthrough
case math.IsInf(f, -1):
return 0, errors.New("invalid bitcoin amount")
}
return round(f * 1e8), nil
}
func round(f float64) int64 {
if f < 0 {
return int64(f - 0.5)
}
return int64(f + 0.5)
}
func newTxFromBytes(txBytes []byte) (*wire.MsgTx, error) {
var msgTx wire.MsgTx
err := msgTx.Deserialize(bytes.NewReader(txBytes))
if err != nil {
return nil, err
}
return &msgTx, nil
}

View file

@ -11,7 +11,7 @@ import (
"strings"
"time"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcd/wire/v2"
)
// Bip16Activation is the timestamp where BIP0016 is valid to use in the

View file

@ -9,7 +9,7 @@ import (
"reflect"
"testing"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcd/wire/v2"
)
// TestPushedData ensured the PushedData function extracts the expected data out

View file

@ -8,7 +8,7 @@ import (
"bytes"
"sync"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/chainhash/v2"
)
// sigCacheEntry represents an entry in the SigCache. Entries within the

View file

@ -10,7 +10,7 @@ import (
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/chainhash/v2"
)
// genRandomSig returns a random message, a signature of the message under the

View file

@ -13,8 +13,8 @@ import (
"io"
"math"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcd/chainhash/v2"
"github.com/btcsuite/btcd/wire/v2"
)
// SigHashType represents hash type bits at the end of a signature.

View file

@ -7,13 +7,12 @@ package txscript
import (
"errors"
"github.com/btcsuite/btcd/address/v2"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/schnorr"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcd/btcec/v2/schnorr"
"github.com/btcsuite/btcd/chaincfg/v2"
"github.com/btcsuite/btcd/wire/v2"
)
// RawTxInWitnessSignature returns the serialized ECDA signature for the input
@ -225,7 +224,7 @@ func p2pkSignatureScript(tx *wire.MsgTx, idx int, subScript []byte, hashType Sig
// the contract (i.e. nrequired signatures are provided). Since it is arguably
// legal to not be able to sign any of the outputs, no error is returned.
func signMultiSig(tx *wire.MsgTx, idx int, subScript []byte, hashType SigHashType,
addresses []btcutil.Address, nRequired int, kdb KeyDB) ([]byte, bool) {
addresses []address.Address, nRequired int, kdb KeyDB) ([]byte, bool) {
// We start with a single OP_FALSE to work around the (now standard)
// but in the reference implementation that causes a spurious pop at
// the end of OP_CHECKMULTISIG.
@ -255,7 +254,7 @@ func signMultiSig(tx *wire.MsgTx, idx int, subScript []byte, hashType SigHashTyp
func sign(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int,
subScript []byte, hashType SigHashType, kdb KeyDB, sdb ScriptDB) ([]byte,
ScriptClass, []btcutil.Address, int, error) {
ScriptClass, []address.Address, int, error) {
class, addresses, nrequired, err := ExtractPkScriptAddrs(subScript,
chainParams)
@ -329,7 +328,7 @@ func sign(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int,
// NOTE: This function is only valid for version 0 scripts. Since the function
// does not accept a script version, the results are undefined for other script
// versions.
func mergeMultiSig(tx *wire.MsgTx, idx int, addresses []btcutil.Address,
func mergeMultiSig(tx *wire.MsgTx, idx int, addresses []address.Address,
nRequired int, pkScript, sigScript, prevScript []byte) []byte {
// Nothing to merge if either the new or previous signature scripts are
@ -398,7 +397,7 @@ sigLoop:
// All multisig addresses should be pubkey addresses
// it is an error to call this internal function with
// bad input.
pkaddr := addr.(*btcutil.AddressPubKey)
pkaddr := addr.(*address.AddressPubKey)
pubKey := pkaddr.PubKey()
@ -452,7 +451,7 @@ sigLoop:
// does not accept a script version, the results are undefined for other script
// versions.
func mergeScripts(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int,
pkScript []byte, class ScriptClass, addresses []btcutil.Address,
pkScript []byte, class ScriptClass, addresses []address.Address,
nRequired int, sigScript, prevScript []byte) []byte {
// TODO(oga) the scripthash and multisig paths here are overly
@ -519,28 +518,28 @@ func mergeScripts(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int,
// KeyDB is an interface type provided to SignTxOutput, it encapsulates
// any user state required to get the private keys for an address.
type KeyDB interface {
GetKey(btcutil.Address) (*btcec.PrivateKey, bool, error)
GetKey(address.Address) (*btcec.PrivateKey, bool, error)
}
// KeyClosure implements KeyDB with a closure.
type KeyClosure func(btcutil.Address) (*btcec.PrivateKey, bool, error)
type KeyClosure func(address.Address) (*btcec.PrivateKey, bool, error)
// GetKey implements KeyDB by returning the result of calling the closure.
func (kc KeyClosure) GetKey(address btcutil.Address) (*btcec.PrivateKey, bool, error) {
func (kc KeyClosure) GetKey(address address.Address) (*btcec.PrivateKey, bool, error) {
return kc(address)
}
// ScriptDB is an interface type provided to SignTxOutput, it encapsulates any
// user state required to get the scripts for an pay-to-script-hash address.
type ScriptDB interface {
GetScript(btcutil.Address) ([]byte, error)
GetScript(address.Address) ([]byte, error)
}
// ScriptClosure implements ScriptDB with a closure.
type ScriptClosure func(btcutil.Address) ([]byte, error)
type ScriptClosure func(address.Address) ([]byte, error)
// GetScript implements ScriptDB by returning the result of calling the closure.
func (sc ScriptClosure) GetScript(address btcutil.Address) ([]byte, error) {
func (sc ScriptClosure) GetScript(address address.Address) ([]byte, error) {
return sc(address)
}

View file

@ -9,12 +9,12 @@ import (
"fmt"
"testing"
"github.com/btcsuite/btcd/address/v2"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/schnorr"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcd/chaincfg/v2"
"github.com/btcsuite/btcd/chainhash/v2"
"github.com/btcsuite/btcd/wire/v2"
"github.com/stretchr/testify/require"
)
@ -25,12 +25,12 @@ type addressToKey struct {
func mkGetKey(keys map[string]addressToKey) KeyDB {
if keys == nil {
return KeyClosure(func(addr btcutil.Address) (*btcec.PrivateKey,
return KeyClosure(func(addr address.Address) (*btcec.PrivateKey,
bool, error) {
return nil, false, errors.New("nope")
})
}
return KeyClosure(func(addr btcutil.Address) (*btcec.PrivateKey,
return KeyClosure(func(addr address.Address) (*btcec.PrivateKey,
bool, error) {
a2k, ok := keys[addr.EncodeAddress()]
if !ok {
@ -42,11 +42,11 @@ func mkGetKey(keys map[string]addressToKey) KeyDB {
func mkGetScript(scripts map[string][]byte) ScriptDB {
if scripts == nil {
return ScriptClosure(func(addr btcutil.Address) ([]byte, error) {
return ScriptClosure(func(addr address.Address) ([]byte, error) {
return nil, errors.New("nope")
})
}
return ScriptClosure(func(addr btcutil.Address) ([]byte, error) {
return ScriptClosure(func(addr address.Address) ([]byte, error) {
script, ok := scripts[addr.EncodeAddress()]
if !ok {
return nil, errors.New("nope")
@ -153,8 +153,8 @@ func TestSignTxOutput(t *testing.T) {
}
pk := key.PubKey().SerializeUncompressed()
address, err := btcutil.NewAddressPubKeyHash(
btcutil.Hash160(pk), &chaincfg.TestNet3Params)
address, err := address.NewAddressPubKeyHash(
address.Hash160(pk), &chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
@ -189,8 +189,8 @@ func TestSignTxOutput(t *testing.T) {
}
pk := key.PubKey().SerializeUncompressed()
address, err := btcutil.NewAddressPubKeyHash(
btcutil.Hash160(pk), &chaincfg.TestNet3Params)
address, err := address.NewAddressPubKeyHash(
address.Hash160(pk), &chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
@ -249,8 +249,8 @@ func TestSignTxOutput(t *testing.T) {
}
pk := key.PubKey().SerializeCompressed()
address, err := btcutil.NewAddressPubKeyHash(
btcutil.Hash160(pk), &chaincfg.TestNet3Params)
address, err := address.NewAddressPubKeyHash(
address.Hash160(pk), &chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
@ -287,8 +287,8 @@ func TestSignTxOutput(t *testing.T) {
}
pk := key.PubKey().SerializeCompressed()
address, err := btcutil.NewAddressPubKeyHash(
btcutil.Hash160(pk), &chaincfg.TestNet3Params)
address, err := address.NewAddressPubKeyHash(
address.Hash160(pk), &chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
@ -348,7 +348,7 @@ func TestSignTxOutput(t *testing.T) {
}
pk := key.PubKey().SerializeUncompressed()
address, err := btcutil.NewAddressPubKey(pk,
address, err := address.NewAddressPubKey(pk,
&chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make address for %s: %v",
@ -386,7 +386,7 @@ func TestSignTxOutput(t *testing.T) {
}
pk := key.PubKey().SerializeUncompressed()
address, err := btcutil.NewAddressPubKey(pk,
address, err := address.NewAddressPubKey(pk,
&chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make address for %s: %v",
@ -446,7 +446,7 @@ func TestSignTxOutput(t *testing.T) {
}
pk := key.PubKey().SerializeCompressed()
address, err := btcutil.NewAddressPubKey(pk,
address, err := address.NewAddressPubKey(pk,
&chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make address for %s: %v",
@ -484,7 +484,7 @@ func TestSignTxOutput(t *testing.T) {
}
pk := key.PubKey().SerializeCompressed()
address, err := btcutil.NewAddressPubKey(pk,
address, err := address.NewAddressPubKey(pk,
&chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make address for %s: %v",
@ -545,22 +545,22 @@ func TestSignTxOutput(t *testing.T) {
}
pk := key.PubKey().SerializeUncompressed()
address, err := btcutil.NewAddressPubKeyHash(
btcutil.Hash160(pk), &chaincfg.TestNet3Params)
addr, err := address.NewAddressPubKeyHash(
address.Hash160(pk), &chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
break
}
pkScript, err := PayToAddrScript(address)
pkScript, err := PayToAddrScript(addr)
if err != nil {
t.Errorf("failed to make pkscript "+
"for %s: %v", msg, err)
break
}
scriptAddr, err := btcutil.NewAddressScriptHash(
scriptAddr, err := address.NewAddressScriptHash(
pkScript, &chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make p2sh addr for %s: %v",
@ -579,7 +579,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signAndCheck(msg, tx, i, inputAmounts[i],
scriptPkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {key, false},
addr.EncodeAddress(): {key, false},
}), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript,
}), nil); err != nil {
@ -601,22 +601,22 @@ func TestSignTxOutput(t *testing.T) {
}
pk := key.PubKey().SerializeUncompressed()
address, err := btcutil.NewAddressPubKeyHash(
btcutil.Hash160(pk), &chaincfg.TestNet3Params)
addr, err := address.NewAddressPubKeyHash(
address.Hash160(pk), &chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
break
}
pkScript, err := PayToAddrScript(address)
pkScript, err := PayToAddrScript(addr)
if err != nil {
t.Errorf("failed to make pkscript "+
"for %s: %v", msg, err)
break
}
scriptAddr, err := btcutil.NewAddressScriptHash(
scriptAddr, err := address.NewAddressScriptHash(
pkScript, &chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make p2sh addr for %s: %v",
@ -635,7 +635,7 @@ func TestSignTxOutput(t *testing.T) {
sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
tx, i, scriptPkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {key, false},
addr.EncodeAddress(): {key, false},
}), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript,
}), nil)
@ -650,7 +650,7 @@ func TestSignTxOutput(t *testing.T) {
sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
tx, i, scriptPkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {key, false},
addr.EncodeAddress(): {key, false},
}), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript,
}), nil)
@ -683,21 +683,21 @@ func TestSignTxOutput(t *testing.T) {
}
pk := key.PubKey().SerializeCompressed()
address, err := btcutil.NewAddressPubKeyHash(
btcutil.Hash160(pk), &chaincfg.TestNet3Params)
addr, err := address.NewAddressPubKeyHash(
address.Hash160(pk), &chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
break
}
pkScript, err := PayToAddrScript(address)
pkScript, err := PayToAddrScript(addr)
if err != nil {
t.Errorf("failed to make pkscript "+
"for %s: %v", msg, err)
}
scriptAddr, err := btcutil.NewAddressScriptHash(
scriptAddr, err := address.NewAddressScriptHash(
pkScript, &chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make p2sh addr for %s: %v",
@ -716,7 +716,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signAndCheck(msg, tx, i, inputAmounts[i],
scriptPkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {key, true},
addr.EncodeAddress(): {key, true},
}), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript,
}), nil); err != nil {
@ -739,21 +739,21 @@ func TestSignTxOutput(t *testing.T) {
}
pk := key.PubKey().SerializeCompressed()
address, err := btcutil.NewAddressPubKeyHash(
btcutil.Hash160(pk), &chaincfg.TestNet3Params)
addr, err := address.NewAddressPubKeyHash(
address.Hash160(pk), &chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make address for %s: %v",
msg, err)
break
}
pkScript, err := PayToAddrScript(address)
pkScript, err := PayToAddrScript(addr)
if err != nil {
t.Errorf("failed to make pkscript "+
"for %s: %v", msg, err)
}
scriptAddr, err := btcutil.NewAddressScriptHash(
scriptAddr, err := address.NewAddressScriptHash(
pkScript, &chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make p2sh addr for %s: %v",
@ -772,7 +772,7 @@ func TestSignTxOutput(t *testing.T) {
sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
tx, i, scriptPkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {key, true},
addr.EncodeAddress(): {key, true},
}), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript,
}), nil)
@ -787,7 +787,7 @@ func TestSignTxOutput(t *testing.T) {
sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
tx, i, scriptPkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {key, true},
addr.EncodeAddress(): {key, true},
}), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript,
}), nil)
@ -820,7 +820,7 @@ func TestSignTxOutput(t *testing.T) {
}
pk := key.PubKey().SerializeUncompressed()
address, err := btcutil.NewAddressPubKey(pk,
addr, err := address.NewAddressPubKey(pk,
&chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make address for %s: %v",
@ -828,13 +828,13 @@ func TestSignTxOutput(t *testing.T) {
break
}
pkScript, err := PayToAddrScript(address)
pkScript, err := PayToAddrScript(addr)
if err != nil {
t.Errorf("failed to make pkscript "+
"for %s: %v", msg, err)
}
scriptAddr, err := btcutil.NewAddressScriptHash(
scriptAddr, err := address.NewAddressScriptHash(
pkScript, &chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make p2sh addr for %s: %v",
@ -853,7 +853,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signAndCheck(msg, tx, i, inputAmounts[i],
scriptPkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {key, false},
addr.EncodeAddress(): {key, false},
}), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript,
}), nil); err != nil {
@ -876,7 +876,7 @@ func TestSignTxOutput(t *testing.T) {
}
pk := key.PubKey().SerializeUncompressed()
address, err := btcutil.NewAddressPubKey(pk,
addr, err := address.NewAddressPubKey(pk,
&chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make address for %s: %v",
@ -884,13 +884,13 @@ func TestSignTxOutput(t *testing.T) {
break
}
pkScript, err := PayToAddrScript(address)
pkScript, err := PayToAddrScript(addr)
if err != nil {
t.Errorf("failed to make pkscript "+
"for %s: %v", msg, err)
}
scriptAddr, err := btcutil.NewAddressScriptHash(
scriptAddr, err := address.NewAddressScriptHash(
pkScript, &chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make p2sh addr for %s: %v",
@ -908,7 +908,7 @@ func TestSignTxOutput(t *testing.T) {
sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
tx, i, scriptPkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {key, false},
addr.EncodeAddress(): {key, false},
}), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript,
}), nil)
@ -923,7 +923,7 @@ func TestSignTxOutput(t *testing.T) {
sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
tx, i, scriptPkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {key, false},
addr.EncodeAddress(): {key, false},
}), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript,
}), nil)
@ -956,7 +956,7 @@ func TestSignTxOutput(t *testing.T) {
}
pk := key.PubKey().SerializeCompressed()
address, err := btcutil.NewAddressPubKey(pk,
addr, err := address.NewAddressPubKey(pk,
&chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make address for %s: %v",
@ -964,13 +964,13 @@ func TestSignTxOutput(t *testing.T) {
break
}
pkScript, err := PayToAddrScript(address)
pkScript, err := PayToAddrScript(addr)
if err != nil {
t.Errorf("failed to make pkscript "+
"for %s: %v", msg, err)
}
scriptAddr, err := btcutil.NewAddressScriptHash(
scriptAddr, err := address.NewAddressScriptHash(
pkScript, &chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make p2sh addr for %s: %v",
@ -988,7 +988,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signAndCheck(msg, tx, i, inputAmounts[i],
scriptPkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {key, true},
addr.EncodeAddress(): {key, true},
}), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript,
}), nil); err != nil {
@ -1011,7 +1011,7 @@ func TestSignTxOutput(t *testing.T) {
}
pk := key.PubKey().SerializeCompressed()
address, err := btcutil.NewAddressPubKey(pk,
addr, err := address.NewAddressPubKey(pk,
&chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make address for %s: %v",
@ -1019,13 +1019,13 @@ func TestSignTxOutput(t *testing.T) {
break
}
pkScript, err := PayToAddrScript(address)
pkScript, err := PayToAddrScript(addr)
if err != nil {
t.Errorf("failed to make pkscript "+
"for %s: %v", msg, err)
}
scriptAddr, err := btcutil.NewAddressScriptHash(
scriptAddr, err := address.NewAddressScriptHash(
pkScript, &chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make p2sh addr for %s: %v",
@ -1043,7 +1043,7 @@ func TestSignTxOutput(t *testing.T) {
sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
tx, i, scriptPkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {key, true},
addr.EncodeAddress(): {key, true},
}), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript,
}), nil)
@ -1058,7 +1058,7 @@ func TestSignTxOutput(t *testing.T) {
sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
tx, i, scriptPkScript, hashType,
mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {key, true},
addr.EncodeAddress(): {key, true},
}), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript,
}), nil)
@ -1091,7 +1091,7 @@ func TestSignTxOutput(t *testing.T) {
}
pk1 := key1.PubKey().SerializeCompressed()
address1, err := btcutil.NewAddressPubKey(pk1,
address1, err := address.NewAddressPubKey(pk1,
&chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make address for %s: %v",
@ -1107,7 +1107,7 @@ func TestSignTxOutput(t *testing.T) {
}
pk2 := key2.PubKey().SerializeCompressed()
address2, err := btcutil.NewAddressPubKey(pk2,
address2, err := address.NewAddressPubKey(pk2,
&chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make address 2 for %s: %v",
@ -1116,14 +1116,14 @@ func TestSignTxOutput(t *testing.T) {
}
pkScript, err := MultiSigScript(
[]*btcutil.AddressPubKey{address1, address2},
[]*address.AddressPubKey{address1, address2},
2)
if err != nil {
t.Errorf("failed to make pkscript "+
"for %s: %v", msg, err)
}
scriptAddr, err := btcutil.NewAddressScriptHash(
scriptAddr, err := address.NewAddressScriptHash(
pkScript, &chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make p2sh addr for %s: %v",
@ -1165,7 +1165,7 @@ func TestSignTxOutput(t *testing.T) {
}
pk1 := key1.PubKey().SerializeCompressed()
address1, err := btcutil.NewAddressPubKey(pk1,
address1, err := address.NewAddressPubKey(pk1,
&chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make address for %s: %v",
@ -1181,7 +1181,7 @@ func TestSignTxOutput(t *testing.T) {
}
pk2 := key2.PubKey().SerializeCompressed()
address2, err := btcutil.NewAddressPubKey(pk2,
address2, err := address.NewAddressPubKey(pk2,
&chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make address 2 for %s: %v",
@ -1190,14 +1190,14 @@ func TestSignTxOutput(t *testing.T) {
}
pkScript, err := MultiSigScript(
[]*btcutil.AddressPubKey{address1, address2},
[]*address.AddressPubKey{address1, address2},
2)
if err != nil {
t.Errorf("failed to make pkscript "+
"for %s: %v", msg, err)
}
scriptAddr, err := btcutil.NewAddressScriptHash(
scriptAddr, err := address.NewAddressScriptHash(
pkScript, &chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make p2sh addr for %s: %v",
@ -1269,7 +1269,7 @@ func TestSignTxOutput(t *testing.T) {
}
pk1 := key1.PubKey().SerializeCompressed()
address1, err := btcutil.NewAddressPubKey(pk1,
address1, err := address.NewAddressPubKey(pk1,
&chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make address for %s: %v",
@ -1285,7 +1285,7 @@ func TestSignTxOutput(t *testing.T) {
}
pk2 := key2.PubKey().SerializeCompressed()
address2, err := btcutil.NewAddressPubKey(pk2,
address2, err := address.NewAddressPubKey(pk2,
&chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make address 2 for %s: %v",
@ -1294,14 +1294,14 @@ func TestSignTxOutput(t *testing.T) {
}
pkScript, err := MultiSigScript(
[]*btcutil.AddressPubKey{address1, address2},
[]*address.AddressPubKey{address1, address2},
2)
if err != nil {
t.Errorf("failed to make pkscript "+
"for %s: %v", msg, err)
}
scriptAddr, err := btcutil.NewAddressScriptHash(
scriptAddr, err := address.NewAddressScriptHash(
pkScript, &chaincfg.TestNet3Params)
if err != nil {
t.Errorf("failed to make p2sh addr for %s: %v",

View file

@ -10,8 +10,8 @@ import (
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
"github.com/btcsuite/btcd/btcec/v2/schnorr"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcd/chainhash/v2"
"github.com/btcsuite/btcd/wire/v2"
)
// signatureVerifier is an abstract interface that allows the op code execution

View file

@ -8,9 +8,9 @@ import (
"bytes"
"fmt"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcd/address/v2"
"github.com/btcsuite/btcd/chaincfg/v2"
"github.com/btcsuite/btcd/wire/v2"
)
const (
@ -928,50 +928,50 @@ func payToPubKeyScript(serializedPubKey []byte) ([]byte, error) {
// PayToAddrScript creates a new script to pay a transaction output to a the
// specified address.
func PayToAddrScript(addr btcutil.Address) ([]byte, error) {
func PayToAddrScript(addr address.Address) ([]byte, error) {
const nilAddrErrStr = "unable to generate payment script for nil address"
switch addr := addr.(type) {
case *btcutil.AddressPubKeyHash:
case *address.AddressPubKeyHash:
if addr == nil {
return nil, scriptError(ErrUnsupportedAddress,
nilAddrErrStr)
}
return payToPubKeyHashScript(addr.ScriptAddress())
case *btcutil.AddressScriptHash:
case *address.AddressScriptHash:
if addr == nil {
return nil, scriptError(ErrUnsupportedAddress,
nilAddrErrStr)
}
return payToScriptHashScript(addr.ScriptAddress())
case *btcutil.AddressPubKey:
case *address.AddressPubKey:
if addr == nil {
return nil, scriptError(ErrUnsupportedAddress,
nilAddrErrStr)
}
return payToPubKeyScript(addr.ScriptAddress())
case *btcutil.AddressWitnessPubKeyHash:
case *address.AddressWitnessPubKeyHash:
if addr == nil {
return nil, scriptError(ErrUnsupportedAddress,
nilAddrErrStr)
}
return payToWitnessPubKeyHashScript(addr.ScriptAddress())
case *btcutil.AddressWitnessScriptHash:
case *address.AddressWitnessScriptHash:
if addr == nil {
return nil, scriptError(ErrUnsupportedAddress,
nilAddrErrStr)
}
return payToWitnessScriptHashScript(addr.ScriptAddress())
case *btcutil.AddressTaproot:
case *address.AddressTaproot:
if addr == nil {
return nil, scriptError(ErrUnsupportedAddress,
nilAddrErrStr)
}
return payToWitnessTaprootScript(addr.ScriptAddress())
case *btcutil.AddressPayToAnchor:
case *address.AddressPayToAnchor:
if addr == nil {
return nil, scriptError(ErrUnsupportedAddress,
nilAddrErrStr)
@ -1001,7 +1001,7 @@ func NullDataScript(data []byte) ([]byte, error) {
// nrequired of the keys in pubkeys are required to have signed the transaction
// for success. An Error with the error code ErrTooManyRequiredSigs will be
// returned if nrequired is larger than the number of keys provided.
func MultiSigScript(pubkeys []*btcutil.AddressPubKey, nrequired int) ([]byte, error) {
func MultiSigScript(pubkeys []*address.AddressPubKey, nrequired int) ([]byte, error) {
if len(pubkeys) < nrequired {
str := fmt.Sprintf("unable to generate multisig script with "+
"%d required signatures when there are only %d public "+
@ -1042,10 +1042,10 @@ func PushedData(script []byte) ([][]byte, error) {
// pubKeyHashToAddrs is a convenience function to attempt to convert the
// passed hash to a pay-to-pubkey-hash address housed within an address
// slice. It is used to consolidate common code.
func pubKeyHashToAddrs(hash []byte, params *chaincfg.Params) []btcutil.Address {
func pubKeyHashToAddrs(hash []byte, params *chaincfg.Params) []address.Address {
// Skip the pubkey hash if it's invalid for some reason.
var addrs []btcutil.Address
addr, err := btcutil.NewAddressPubKeyHash(hash, params)
var addrs []address.Address
addr, err := address.NewAddressPubKeyHash(hash, params)
if err == nil {
addrs = append(addrs, addr)
}
@ -1055,10 +1055,10 @@ func pubKeyHashToAddrs(hash []byte, params *chaincfg.Params) []btcutil.Address {
// scriptHashToAddrs is a convenience function to attempt to convert the passed
// hash to a pay-to-script-hash address housed within an address slice. It is
// used to consolidate common code.
func scriptHashToAddrs(hash []byte, params *chaincfg.Params) []btcutil.Address {
func scriptHashToAddrs(hash []byte, params *chaincfg.Params) []address.Address {
// Skip the hash if it's invalid for some reason.
var addrs []btcutil.Address
addr, err := btcutil.NewAddressScriptHashFromHash(hash, params)
var addrs []address.Address
addr, err := address.NewAddressScriptHashFromHash(hash, params)
if err == nil {
addrs = append(addrs, addr)
}
@ -1070,7 +1070,8 @@ func scriptHashToAddrs(hash []byte, params *chaincfg.Params) []btcutil.Address {
// 'standard' transaction script types. Any data such as public keys which are
// invalid are omitted from the results.
func ExtractPkScriptAddrs(pkScript []byte,
chainParams *chaincfg.Params) (ScriptClass, []btcutil.Address, int, error) {
chainParams *chaincfg.Params) (ScriptClass, []address.Address, int,
error) {
// Check for pay-to-pubkey-hash script.
if hash := extractPubKeyHash(pkScript); hash != nil {
@ -1084,8 +1085,8 @@ func ExtractPkScriptAddrs(pkScript []byte,
// Check for pay-to-pubkey script.
if data := extractPubKey(pkScript); data != nil {
var addrs []btcutil.Address
addr, err := btcutil.NewAddressPubKey(data, chainParams)
var addrs []address.Address
addr, err := address.NewAddressPubKey(data, chainParams)
if err == nil {
addrs = append(addrs, addr)
}
@ -1097,9 +1098,9 @@ func ExtractPkScriptAddrs(pkScript []byte,
details := extractMultisigScriptDetails(scriptVersion, pkScript, true)
if details.valid {
// Convert the public keys while skipping any that are invalid.
addrs := make([]btcutil.Address, 0, len(details.pubKeys))
addrs := make([]address.Address, 0, len(details.pubKeys))
for _, pubkey := range details.pubKeys {
addr, err := btcutil.NewAddressPubKey(pubkey, chainParams)
addr, err := address.NewAddressPubKey(pubkey, chainParams)
if err == nil {
addrs = append(addrs, addr)
}
@ -1118,8 +1119,8 @@ func ExtractPkScriptAddrs(pkScript []byte,
// P2A scripts have a single deterministic bech32 address per
// network (e.g. bc1pfeessrawgf on mainnet) and require no
// signatures (anyone can spend them).
var addrs []btcutil.Address
if addr, err := btcutil.NewAddressPayToAnchor(
var addrs []address.Address
if addr, err := address.NewAddressPayToAnchor(
chainParams,
); err == nil {
@ -1129,8 +1130,8 @@ func ExtractPkScriptAddrs(pkScript []byte,
}
if hash := extractWitnessPubKeyHash(pkScript); hash != nil {
var addrs []btcutil.Address
addr, err := btcutil.NewAddressWitnessPubKeyHash(hash, chainParams)
var addrs []address.Address
addr, err := address.NewAddressWitnessPubKeyHash(hash, chainParams)
if err == nil {
addrs = append(addrs, addr)
}
@ -1138,8 +1139,8 @@ func ExtractPkScriptAddrs(pkScript []byte,
}
if hash := extractWitnessV0ScriptHash(pkScript); hash != nil {
var addrs []btcutil.Address
addr, err := btcutil.NewAddressWitnessScriptHash(hash, chainParams)
var addrs []address.Address
addr, err := address.NewAddressWitnessScriptHash(hash, chainParams)
if err == nil {
addrs = append(addrs, addr)
}
@ -1147,8 +1148,8 @@ func ExtractPkScriptAddrs(pkScript []byte,
}
if rawKey := extractWitnessV1KeyBytes(pkScript); rawKey != nil {
var addrs []btcutil.Address
addr, err := btcutil.NewAddressTaproot(rawKey, chainParams)
var addrs []address.Address
addr, err := address.NewAddressTaproot(rawKey, chainParams)
if err == nil {
addrs = append(addrs, addr)
}

View file

@ -11,9 +11,9 @@ import (
"reflect"
"testing"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcd/address/v2"
"github.com/btcsuite/btcd/chaincfg/v2"
"github.com/btcsuite/btcd/wire/v2"
)
// mustParseShortForm parses the passed short form script and returns the
@ -30,12 +30,12 @@ func mustParseShortForm(script string) []byte {
return s
}
// newAddressPubKey returns a new btcutil.AddressPubKey from the provided
// newAddressPubKey returns a new address.AddressPubKey from the provided
// serialized public key. It panics if an error occurs. This is only used in
// the tests as a helper since the only way it can fail is if there is an error
// in the test source code.
func newAddressPubKey(serializedPubKey []byte) btcutil.Address {
addr, err := btcutil.NewAddressPubKey(serializedPubKey,
func newAddressPubKey(serializedPubKey []byte) address.Address {
addr, err := address.NewAddressPubKey(serializedPubKey,
&chaincfg.MainNetParams)
if err != nil {
panic("invalid public key in test source")
@ -44,12 +44,12 @@ func newAddressPubKey(serializedPubKey []byte) btcutil.Address {
return addr
}
// newAddressPubKeyHash returns a new btcutil.AddressPubKeyHash from the
// newAddressPubKeyHash returns a new address.AddressPubKeyHash from the
// provided hash. It panics if an error occurs. This is only used in the tests
// as a helper since the only way it can fail is if there is an error in the
// test source code.
func newAddressPubKeyHash(pkHash []byte) btcutil.Address {
addr, err := btcutil.NewAddressPubKeyHash(pkHash, &chaincfg.MainNetParams)
func newAddressPubKeyHash(pkHash []byte) address.Address {
addr, err := address.NewAddressPubKeyHash(pkHash, &chaincfg.MainNetParams)
if err != nil {
panic("invalid public key hash in test source")
}
@ -57,12 +57,12 @@ func newAddressPubKeyHash(pkHash []byte) btcutil.Address {
return addr
}
// newAddressScriptHash returns a new btcutil.AddressScriptHash from the
// newAddressScriptHash returns a new address.AddressScriptHash from the
// provided hash. It panics if an error occurs. This is only used in the tests
// as a helper since the only way it can fail is if there is an error in the
// test source code.
func newAddressScriptHash(scriptHash []byte) btcutil.Address {
addr, err := btcutil.NewAddressScriptHashFromHash(scriptHash,
func newAddressScriptHash(scriptHash []byte) address.Address {
addr, err := address.NewAddressScriptHashFromHash(scriptHash,
&chaincfg.MainNetParams)
if err != nil {
panic("invalid script hash in test source")
@ -71,13 +71,14 @@ func newAddressScriptHash(scriptHash []byte) btcutil.Address {
return addr
}
// newAddressTaproot returns a new btcutil.AddressTaproot from the
// newAddressTaproot returns a new address.AddressTaproot from the
// provided hash. It panics if an error occurs. This is only used in the tests
// as a helper since the only way it can fail is if there is an error in the
// test source code.
func newAddressTaproot(scriptHash []byte) btcutil.Address {
addr, err := btcutil.NewAddressTaproot(scriptHash,
&chaincfg.MainNetParams)
func newAddressTaproot(scriptHash []byte) address.Address {
addr, err := address.NewAddressTaproot(
scriptHash, &chaincfg.MainNetParams,
)
if err != nil {
panic("invalid script hash in test source")
}
@ -93,7 +94,7 @@ func TestExtractPkScriptAddrs(t *testing.T) {
tests := []struct {
name string
script []byte
addrs []btcutil.Address
addrs []address.Address
reqSigs int
class ScriptClass
}{
@ -101,7 +102,7 @@ func TestExtractPkScriptAddrs(t *testing.T) {
name: "standard p2pk with compressed pubkey (0x02)",
script: hexToBytes("2102192d74d0cb94344c9569c2e779015" +
"73d8d7903c3ebec3a957724895dca52c6b4ac"),
addrs: []btcutil.Address{
addrs: []address.Address{
newAddressPubKey(hexToBytes("02192d74d0cb9434" +
"4c9569c2e77901573d8d7903c3ebec3a9577" +
"24895dca52c6b4")),
@ -115,7 +116,7 @@ func TestExtractPkScriptAddrs(t *testing.T) {
"c1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddf" +
"b84ccf9744464f82e160bfa9b8b64f9d4c03f999b864" +
"3f656b412a3ac"),
addrs: []btcutil.Address{
addrs: []address.Address{
newAddressPubKey(hexToBytes("0411db93e1dcdb8a" +
"016b49840f8c53bc1eb68a382e97b1482eca" +
"d7b148a6909a5cb2e0eaddfb84ccf9744464" +
@ -131,7 +132,7 @@ func TestExtractPkScriptAddrs(t *testing.T) {
"73d8d7903c3ebec3a957724895dca52c6b40d4526483" +
"8c0bd96852662ce6a847b197376830160c6d2eb5e6a4" +
"c44d33f453eac"),
addrs: []btcutil.Address{
addrs: []address.Address{
newAddressPubKey(hexToBytes("06192d74d0cb9434" +
"4c9569c2e77901573d8d7903c3ebec3a9577" +
"24895dca52c6b40d45264838c0bd96852662" +
@ -145,7 +146,7 @@ func TestExtractPkScriptAddrs(t *testing.T) {
name: "standard p2pk with compressed pubkey (0x03)",
script: hexToBytes("2103b0bd634234abbb1ba1e986e884185" +
"c61cf43e001f9137f23c2c409273eb16e65ac"),
addrs: []btcutil.Address{
addrs: []address.Address{
newAddressPubKey(hexToBytes("03b0bd634234abbb" +
"1ba1e986e884185c61cf43e001f9137f23c2" +
"c409273eb16e65")),
@ -159,7 +160,7 @@ func TestExtractPkScriptAddrs(t *testing.T) {
"c61cf43e001f9137f23c2c409273eb16e6537a576782" +
"eba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3" +
"c1e0908ef7bac"),
addrs: []btcutil.Address{
addrs: []address.Address{
newAddressPubKey(hexToBytes("04b0bd634234abbb" +
"1ba1e986e884185c61cf43e001f9137f23c2" +
"c409273eb16e6537a576782eba668a7ef8bd" +
@ -175,7 +176,7 @@ func TestExtractPkScriptAddrs(t *testing.T) {
"c61cf43e001f9137f23c2c409273eb16e6537a576782" +
"eba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3" +
"c1e0908ef7bac"),
addrs: []btcutil.Address{
addrs: []address.Address{
newAddressPubKey(hexToBytes("07b0bd634234abbb" +
"1ba1e986e884185c61cf43e001f9137f23c2" +
"c409273eb16e6537a576782eba668a7ef8bd" +
@ -189,7 +190,7 @@ func TestExtractPkScriptAddrs(t *testing.T) {
name: "standard p2pkh",
script: hexToBytes("76a914ad06dd6ddee55cbca9a9e3713bd" +
"7587509a3056488ac"),
addrs: []btcutil.Address{
addrs: []address.Address{
newAddressPubKeyHash(hexToBytes("ad06dd6ddee5" +
"5cbca9a9e3713bd7587509a30564")),
},
@ -200,7 +201,7 @@ func TestExtractPkScriptAddrs(t *testing.T) {
name: "standard p2sh",
script: hexToBytes("a91463bcc565f9e68ee0189dd5cc67f1b" +
"0e5f02f45cb87"),
addrs: []btcutil.Address{
addrs: []address.Address{
newAddressScriptHash(hexToBytes("63bcc565f9e6" +
"8ee0189dd5cc67f1b0e5f02f45cb")),
},
@ -217,7 +218,7 @@ func TestExtractPkScriptAddrs(t *testing.T) {
"1354d80e550078cb532a34bfa2fcfdeb7d76519aecc6" +
"2770f5b0e4ef8551946d8a540911abe3e7854a26f39f" +
"58b25c15342af52ae"),
addrs: []btcutil.Address{
addrs: []address.Address{
newAddressPubKey(hexToBytes("04cc71eb30d653c0" +
"c3163990c47b976f3fb3f37cccdcbedb169a" +
"1dfef58bbfbfaff7d8a473e7e2e6d317b87b" +
@ -245,7 +246,7 @@ func TestExtractPkScriptAddrs(t *testing.T) {
"2bbf781c5410d3f22a7a3a56ffefb2238af8627363bd" +
"f2ed97c1f89784a1aecdb43384f11d2acc64443c7fc2" +
"99cef0400421a53ae"),
addrs: []btcutil.Address{
addrs: []address.Address{
newAddressPubKey(hexToBytes("04cb9c3c222c5f7a" +
"7d3b9bd152f363a0b6d54c9eb312c4d4f9af" +
"1e8551b6c421a6a4ab0e29105f24de20ff46" +
@ -321,7 +322,7 @@ func TestExtractPkScriptAddrs(t *testing.T) {
"16e20626520666f756e6420696e207472616e7361637" +
"4696f6e2036633533636439383731313965663739376" +
"435616463636453ae"),
addrs: []btcutil.Address{},
addrs: []address.Address{},
reqSigs: 1,
class: MultiSigTy,
},
@ -329,7 +330,7 @@ func TestExtractPkScriptAddrs(t *testing.T) {
name: "v1 p2tr witness-script-hash",
script: hexToBytes("51201a82f7457a9ba6ab1074e9f50" +
"053eefc637f8b046e389b636766bdc7d1f676f8"),
addrs: []btcutil.Address{newAddressTaproot(
addrs: []address.Address{newAddressTaproot(
hexToBytes("1a82f7457a9ba6ab1074e9f50053eefc6" +
"37f8b046e389b636766bdc7d1f676f8"))},
reqSigs: 1,
@ -345,7 +346,7 @@ func TestExtractPkScriptAddrs(t *testing.T) {
"13963663463303363363039633539336333653931666" +
"56465373032392131323364643432643235363339643" +
"338613663663530616234636434340a00000053ae"),
addrs: []btcutil.Address{},
addrs: []address.Address{},
reqSigs: 1,
class: MultiSigTy,
},
@ -587,29 +588,29 @@ func TestCalcScriptInfo(t *testing.T) {
}
}
// bogusAddress implements the btcutil.Address interface so the tests can ensure
// bogusAddress implements the address.Address interface so the tests can ensure
// unsupported address types are handled properly.
type bogusAddress struct{}
// EncodeAddress simply returns an empty string. It exists to satisfy the
// btcutil.Address interface.
// address.Address interface.
func (b *bogusAddress) EncodeAddress() string {
return ""
}
// ScriptAddress simply returns an empty byte slice. It exists to satisfy the
// btcutil.Address interface.
// address.Address interface.
func (b *bogusAddress) ScriptAddress() []byte {
return nil
}
// IsForNet lies blatantly to satisfy the btcutil.Address interface.
// IsForNet lies blatantly to satisfy the address.Address interface.
func (b *bogusAddress) IsForNet(chainParams *chaincfg.Params) bool {
return true // why not?
}
// String simply returns an empty string. It exists to satisfy the
// btcutil.Address interface.
// address.Address interface.
func (b *bogusAddress) String() string {
return ""
}
@ -620,7 +621,7 @@ func TestPayToAddrScript(t *testing.T) {
t.Parallel()
// 1MirQ9bwyQcGVJPwKUgapu5ouK2E2Ey4gX
p2pkhMain, err := btcutil.NewAddressPubKeyHash(hexToBytes("e34cce70c86"+
p2pkhMain, err := address.NewAddressPubKeyHash(hexToBytes("e34cce70c86"+
"373273efcc54ce7d2a491bb4a0e84"), &chaincfg.MainNetParams)
if err != nil {
t.Fatalf("Unable to create public key hash address: %v", err)
@ -628,21 +629,21 @@ func TestPayToAddrScript(t *testing.T) {
// Taken from transaction:
// b0539a45de13b3e0403909b8bd1a555b8cbe45fd4e3f3fda76f3a5f52835c29d
p2shMain, _ := btcutil.NewAddressScriptHashFromHash(hexToBytes("e8c300"+
p2shMain, _ := address.NewAddressScriptHashFromHash(hexToBytes("e8c300"+
"c87986efa84c37c0519929019ef86eb5b4"), &chaincfg.MainNetParams)
if err != nil {
t.Fatalf("Unable to create script hash address: %v", err)
}
// mainnet p2pk 13CG6SJ3yHUXo4Cr2RY4THLLJrNFuG3gUg
p2pkCompressedMain, err := btcutil.NewAddressPubKey(hexToBytes("02192d"+
p2pkCompressedMain, err := address.NewAddressPubKey(hexToBytes("02192d"+
"74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b4"),
&chaincfg.MainNetParams)
if err != nil {
t.Fatalf("Unable to create pubkey address (compressed): %v",
err)
}
p2pkCompressed2Main, err := btcutil.NewAddressPubKey(hexToBytes("03b0b"+
p2pkCompressed2Main, err := address.NewAddressPubKey(hexToBytes("03b0b"+
"d634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e65"),
&chaincfg.MainNetParams)
if err != nil {
@ -650,7 +651,7 @@ func TestPayToAddrScript(t *testing.T) {
err)
}
p2pkUncompressedMain, err := btcutil.NewAddressPubKey(hexToBytes("0411"+
p2pkUncompressedMain, err := address.NewAddressPubKey(hexToBytes("0411"+
"db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5"+
"cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b4"+
"12a3"), &chaincfg.MainNetParams)
@ -659,21 +660,21 @@ func TestPayToAddrScript(t *testing.T) {
err)
}
p2wsh, err := btcutil.NewAddressWitnessScriptHash(hexToBytes("e981bd992a43650657"+
p2wsh, err := address.NewAddressWitnessScriptHash(hexToBytes("e981bd992a43650657"+
"d705ef7a30b2adc75a927ed42a4cf6b3da0f865a475fb4"), &chaincfg.MainNetParams)
if err != nil {
t.Fatalf("Unable to create p2wsh address: %v",
err)
}
p2tr, err := btcutil.NewAddressTaproot(hexToBytes("3a8e170b546c3b122ab9c175e"+
p2tr, err := address.NewAddressTaproot(hexToBytes("3a8e170b546c3b122ab9c175e"+
"ff36fb344db2684fe96497eb51b440e75232709"), &chaincfg.MainNetParams)
if err != nil {
t.Fatalf("Unable to create p2tr address: %v",
err)
}
p2wpkh, err := btcutil.NewAddressWitnessPubKeyHash(hexToBytes("748e50366adb8"+
p2wpkh, err := address.NewAddressWitnessPubKeyHash(hexToBytes("748e50366adb8"+
"ae4b0255e406a28f99d24b73cbc"), &chaincfg.MainNetParams)
if err != nil {
t.Fatalf("Unable to create p2wpkh address: %v",
@ -685,7 +686,7 @@ func TestPayToAddrScript(t *testing.T) {
errUnsupportedAddress := scriptError(ErrUnsupportedAddress, "")
tests := []struct {
in btcutil.Address
in address.Address
expected string
err error
}{
@ -748,12 +749,12 @@ func TestPayToAddrScript(t *testing.T) {
},
// Supported address types with nil pointers.
{(*btcutil.AddressPubKeyHash)(nil), "", errUnsupportedAddress},
{(*btcutil.AddressScriptHash)(nil), "", errUnsupportedAddress},
{(*btcutil.AddressPubKey)(nil), "", errUnsupportedAddress},
{(*btcutil.AddressWitnessPubKeyHash)(nil), "", errUnsupportedAddress},
{(*btcutil.AddressWitnessScriptHash)(nil), "", errUnsupportedAddress},
{(*btcutil.AddressTaproot)(nil), "", errUnsupportedAddress},
{(*address.AddressPubKeyHash)(nil), "", errUnsupportedAddress},
{(*address.AddressScriptHash)(nil), "", errUnsupportedAddress},
{(*address.AddressPubKey)(nil), "", errUnsupportedAddress},
{(*address.AddressWitnessPubKeyHash)(nil), "", errUnsupportedAddress},
{(*address.AddressWitnessScriptHash)(nil), "", errUnsupportedAddress},
{(*address.AddressTaproot)(nil), "", errUnsupportedAddress},
// Unsupported address type.
{&bogusAddress{}, "", errUnsupportedAddress},
@ -783,14 +784,14 @@ func TestMultiSigScript(t *testing.T) {
t.Parallel()
// mainnet p2pk 13CG6SJ3yHUXo4Cr2RY4THLLJrNFuG3gUg
p2pkCompressedMain, err := btcutil.NewAddressPubKey(hexToBytes("02192d"+
p2pkCompressedMain, err := address.NewAddressPubKey(hexToBytes("02192d"+
"74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b4"),
&chaincfg.MainNetParams)
if err != nil {
t.Fatalf("Unable to create pubkey address (compressed): %v",
err)
}
p2pkCompressed2Main, err := btcutil.NewAddressPubKey(hexToBytes("03b0b"+
p2pkCompressed2Main, err := address.NewAddressPubKey(hexToBytes("03b0b"+
"d634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e65"),
&chaincfg.MainNetParams)
if err != nil {
@ -798,7 +799,7 @@ func TestMultiSigScript(t *testing.T) {
err)
}
p2pkUncompressedMain, err := btcutil.NewAddressPubKey(hexToBytes("0411"+
p2pkUncompressedMain, err := address.NewAddressPubKey(hexToBytes("0411"+
"db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5"+
"cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b4"+
"12a3"), &chaincfg.MainNetParams)
@ -808,13 +809,13 @@ func TestMultiSigScript(t *testing.T) {
}
tests := []struct {
keys []*btcutil.AddressPubKey
keys []*address.AddressPubKey
nrequired int
expected string
err error
}{
{
[]*btcutil.AddressPubKey{
[]*address.AddressPubKey{
p2pkCompressedMain,
p2pkCompressed2Main,
},
@ -826,7 +827,7 @@ func TestMultiSigScript(t *testing.T) {
nil,
},
{
[]*btcutil.AddressPubKey{
[]*address.AddressPubKey{
p2pkCompressedMain,
p2pkCompressed2Main,
},
@ -838,7 +839,7 @@ func TestMultiSigScript(t *testing.T) {
nil,
},
{
[]*btcutil.AddressPubKey{
[]*address.AddressPubKey{
p2pkCompressedMain,
p2pkCompressed2Main,
},
@ -847,7 +848,7 @@ func TestMultiSigScript(t *testing.T) {
scriptError(ErrTooManyRequiredSigs, ""),
},
{
[]*btcutil.AddressPubKey{
[]*address.AddressPubKey{
p2pkUncompressedMain,
},
1,
@ -858,7 +859,7 @@ func TestMultiSigScript(t *testing.T) {
nil,
},
{
[]*btcutil.AddressPubKey{
[]*address.AddressPubKey{
p2pkUncompressedMain,
},
2,

View file

@ -10,8 +10,8 @@ import (
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/schnorr"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcd/chainhash/v2"
"github.com/btcsuite/btcd/wire/v2"
secp "github.com/decred/dcrd/dcrec/secp256k1/v4"
)

View file

@ -6,43 +6,51 @@ package txscript
import (
"bytes"
"encoding/hex"
"fmt"
prand "math/rand"
"testing"
"testing/quick"
"github.com/btcsuite/btcd/address/v2"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/schnorr"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/btcutil/hdkeychain"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/chaincfg/v2"
secp "github.com/decred/dcrd/dcrec/secp256k1/v4"
"github.com/stretchr/testify/require"
)
var (
testPubBytes, _ = hex.DecodeString("F9308A019258C31049344F85F89D5229B" +
"531C845836F99B08601F113BCE036F9")
// rootKey is the test root key defined in the test vectors:
// privateKeys are four private keys derived from the seed mentioned in
// the BIP86 spec
// https://github.com/bitcoin/bips/blob/master/bip-0086.mediawiki
rootKey, _ = hdkeychain.NewKeyFromString(
"xprv9s21ZrQH143K3GJpoapnV8SFfukcVBSfeCficPSGfubmSFDxo1kuHnLi" +
"sriDvSnRRuL2Qrg5ggqHKNVpxR86QEC8w35uxmGoggxtQTPvfUu",
)
// accountPath is the base path for BIP86 (m/86'/0'/0').
accountPath = []uint32{
86 + hdkeychain.HardenedKeyStart, hdkeychain.HardenedKeyStart,
hdkeychain.HardenedKeyStart,
privateKeys = [][]byte{
// m/86'/0'/0'/0/0
hexToBytes(
"41f41d69260df4cf277826a9b65a3717e4eeddbeedf637f212ca" +
"096576479361",
),
// m/86'/0'/0'/0/1
hexToBytes(
"86c68ac0ed7df88cbdd08a847c6d639f87d1234d40503abf3ac1" +
"78ef7ddc05dd",
),
// m/86'/0'/0'/1/0
hexToBytes(
"6ccbca4a02ac648702dde463d9c1b0d328a4df1e068ef9dc2bc7" +
"88b33a4f0412",
),
// m/86'/0'/0'/1/1
hexToBytes(
"c8d522210e3bc028586dcb7cf7dce3937440ad8132765ecdfa2f" +
"f78d0e9a5d32",
),
}
expectedExternalAddresses = []string{
expectedAddresses = []string{
"bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr",
"bc1p4qhjn9zdvkux4e44uhx8tc55attvtyu358kutcqkudyccelu0was9fqzwh",
}
expectedInternalAddresses = []string{
"bc1p3qkhfews2uk44qtvauqyr2ttdsw7svhkl9nkm9s9c3x4ax5h60wqwruhk7",
"bc1ptdg60grjk9t3qqcqczp4tlyy3z47yrx9nhlrjsmw36q5a72lhdrs9f00nj",
}
)
@ -242,46 +250,22 @@ func TestTaprootTweakNoMutation(t *testing.T) {
// TestTaprootConstructKeyPath tests the key spend only taproot construction.
func TestTaprootConstructKeyPath(t *testing.T) {
checkPath := func(branch uint32, expectedAddresses []string) {
path, err := derivePath(rootKey, append(accountPath, branch))
t.Parallel()
for idx, key := range privateKeys {
key := key
_, pubKey := btcec.PrivKeyFromBytes(key)
tapKey := ComputeTaprootKeyNoScript(pubKey)
addr, err := address.NewAddressTaproot(
schnorr.SerializePubKey(tapKey),
&chaincfg.MainNetParams,
)
require.NoError(t, err)
for index, expectedAddr := range expectedAddresses {
extendedKey, err := path.Derive(uint32(index))
require.NoError(t, err)
pubKey, err := extendedKey.ECPubKey()
require.NoError(t, err)
tapKey := ComputeTaprootKeyNoScript(pubKey)
addr, err := btcutil.NewAddressTaproot(
schnorr.SerializePubKey(tapKey),
&chaincfg.MainNetParams,
)
require.NoError(t, err)
require.Equal(t, expectedAddr, addr.String())
}
require.Equal(t, expectedAddresses[idx], addr.String())
}
checkPath(0, expectedExternalAddresses)
checkPath(1, expectedInternalAddresses)
}
func derivePath(key *hdkeychain.ExtendedKey, path []uint32) (
*hdkeychain.ExtendedKey, error) {
var (
currentKey = key
err error
)
for _, pathPart := range path {
currentKey, err = currentKey.Derive(pathPart)
if err != nil {
return nil, err
}
}
return currentKey, nil
}
// TestTapscriptCommitmentVerification that given a valid control block, proof