Skip to content

Commit

Permalink
add some txscript support for parsing taproot scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
buck54321 committed Nov 21, 2021
1 parent 890bab9 commit 3316b84
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 20 deletions.
21 changes: 3 additions & 18 deletions txscript/pkscript.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,26 +239,11 @@ func computeNonWitnessPkScript(sigScript []byte) (PkScript, error) {

// computeWitnessPkScript computes the script of an output by looking at the
// spending input's witness.
// IMPORTANT: With the addition of taproot, we can no longer say for certain
// what kind of script the witness is in most cases. The only case in which we
// can say for sure is when the witness data has an annex as the last push. In
// that case, we can identify the script type, but we lack the ability to
// reconstruct the script itself.
// IMPORTANT: With the addition of taproot, we can not say for certain
// what kind of script the witness is.
func computeWitnessPkScript(witness wire.TxWitness) (PkScript, error) {
var pkScript PkScript
switch {
// If the last push starts with the annex flag, this is a taproot spend.
// We can set the script class, but we can't say what the pubkey script
// looks like with just the witness data.
case isAnnexedWitness(witness):
pkScript.class = WitnessV1TaprootTy

// For any other witnesses, we can't say for certain what type it is or what
// the pubkey script will be.
default:
pkScript.class = WitnessUnknownTy
}

pkScript.class = WitnessUnknownTy
return pkScript, nil
}

Expand Down
9 changes: 9 additions & 0 deletions txscript/standard.go
Original file line number Diff line number Diff line change
Expand Up @@ -1007,6 +1007,15 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script
return WitnessV0ScriptHashTy, addrs, 1, nil
}

if hash := extractWitnessV1ScriptHash(pkScript); hash != nil {
var addrs []btcutil.Address
addr, err := btcutil.NewAddressTaproot(hash, chainParams)
if err == nil {
addrs = append(addrs, addr)
}
return WitnessV1TaprootTy, addrs, 1, nil
}

// case WitnessV1TaprootTy:
// requiredSigs = 1
// addr, err := btcutil.NewAddressTaproot(pops[1].data,
Expand Down
25 changes: 23 additions & 2 deletions txscript/standard_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,20 @@ func newAddressScriptHash(scriptHash []byte) btcutil.Address {
return addr
}

// newAddressTaproot returns a new btcutil.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)
if err != nil {
panic("invalid script hash in test source")
}

return addr
}

// TestExtractPkScriptAddrs ensures that extracting the type, addresses, and
// number of required signatures from PkScripts works as intended.
func TestExtractPkScriptAddrs(t *testing.T) {
Expand Down Expand Up @@ -311,8 +325,15 @@ func TestExtractPkScriptAddrs(t *testing.T) {
reqSigs: 1,
class: MultiSigTy,
},
// from real tx: 691dd277dc0e90a462a3d652a1171686de49cf19067cd33c7df0392833fb986a, vout 44
// invalid public keys
{
name: "v1 p2tr witness-script-hash",
script: hexToBytes("51201a82f7457a9ba6ab1074e9f50" +
"053eefc637f8b046e389b636766bdc7d1f676f8"),
addrs: []btcutil.Address{newAddressTaproot(
hexToBytes("1a82f7457a9ba6ab1074e9f50053eefc637f8b046e389b636766bdc7d1f676f8"))},
reqSigs: 1,
class: WitnessV1TaprootTy,
},
{
name: "1 of 3 multisig with invalid pubkeys 2",
script: hexToBytes("514134633365633235396337346461636" +
Expand Down

0 comments on commit 3316b84

Please sign in to comment.