dcrd/txscript/stdscript/script.go
Dave Collins 7d97fd5ff8
stdscript: Move from internal/staging to txscript.
This moves the new stdscript package from the internal staging area to
the txscript module and updates the relevant paths and package README.md
accordingly.
2021-11-18 12:29:53 -06:00

545 lines
19 KiB
Go

// Copyright (c) 2021 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
// Package stdscript provides facilities for working with standard scripts.
package stdscript
// ScriptType identifies the type of known scripts in the blockchain that are
// typically considered standard by the default policy of most nodes. All other
// scripts are considered non-standard.
type ScriptType byte
const (
// STNonStandard indicates a script is none of the recognized standard
// forms.
STNonStandard ScriptType = iota
// STPubKeyEcdsaSecp256k1 identifies a standard script that imposes an
// encumbrance that requires a valid ECDSA signature for a specific
// secp256k1 public key.
//
// This is commonly referred to as either a pay-to-pubkey (P2PK) script or
// the more specific pay-to-pubkey-ecdsa-secp256k1 script.
STPubKeyEcdsaSecp256k1
// STPubKeyEd25519 identifies a standard script that imposes an encumbrance
// that requires a valid Ed25519 signature for a specific Ed25519 public
// key.
//
// This is commonly referred to as a pay-to-pubkey-ed25519 script.
STPubKeyEd25519
// STPubKeySchnorrSecp256k1 identifies a standard script that imposes an
// encumbrance that requires a valid EC-Schnorr-DCRv0 signature for a
// specific secp256k1 public key.
//
// This is commonly referred to as a pay-to-pubkey-schnorr-secp256k1 script.
STPubKeySchnorrSecp256k1
// STPubKeyHashEcdsaSecp256k1 identifies a standard script that imposes an
// encumbrance that requires a secp256k1 public key that hashes to a
// specific value along with a valid ECDSA signature for that public key.
//
// This is commonly referred to as either a pay-to-pubkey-hash (P2PKH)
// script or the more specific pay-to-pubkey-hash-ecdsa-secp256k1 script.
STPubKeyHashEcdsaSecp256k1
// STPubKeyHashEd25519 identifies a standard script that imposes an
// encumbrance that requires an Ed25519 public key that hashes to a specific
// value along with a valid Ed25519 signature for that public key.
//
// This is commonly referred to as a pay-to-pubkey-hash-ed25519 script.
STPubKeyHashEd25519
// STPubKeyHashSchnorrSecp256k1 identifies a standard script that imposes an
// encumbrance that requires a secp256k1 public key that hashes to a
// specific value along with a valid EC-Schnorr-DCRv0 signature for that
// public key.
//
// This is commonly referred to as a pay-to-pubkey-hash-schnorr-secp256k1
// script.
STPubKeyHashSchnorrSecp256k1
// STScriptHash identifies a standard script that imposes an encumbrance
// that requires a script that hashes to a specific value along with all of
// the encumbrances that script itself imposes. The script is commonly
// referred to as a redeem script.
//
// This is commonly referred to as pay-to-script-hash (P2SH).
STScriptHash
// STMultiSig identifies a standard script that imposes an encumbrance that
// requires a given number of valid ECDSA signatures which correspond to
// given secp256k1 public keys.
//
// This is commonly referred to as a standard ECDSA n-of-m multi-signature
// script.
STMultiSig
// STNullData identifies a standard null data script that is provably
// prunable.
STNullData
// STStakeSubmissionPubKeyHash identifies a script that is only valid when
// used as part of a ticket purchase transaction in the staking system and
// is used for imposing voting rights.
//
// It imposes an encumbrance that requires a secp256k1 public key that
// hashes to a specific value along with a valid ECDSA signature for that
// public key.
STStakeSubmissionPubKeyHash
// STStakeSubmissionScriptHash identifies a script that is only valid when
// used as part of a ticket purchase transaction in the staking system and
// is used for imposing voting rights.
//
// It imposes an encumbrance that requires a script that hashes to a
// specific value along with all of the encumbrances that script itself
// imposes. The script is commonly referred to as a redeem script.
STStakeSubmissionScriptHash
// STStakeGenPubKeyHash identifies a script that is only valid when used as
// part of a vote transaction in the staking system.
//
// It imposes an encumbrance that requires a secp256k1 public key that
// hashes to a specific value along with a valid ECDSA signature for that
// public key.
STStakeGenPubKeyHash
// STStakeGenScriptHash identifies a script that is only valid when used as
// part of a vote transaction in the staking system.
//
// It imposes an encumbrance that requires a script that hashes to a
// specific value along with all of the encumbrances that script itself
// imposes. The script is commonly referred to as a redeem script.
STStakeGenScriptHash
// STStakeRevocationPubKeyHash identifies a script that is only valid when
// used as part of a revocation transaction in the staking system.
//
// It imposes an encumbrance that requires a secp256k1 public key that
// hashes to a specific value along with a valid ECDSA signature for that
// public key.
STStakeRevocationPubKeyHash
// STStakeRevocationScriptHash identifies a script that is only valid when
// used as part of a revocation transaction in the staking system.
//
// It imposes an encumbrance that requires a script that hashes to a
// specific value along with all of the encumbrances that script itself
// imposes. The script is commonly referred to as a redeem script.
STStakeRevocationScriptHash
// STStakeChangePubKeyHash identifies a script that is only valid when used
// as part of supported transactions in the staking system.
//
// It imposes an encumbrance that requires a secp256k1 public key that
// hashes to a specific value along with a valid ECDSA signature for that
// public key.
STStakeChangePubKeyHash
// STStakeChangeScriptHash identifies a script that is only valid when used
// as part of supported transactions in the staking system.
//
// It imposes an encumbrance that requires a script that hashes to a
// specific value along with all of the encumbrances that script itself
// imposes. The script is commonly referred to as a redeem script.
STStakeChangeScriptHash
// STTreasuryAdd identifies a script that is only valid when used as part
// supported transactions in the staking system and adds value to the
// treasury account.
STTreasuryAdd
// STTreasuryGenPubKeyHash identifies a script that is only valid when used
// as part supported transactions in the staking system and generates utxos
// from the treasury account.
//
// It imposes an encumbrance that requires a secp256k1 public key that
// hashes to a specific value along with a valid ECDSA signature for that
// public key.
STTreasuryGenPubKeyHash
// STTreasuryGenScriptHash identifies a script that is only valid when used
// as part supported transactions in the staking system and generates utxos
// from the treasury account.
//
// It imposes an encumbrance that requires a script that hashes to a
// specific value along with all of the encumbrances that script itself
// imposes. The script is commonly referred to as a redeem script.
STTreasuryGenScriptHash
// numScriptTypes is the maximum script type number used in tests. This
// entry MUST be the last entry in the enum.
numScriptTypes
)
// scriptTypeToName houses the human-readable strings which describe each script
// type.
var scriptTypeToName = []string{
STNonStandard: "nonstandard",
STPubKeyEcdsaSecp256k1: "pubkey",
STPubKeyEd25519: "pubkey-ed25519",
STPubKeySchnorrSecp256k1: "pubkey-schnorr-secp256k1",
STPubKeyHashEcdsaSecp256k1: "pubkeyhash",
STPubKeyHashEd25519: "pubkeyhash-ed25519",
STPubKeyHashSchnorrSecp256k1: "pubkeyhash-schnorr-secp256k1",
STScriptHash: "scripthash",
STMultiSig: "multisig",
STNullData: "nulldata",
STStakeSubmissionPubKeyHash: "stakesubmission-pubkeyhash",
STStakeSubmissionScriptHash: "stakesubmission-scripthash",
STStakeGenPubKeyHash: "stakegen-pubkeyhash",
STStakeGenScriptHash: "stakegen-scripthash",
STStakeRevocationPubKeyHash: "stakerevoke-pubkeyhash",
STStakeRevocationScriptHash: "stakerevoke-scripthash",
STStakeChangePubKeyHash: "stakechange-pubkeyhash",
STStakeChangeScriptHash: "stakechange-scripthash",
STTreasuryAdd: "treasuryadd",
STTreasuryGenPubKeyHash: "treasurygen-pubkeyhash",
STTreasuryGenScriptHash: "treasurygen-scripthash",
}
// String returns the ScriptType as a human-readable name.
func (t ScriptType) String() string {
if t >= numScriptTypes {
return "invalid"
}
return scriptTypeToName[t]
}
// IsPubKeyScript returns whether or not the passed script is either a standard
// pay-to-compressed-secp256k1-pubkey or pay-to-uncompressed-secp256k1-pubkey
// script.
//
// NOTE: Version 0 scripts are the only currently supported version. It will
// always return false for other script versions.
func IsPubKeyScript(scriptVersion uint16, script []byte) bool {
switch scriptVersion {
case 0:
return IsPubKeyScriptV0(script)
}
return false
}
// IsPubKeyEd25519Script returns whether or not the passed script is a standard
// pay-to-ed25519-pubkey script.
//
// NOTE: Version 0 scripts are the only currently supported version. It will
// always return false for other script versions.
func IsPubKeyEd25519Script(scriptVersion uint16, script []byte) bool {
switch scriptVersion {
case 0:
return IsPubKeyEd25519ScriptV0(script)
}
return false
}
// IsPubKeySchnorrSecp256k1Script returns whether or not the passed script is a
// standard pay-to-schnorr-secp256k1-pubkey script.
//
// NOTE: Version 0 scripts are the only currently supported version. It will
// always return false for other script versions.
func IsPubKeySchnorrSecp256k1Script(scriptVersion uint16, script []byte) bool {
switch scriptVersion {
case 0:
return IsPubKeySchnorrSecp256k1ScriptV0(script)
}
return false
}
// IsPubKeyHashScript returns whether or not the passed script is a standard
// pay-to-pubkey-hash-ecdsa-secp256k1 script.
//
// NOTE: Version 0 scripts are the only currently supported version. It will
// always return false for other script versions.
func IsPubKeyHashScript(scriptVersion uint16, script []byte) bool {
switch scriptVersion {
case 0:
return IsPubKeyHashScriptV0(script)
}
return false
}
// IsPubKeyHashEd25519Script returns whether or not the passed script is a
// standard pay-to-pubkey-hash-ed25519 script.
//
// NOTE: Version 0 scripts are the only currently supported version. It will
// always return false for other script versions.
func IsPubKeyHashEd25519Script(scriptVersion uint16, script []byte) bool {
switch scriptVersion {
case 0:
return IsPubKeyHashEd25519ScriptV0(script)
}
return false
}
// IsPubKeyHashSchnorrSecp256k1Script returns whether or not the passed script
// is a standard pay-to-pubkey-hash-schnorr-secp256k1 script.
//
// NOTE: Version 0 scripts are the only currently supported version. It will
// always return false for other script versions.
func IsPubKeyHashSchnorrSecp256k1Script(scriptVersion uint16, script []byte) bool {
switch scriptVersion {
case 0:
return IsPubKeyHashSchnorrSecp256k1ScriptV0(script)
}
return false
}
// IsScriptHashScript returns whether or not the passed script is a standard
// pay-to-script-hash script.
//
// NOTE: Version 0 scripts are the only currently supported version. It will
// always return false for other script versions.
func IsScriptHashScript(scriptVersion uint16, script []byte) bool {
switch scriptVersion {
case 0:
return IsScriptHashScriptV0(script)
}
return false
}
// IsMultiSigScript returns whether or not the passed script is a standard
// ECDSA multisig script.
//
// NOTE: Version 0 scripts are the only currently supported version. It will
// always return false for other script versions.
func IsMultiSigScript(scriptVersion uint16, script []byte) bool {
switch scriptVersion {
case 0:
return IsMultiSigScriptV0(script)
}
return false
}
// IsMultiSigSigScript returns whether or not the passed script appears to be a
// signature script which consists of a pay-to-script-hash multi-signature
// redeem script. Determining if a signature script is actually a redemption of
// pay-to-script-hash requires the associated public key script which is often
// expensive to obtain. Therefore, this makes a fast best effort guess that has
// a high probability of being correct by checking if the signature script ends
// with a data push and treating that data push as if it were a p2sh redeem
// script.
//
// NOTE: Version 0 scripts are the only currently supported version. It will
// always return false for other script versions.
func IsMultiSigSigScript(scriptVersion uint16, script []byte) bool {
switch scriptVersion {
case 0:
return IsMultiSigSigScriptV0(script)
}
return false
}
// IsNullDataScript returns whether or not the passed script is a standard
// null data script.
//
// NOTE: Version 0 scripts are the only currently supported version. It will
// always return false for other script versions.
func IsNullDataScript(scriptVersion uint16, script []byte) bool {
switch scriptVersion {
case 0:
return IsNullDataScriptV0(script)
}
return false
}
// IsStakeSubmissionPubKeyHashScript returns whether or not the passed script is
// a standard stake submission pay-to-pubkey-hash script.
//
// NOTE: Version 0 scripts are the only currently supported version. It will
// always return false for other script versions.
func IsStakeSubmissionPubKeyHashScript(scriptVersion uint16, script []byte) bool {
switch scriptVersion {
case 0:
return IsStakeSubmissionPubKeyHashScriptV0(script)
}
return false
}
// IsStakeSubmissionScriptHashScript returns whether or not the passed script is
// a standard stake submission pay-to-script-hash script.
//
// NOTE: Version 0 scripts are the only currently supported version. It will
// always return false for other script versions.
func IsStakeSubmissionScriptHashScript(scriptVersion uint16, script []byte) bool {
switch scriptVersion {
case 0:
return IsStakeSubmissionScriptHashScriptV0(script)
}
return false
}
// IsStakeGenPubKeyHashScript returns whether or not the passed script is a
// standard stake generation pay-to-pubkey-hash script.
//
// NOTE: Version 0 scripts are the only currently supported version. It will
// always return false for other script versions.
func IsStakeGenPubKeyHashScript(scriptVersion uint16, script []byte) bool {
switch scriptVersion {
case 0:
return IsStakeGenPubKeyHashScriptV0(script)
}
return false
}
// IsStakeGenScriptHashScript returns whether or not the passed script is a
// standard stake generation pay-to-script-hash script.
//
// NOTE: Version 0 scripts are the only currently supported version. It will
// always return false for other script versions.
func IsStakeGenScriptHashScript(scriptVersion uint16, script []byte) bool {
switch scriptVersion {
case 0:
return IsStakeGenScriptHashScriptV0(script)
}
return false
}
// IsStakeRevocationPubKeyHashScript returns whether or not the passed script is
// a standard stake revocation pay-to-pubkey-hash script.
//
// NOTE: Version 0 scripts are the only currently supported version. It will
// always return false for other script versions.
func IsStakeRevocationPubKeyHashScript(scriptVersion uint16, script []byte) bool {
switch scriptVersion {
case 0:
return IsStakeRevocationPubKeyHashScriptV0(script)
}
return false
}
// IsStakeRevocationScriptHashScript returns whether or not the passed script is
// a standard stake revocation pay-to-script-hash script.
//
// NOTE: Version 0 scripts are the only currently supported version. It will
// always return false for other script versions.
func IsStakeRevocationScriptHashScript(scriptVersion uint16, script []byte) bool {
switch scriptVersion {
case 0:
return IsStakeRevocationScriptHashScriptV0(script)
}
return false
}
// IsStakeChangePubKeyHashScript returns whether or not the passed script is a
// standard stake change pay-to-pubkey-hash script.
//
// NOTE: Version 0 scripts are the only currently supported version. It will
// always return false for other script versions.
func IsStakeChangePubKeyHashScript(scriptVersion uint16, script []byte) bool {
switch scriptVersion {
case 0:
return IsStakeChangePubKeyHashScriptV0(script)
}
return false
}
// IsStakeChangeScriptHashScript returns whether or not the passed script is a
// standard stake change pay-to-script-hash script.
//
// NOTE: Version 0 scripts are the only currently supported version. It will
// always return false for other script versions.
func IsStakeChangeScriptHashScript(scriptVersion uint16, script []byte) bool {
switch scriptVersion {
case 0:
return IsStakeChangeScriptHashScriptV0(script)
}
return false
}
// IsTreasuryAddScript returns whether or not the passed script is a supported
// treasury add script.
//
// NOTE: Version 0 scripts are the only currently supported version. It will
// always return false for other script versions.
func IsTreasuryAddScript(scriptVersion uint16, script []byte) bool {
switch scriptVersion {
case 0:
return IsTreasuryAddScriptV0(script)
}
return false
}
// IsTreasuryGenPubKeyHashScript returns whether or not the passed script is a
// standard treasury generation pay-to-pubkey-hash script.
//
// NOTE: Version 0 scripts are the only currently supported version. It will
// always return false for other script versions.
func IsTreasuryGenPubKeyHashScript(scriptVersion uint16, script []byte) bool {
switch scriptVersion {
case 0:
return IsTreasuryGenPubKeyHashScriptV0(script)
}
return false
}
// IsTreasuryGenScriptHashScript returns whether or not the passed script is a
// standard treasury generation pay-to-script-hash script.
//
// NOTE: Version 0 scripts are the only currently supported version. It will
// always return false for other script versions.
func IsTreasuryGenScriptHashScript(scriptVersion uint16, script []byte) bool {
switch scriptVersion {
case 0:
return IsTreasuryGenScriptHashScriptV0(script)
}
return false
}
// DetermineScriptType returns the type of the script passed.
//
// NOTE: Version 0 scripts are the only currently supported version. It will
// always return STNonStandard for other script versions.
//
// Similarly, STNonStandard is returned when the script does not parse.
func DetermineScriptType(scriptVersion uint16, script []byte) ScriptType {
switch scriptVersion {
case 0:
return DetermineScriptTypeV0(script)
}
// All scripts with newer versions are considered non standard.
return STNonStandard
}
// DetermineRequiredSigs attempts to identify the number of signatures required
// by the passed script for the known standard types.
//
// NOTE: Version 0 scripts are the only currently supported version. It will
// always return 0 for other script versions.
//
// Similarly, 0 is returned when the script does not parse or is not one of the
// known standard types.
func DetermineRequiredSigs(scriptVersion uint16, script []byte) uint16 {
switch scriptVersion {
case 0:
return DetermineRequiredSigsV0(script)
}
return 0
}