txscript: Make typeOfScript accept raw script.

This converts the typeOfScript function to accept a script version and
raw script instead of an array of internal parsed opcodes in order to
make it more flexible for raw script analysis.

Also, this adds a comment to CalcScriptInfo to call out the specific
version semantics and deprecates the function since nothing currently
uses it, and the relevant information can now be obtained by callers
more directly through the use of the new script tokenizer.

All other callers are updated accordingly.
This commit is contained in:
Dave Collins 2019-03-13 01:11:33 -05:00 committed by Roy Lee
parent aa5a1d1648
commit 9ac8abd519

View file

@ -498,7 +498,19 @@ func isNullDataScript(scriptVersion uint16, script []byte) bool {
// scriptType returns the type of the script being inspected from the known // scriptType returns the type of the script being inspected from the known
// standard types. // standard types.
func typeOfScript(pops []parsedOpcode) ScriptClass { //
// NOTE: All scripts that are not version 0 are currently considered non
// standard.
func typeOfScript(scriptVersion uint16, script []byte) ScriptClass {
if scriptVersion != 0 {
return NonStandardTy
}
pops, err := parseScript(script)
if err != nil {
return NonStandardTy
}
if isPubkey(pops) { if isPubkey(pops) {
return PubKeyTy return PubKeyTy
} else if isPubkeyHash(pops) { } else if isPubkeyHash(pops) {
@ -521,11 +533,8 @@ func typeOfScript(pops []parsedOpcode) ScriptClass {
// //
// NonStandardTy will be returned when the script does not parse. // NonStandardTy will be returned when the script does not parse.
func GetScriptClass(script []byte) ScriptClass { func GetScriptClass(script []byte) ScriptClass {
pops, err := parseScript(script) const scriptVersion = 0
if err != nil { return typeOfScript(scriptVersion, script)
return NonStandardTy
}
return typeOfScript(pops)
} }
// NewScriptClass returns the ScriptClass corresponding to the string name // NewScriptClass returns the ScriptClass corresponding to the string name
@ -608,9 +617,17 @@ type ScriptInfo struct {
// pair. It will error if the pair is in someway invalid such that they can not // pair. It will error if the pair is in someway invalid such that they can not
// be analysed, i.e. if they do not parse or the pkScript is not a push-only // be analysed, i.e. if they do not parse or the pkScript is not a push-only
// script // script
//
// 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.
//
// DEPRECATED. This will be removed in the next major version bump.
func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness, func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness,
bip16, segwit bool) (*ScriptInfo, error) { bip16, segwit bool) (*ScriptInfo, error) {
const scriptVersion = 0
sigPops, err := parseScript(sigScript) sigPops, err := parseScript(sigScript)
if err != nil { if err != nil {
return nil, err return nil, err
@ -621,9 +638,8 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness,
return nil, err return nil, err
} }
// Push only sigScript makes little sense.
si := new(ScriptInfo) si := new(ScriptInfo)
si.PkScriptClass = typeOfScript(pkPops) si.PkScriptClass = typeOfScript(scriptVersion, pkScript)
// Can't have a signature script that doesn't just push data. // Can't have a signature script that doesn't just push data.
if !isPushOnly(sigPops) { if !isPushOnly(sigPops) {
@ -644,7 +660,8 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness,
return nil, err return nil, err
} }
shInputs := expectedInputs(shPops, typeOfScript(shPops)) redeemClass := typeOfScript(scriptVersion, script)
shInputs := expectedInputs(shPops, redeemClass)
if shInputs == -1 { if shInputs == -1 {
si.ExpectedInputs = -1 si.ExpectedInputs = -1
} else { } else {
@ -671,7 +688,9 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness,
// Extract the pushed witness program from the sigScript so we // Extract the pushed witness program from the sigScript so we
// can determine the number of expected inputs. // can determine the number of expected inputs.
pkPops, _ := parseScript(sigScript[1:]) pkPops, _ := parseScript(sigScript[1:])
shInputs := expectedInputs(pkPops, typeOfScript(pkPops))
redeemClass := typeOfScript(scriptVersion, sigScript[1:])
shInputs := expectedInputs(pkPops, redeemClass)
if shInputs == -1 { if shInputs == -1 {
si.ExpectedInputs = -1 si.ExpectedInputs = -1
} else { } else {
@ -691,7 +710,8 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness,
witnessScript := witness[len(witness)-1] witnessScript := witness[len(witness)-1]
pops, _ := parseScript(witnessScript) pops, _ := parseScript(witnessScript)
shInputs := expectedInputs(pops, typeOfScript(pops)) redeemClass := typeOfScript(scriptVersion, witnessScript)
shInputs := expectedInputs(pops, redeemClass)
if shInputs == -1 { if shInputs == -1 {
si.ExpectedInputs = -1 si.ExpectedInputs = -1
} else { } else {
@ -888,7 +908,9 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script
return NonStandardTy, nil, 0, err return NonStandardTy, nil, 0, err
} }
scriptClass := typeOfScript(pops) const scriptVersion = 0
scriptClass := typeOfScript(scriptVersion, pkScript)
switch scriptClass { switch scriptClass {
case PubKeyHashTy: case PubKeyHashTy:
// A pay-to-pubkey-hash script is of the form: // A pay-to-pubkey-hash script is of the form: