8000 txscript: fix reconstruct bug for p2pkh by kcalvinalvin · Pull Request #139 · utreexo/utreexod · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

txscript: fix reconstruct bug for p2pkh #139

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions txscript/pkscript.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ import (
)

const (
// pubkeyUncompressed is the byte prepended to uncompressed pubkeys.
pubkeyUncompressed byte = 0x4 // x coord + y coord

// minPubKeyHashSigScriptLen is the minimum length of a signature script
// that spends a P2PKH output. The length is composed of the following:
// Signature length (1 byte)
Expand All @@ -36,6 +39,10 @@ const (
// key.
compressedPubKeyLen = 33

// uncompressedPubKeyLen is the length in bytes of a uncompressed public
// key.
uncompressedPubKeyLen = 65

// pubKeyHashLen is the length of a P2PKH script.
pubKeyHashLen = 25

Expand Down
28 changes: 17 additions & 11 deletions txscript/standard.go
Original file line number Diff line number Diff line change
Expand Up @@ -1171,22 +1171,28 @@ func ReconstructScript(sigScript []byte, witness wire.TxWitness, class ScriptCla
var script []byte
var err error

// A closure to check if a function is an uncompressed pubkey. If the length is right
// and the prepended byte is the byte for uncompressed pubkeys, we can safely assume that
// it's an uncompressed pubkey.
isUncompressedPubKey := func(pubKey []byte) bool {
return len(pubKey) == uncompressedPubKeyLen &&
(pubKey[0]&^byte(0x1) == pubkeyUncompressed)
}

switch class {
case PubKeyHashTy:
var data []byte

// Extract out the pubkey data.
var pubkeyData, data []byte
tokenizer := MakeScriptTokenizer(0, sigScript)
for tokenizer.Next() {
data = tokenizer.Data()

// If we found the key, break immediately. This prevents
// erroring out from OP_DUP OP_DROP opcodes that are appended
// to some redeem scripts.
if btcec.IsCompressedPubKey(data) {
break
if btcec.IsCompressedPubKey(data) || isUncompressedPubKey(data) {
pubkeyData = data
}
}
hash := btcutil.Hash160(data)

hash := btcutil.Hash160(pubkeyData)
script, err = payToPubKeyHashScript(hash)
if err != nil {
return nil, err
Expand Down Expand Up @@ -1218,14 +1224,14 @@ func ReconstructScript(sigScript []byte, witness wire.TxWitness, class ScriptCla
return nil, fmt.Errorf("unable to reconstruct script due to missing witness: %v", witness)
}
last := witness[len(witness)-1]
hash := chainhash.HashB(last)
hash := chainhash.HashH(last)

script, err = payToWitnessScriptHashScript(hash)
script, err = payToWitnessScriptHashScript(hash[:])
if err != nil {
return nil, err
}
default:
return nil, nil
return nil, fmt.Errorf("unsupported scriptclass %v", class.String())
}

return script, nil
Expand Down
41 changes: 41 additions & 0 deletions txscript/standard_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1325,6 +1325,47 @@ func TestReconstructScript(t *testing.T) {
class ScriptClass
expectErr bool
}{
{
// a44d40b3a14aca3f19ccf47244ef4a70ed02d00f5d840c38756368e9a7cc24b1:4 on testnet3
name: "uncompressed-p2pkh",
pkScript: "OP_DUP OP_HASH160 DATA_20 " +
"0x6b2044146a4438e6e5bfbc65f147afeb64d14fbb " +
"OP_EQUALVERIFY OP_CHECKSIG",
sigScript: "DATA_71 0x3044022075c0666d413fc85cca94ea2f24adc0fedb61a3ba0fcfb240" +
"c1a4fd2587b03bf90220525ad4d92c6bf635f8b97c188ebf491c6e342b767a5432f" +
"318cbb0245a7f64be01 DATA_65 0x04c4bee5e6dbb5c1651437cb4386c1515c7776" +
"c64535077204c6f24f05a37d04a32bc78beb2193b53b104c9954c44b0ce168bc78efd5f1e1c7db9d6c21b3016599",
class: PubKeyHashTy,
expectErr: false,
},
{
// a44d40b3a14aca3f19ccf47244ef4a70ed02d00f5d840c38756368e9a7cc24b1:4 on testnet3
name: "uncompressed-p2pkh-with-op-dup-and-op-drop-at-the-end",
pkScript: "OP_DUP OP_HASH160 DATA_20 " +
"0x6b2044146a4438e6e5bfbc65f147afeb64d14fbb " +
"OP_EQUALVERIFY OP_CHECKSIG",
sigScript: "DATA_71 0x3044022075c0666d413fc85cca94ea2f24adc0fedb61a3ba0fcfb240" +
"c1a4fd2587b03bf90220525ad4d92c6bf635f8b97c188ebf491c6e342b767a5432f" +
"318cbb0245a7f64be01 DATA_65 0x04c4bee5e6dbb5c1651437cb4386c1515c7776" +
"c64535077204c6f24f05a37d04a32bc78beb2193b53b104c9954c44b0ce168bc78efd5f1e1c7db9d6c21b3016599 " +
"OP_DUP OP_DROP",
class: PubKeyHashTy,
expectErr: false,
},
{
// e244bacd69d8f5ae77c349f0e7e4f977f21f8e219ac8e0a35afd43414efdee90:1 on testnet3
name: "p2pkh-that-has-a-op-drop-in-the-middle",
pkScript: "OP_DUP OP_HASH160 DATA_20 " +
"0xe1c5ba4d1fef0a3c7806603de565929684f9c2b1 " +
"OP_EQUALVERIFY OP_CHECKSIG",
sigScript: "DATA_33 0x035922db6794aac9676322fb72d0cf4fb3148770d5a1931de2ab3263b7ec9e8ec9 " +
"OP_DROP DATA_72 " +
"0x304502210086c4ff9fb0fccd6a626c4e902d4c3c05b32f6abc1cdafc6c4b08ce88ae4bb9e0022" +
"02367a6cfd15d5aa98903c83f60773616da2b6e01b20c9c76fc8cfbfb5ccbefee01 " +
"DATA_33 0x0270e4215fbe540cab09ac91c9586eba4fc797537859489f4a23d3e22356f1732f",
class: PubKeyHashTy,
expectErr: false,
},
{
// 8ea059a12212dd6d2ca3a87b9550bbaa290211679a6be990e9ed8152094c987d:0 on testnet3
name: "p2pkh",
Expand Down
0