github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/btcutil/txscript/standard.go (about) 1 // Copyright (c) 2013-2015 The btcsuite developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package txscript 6 7 import ( 8 "github.com/mit-dci/lit/btcutil" 9 "github.com/mit-dci/lit/coinparam" 10 ) 11 12 const ( 13 // MaxDataCarrierSize is the maximum number of bytes allowed in pushed 14 // data to be considered a nulldata transaction 15 MaxDataCarrierSize = 80 16 17 // StandardVerifyFlags are the script flags which are used when 18 // executing transaction scripts to enforce additional checks which 19 // are required for the script to be considered standard. These checks 20 // help reduce issues related to transaction malleability as well as 21 // allow pay-to-script hash transactions. Note these flags are 22 // different than what is required for the consensus rules in that they 23 // are more strict. 24 // 25 // TODO: This definition does not belong here. It belongs in a policy 26 // package. 27 StandardVerifyFlags = ScriptBip16 | 28 ScriptVerifyDERSignatures | 29 ScriptVerifyStrictEncoding | 30 ScriptVerifyMinimalData | 31 ScriptStrictMultiSig | 32 ScriptDiscourageUpgradableNops | 33 ScriptVerifyCleanStack | 34 ScriptVerifyCheckLockTimeVerify | 35 ScriptVerifyLowS | 36 ScriptStrictMultiSig | 37 ScriptVerifyWitness | 38 ScriptVerifyDiscourageUpgradeableWitnessProgram 39 ) 40 41 // ScriptClass is an enumeration for the list of standard types of script. 42 type ScriptClass byte 43 44 // Classes of script payment known about in the blockchain. 45 const ( 46 NonStandardTy ScriptClass = iota // None of the recognized forms. 47 PubKeyTy // Pay pubkey. 48 PubKeyHashTy // Pay pubkey hash. 49 WitnessPubKeyHashTy // Pay witness pubkey hash. 50 ScriptHashTy // Pay to script hash. 51 WitnessScriptHashTy // Pay to witness script hash. 52 MultiSigTy // Multi signature. 53 NullDataTy // Empty data-only (provably prunable). 54 ) 55 56 // scriptClassToName houses the human-readable strings which describe each 57 // script class. 58 var scriptClassToName = []string{ 59 NonStandardTy: "nonstandard", 60 PubKeyTy: "pubkey", 61 PubKeyHashTy: "pubkeyhash", 62 WitnessPubKeyHashTy: "witnesspubkeyhash", 63 ScriptHashTy: "scripthash", 64 WitnessScriptHashTy: "witnessscripthash", 65 MultiSigTy: "multisig", 66 NullDataTy: "nulldata", 67 } 68 69 // String implements the Stringer interface by returning the name of 70 // the enum script class. If the enum is invalid then "Invalid" will be 71 // returned. 72 func (t ScriptClass) String() string { 73 if int(t) > len(scriptClassToName) || int(t) < 0 { 74 return "Invalid" 75 } 76 return scriptClassToName[t] 77 } 78 79 // isPubkey returns true if the script passed is a pay-to-pubkey transaction, 80 // false otherwise. 81 func isPubkey(pops []parsedOpcode) bool { 82 // Valid pubkeys are either 33 or 65 bytes. 83 return len(pops) == 2 && 84 (len(pops[0].data) == 33 || len(pops[0].data) == 65) && 85 pops[1].opcode.value == OP_CHECKSIG 86 } 87 88 // isPubkeyHash returns true if the script passed is a pay-to-pubkey-hash 89 // transaction, false otherwise. 90 func isPubkeyHash(pops []parsedOpcode) bool { 91 return len(pops) == 5 && 92 pops[0].opcode.value == OP_DUP && 93 pops[1].opcode.value == OP_HASH160 && 94 pops[2].opcode.value == OP_DATA_20 && 95 pops[3].opcode.value == OP_EQUALVERIFY && 96 pops[4].opcode.value == OP_CHECKSIG 97 98 } 99 100 // isMultiSig returns true if the passed script is a multisig transaction, false 101 // otherwise. 102 func isMultiSig(pops []parsedOpcode) bool { 103 // The absolute minimum is 1 pubkey: 104 // OP_0/OP_1-16 <pubkey> OP_1 OP_CHECKMULTISIG 105 l := len(pops) 106 if l < 4 { 107 return false 108 } 109 if !isSmallInt(pops[0].opcode) { 110 return false 111 } 112 if !isSmallInt(pops[l-2].opcode) { 113 return false 114 } 115 if pops[l-1].opcode.value != OP_CHECKMULTISIG { 116 return false 117 } 118 119 // Verify the number of pubkeys specified matches the actual number 120 // of pubkeys provided. 121 if l-2-1 != asSmallInt(pops[l-2].opcode) { 122 return false 123 } 124 125 for _, pop := range pops[1 : l-2] { 126 // Valid pubkeys are either 33 or 65 bytes. 127 if len(pop.data) != 33 && len(pop.data) != 65 { 128 return false 129 } 130 } 131 return true 132 } 133 134 // isNullData returns true if the passed script is a null data transaction, 135 // false otherwise. 136 func isNullData(pops []parsedOpcode) bool { 137 // A nulldata transaction is either a single OP_RETURN or an 138 // OP_RETURN SMALLDATA (where SMALLDATA is a data push up to 139 // MaxDataCarrierSize bytes). 140 l := len(pops) 141 if l == 1 && pops[0].opcode.value == OP_RETURN { 142 return true 143 } 144 145 return l == 2 && 146 pops[0].opcode.value == OP_RETURN && 147 pops[1].opcode.value <= OP_PUSHDATA4 && 148 len(pops[1].data) <= MaxDataCarrierSize 149 } 150 151 // scriptType returns the type of the script being inspected from the known 152 // standard types. 153 func typeOfScript(pops []parsedOpcode) ScriptClass { 154 if isPubkey(pops) { 155 return PubKeyTy 156 } else if isPubkeyHash(pops) { 157 return PubKeyHashTy 158 } else if isWitnessPubKeyHash(pops) { 159 return WitnessPubKeyHashTy 160 } else if isScriptHash(pops) { 161 return ScriptHashTy 162 } else if isWitnessScriptHash(pops) { 163 return WitnessScriptHashTy 164 } else if isMultiSig(pops) { 165 return MultiSigTy 166 } else if isNullData(pops) { 167 return NullDataTy 168 } 169 return NonStandardTy 170 } 171 172 // GetScriptClass returns the class of the script passed. 173 // 174 // NonStandardTy will be returned when the script does not parse. 175 func GetScriptClass(script []byte) ScriptClass { 176 pops, err := ParseScript(script) 177 if err != nil { 178 return NonStandardTy 179 } 180 return typeOfScript(pops) 181 } 182 183 // expectedInputs returns the number of arguments required by a script. 184 // If the script is of unknown type such that the number can not be determined 185 // then -1 is returned. We are an internal function and thus assume that class 186 // is the real class of pops (and we can thus assume things that were determined 187 // while finding out the type). 188 func expectedInputs(pops []parsedOpcode, class ScriptClass) int { 189 switch class { 190 case PubKeyTy: 191 return 1 192 193 case PubKeyHashTy: 194 return 2 195 196 case WitnessPubKeyHashTy: 197 return 2 198 199 case ScriptHashTy: 200 // Not including script. That is handled by the caller. 201 return 1 202 203 case WitnessScriptHashTy: 204 // Not including script. That is handled by the caller. 205 return 1 206 207 case MultiSigTy: 208 // Standard multisig has a push a small number for the number 209 // of sigs and number of keys. Check the first push instruction 210 // to see how many arguments are expected. typeOfScript already 211 // checked this so we know it'll be a small int. Also, due to 212 // the original bitcoind bug where OP_CHECKMULTISIG pops an 213 // additional item from the stack, add an extra expected input 214 // for the extra push that is required to compensate. 215 return asSmallInt(pops[0].opcode) + 1 216 217 case NullDataTy: 218 fallthrough 219 default: 220 return -1 221 } 222 } 223 224 // ScriptInfo houses information about a script pair that is determined by 225 // CalcScriptInfo. 226 type ScriptInfo struct { 227 // PkScriptClass is the class of the public key script and is equivalent 228 // to calling GetScriptClass on it. 229 PkScriptClass ScriptClass 230 231 // NumInputs is the number of inputs provided by the public key script. 232 NumInputs int 233 234 // ExpectedInputs is the number of outputs required by the signature 235 // script and any pay-to-script-hash scripts. The number will be -1 if 236 // unknown. 237 ExpectedInputs int 238 239 // SigOps is the number of signature operations in the script pair. 240 SigOps int 241 } 242 243 // CalcScriptInfo returns a structure providing data about the provided script 244 // pair. It will error if the pair is in someway invalid such that they can not 245 // be analysed, i.e. if they do not parse or the pkScript is not a push-only 246 // script 247 func CalcScriptInfo(sigScript, pkScript []byte, bip16 bool) (*ScriptInfo, error) { 248 sigPops, err := ParseScript(sigScript) 249 if err != nil { 250 return nil, err 251 } 252 253 pkPops, err := ParseScript(pkScript) 254 if err != nil { 255 return nil, err 256 } 257 258 // Push only sigScript makes little sense. 259 si := new(ScriptInfo) 260 si.PkScriptClass = typeOfScript(pkPops) 261 262 // Can't have a sigScript that doesn't just push data. 263 if !isPushOnly(sigPops) { 264 return nil, ErrStackNonPushOnly 265 } 266 267 si.ExpectedInputs = expectedInputs(pkPops, si.PkScriptClass) 268 269 // All entries pushed to stack (or are OP_RESERVED and exec will fail). 270 si.NumInputs = len(sigPops) 271 272 // Count sigops taking into account pay-to-script-hash. 273 if si.PkScriptClass == ScriptHashTy && bip16 { 274 // The pay-to-hash-script is the final data push of the 275 // signature script. 276 script := sigPops[len(sigPops)-1].data 277 shPops, err := ParseScript(script) 278 if err != nil { 279 return nil, err 280 } 281 282 shInputs := expectedInputs(shPops, typeOfScript(shPops)) 283 if shInputs == -1 { 284 si.ExpectedInputs = -1 285 } else { 286 si.ExpectedInputs += shInputs 287 } 288 si.SigOps = getSigOpCount(shPops, true) 289 // TODO(roasbeef): segwit sig op counting 290 } else { 291 si.SigOps = getSigOpCount(pkPops, true) 292 } 293 294 return si, nil 295 } 296 297 // CalcMultiSigStats returns the number of public keys and signatures from 298 // a multi-signature transaction script. The passed script MUST already be 299 // known to be a multi-signature script. 300 func CalcMultiSigStats(script []byte) (int, int, error) { 301 pops, err := ParseScript(script) 302 if err != nil { 303 return 0, 0, err 304 } 305 306 // A multi-signature script is of the pattern: 307 // NUM_SIGS PUBKEY PUBKEY PUBKEY... NUM_PUBKEYS OP_CHECKMULTISIG 308 // Therefore the number of signatures is the oldest item on the stack 309 // and the number of pubkeys is the 2nd to last. Also, the absolute 310 // minimum for a multi-signature script is 1 pubkey, so at least 4 311 // items must be on the stack per: 312 // OP_1 PUBKEY OP_1 OP_CHECKMULTISIG 313 if len(pops) < 4 { 314 return 0, 0, ErrStackUnderflow 315 } 316 317 numSigs := asSmallInt(pops[0].opcode) 318 numPubKeys := asSmallInt(pops[len(pops)-2].opcode) 319 return numPubKeys, numSigs, nil 320 } 321 322 // payToPubKeyHashScript creates a new script to pay a transaction 323 // output to a 20-byte pubkey hash. It is expected that the input is a valid 324 // hash. 325 func payToPubKeyHashScript(pubKeyHash []byte) ([]byte, error) { 326 return NewScriptBuilder().AddOp(OP_DUP).AddOp(OP_HASH160). 327 AddData(pubKeyHash).AddOp(OP_EQUALVERIFY).AddOp(OP_CHECKSIG). 328 Script() 329 } 330 331 // payToWitnessPubKeyHashScript creates a new script to pay to a version 0 332 // pubkey hash witness program. The passed hash is expected to be valid. 333 func payToWitnessPubKeyHashScript(pubKeyHash []byte) ([]byte, error) { 334 return NewScriptBuilder().AddOp(OP_0).AddData(pubKeyHash).Script() 335 } 336 337 // payToScriptHashScript creates a new script to pay a transaction output to a 338 // script hash. It is expected that the input is a valid hash. 339 func payToScriptHashScript(scriptHash []byte) ([]byte, error) { 340 return NewScriptBuilder().AddOp(OP_HASH160).AddData(scriptHash). 341 AddOp(OP_EQUAL).Script() 342 } 343 344 // payToWitnessPubKeyHashScript creates a new script to pay to a version 0 345 // script hash witness program. The passed hash is expected to be valid. 346 func payToWitnessScriptHashScript(scriptHash []byte) ([]byte, error) { 347 return NewScriptBuilder().AddOp(OP_0).AddData(scriptHash).Script() 348 } 349 350 // payToPubkeyScript creates a new script to pay a transaction output to a 351 // public key. It is expected that the input is a valid pubkey. 352 func payToPubKeyScript(serializedPubKey []byte) ([]byte, error) { 353 return NewScriptBuilder().AddData(serializedPubKey). 354 AddOp(OP_CHECKSIG).Script() 355 } 356 357 // PayToAddrScript creates a new script to pay a transaction output to a the 358 // specified address. 359 func PayToAddrScript(addr btcutil.Address) ([]byte, error) { 360 switch addr := addr.(type) { 361 case *btcutil.AddressPubKeyHash: 362 if addr == nil { 363 return nil, ErrUnsupportedAddress 364 } 365 return payToPubKeyHashScript(addr.ScriptAddress()) 366 367 case *btcutil.AddressScriptHash: 368 if addr == nil { 369 return nil, ErrUnsupportedAddress 370 } 371 return payToScriptHashScript(addr.ScriptAddress()) 372 373 case *btcutil.AddressPubKey: 374 if addr == nil { 375 return nil, ErrUnsupportedAddress 376 } 377 return payToPubKeyScript(addr.ScriptAddress()) 378 379 // case *btcutil.AddressWitnessPubKeyHash: 380 // if addr == nil { 381 // return nil, ErrUnsupportedAddress 382 // } 383 // return payToWitnessPubKeyHashScript(addr.ScriptAddress()) 384 // case *btcutil.AddressWitnessScriptHash: 385 // if addr == nil { 386 // return nil, ErrUnsupportedAddress 387 // } 388 // return payToWitnessScriptHashScript(addr.ScriptAddress()) 389 } 390 391 return nil, ErrUnsupportedAddress 392 } 393 394 // MultiSigScript returns a valid script for a multisignature redemption where 395 // nrequired of the keys in pubkeys are required to have signed the transaction 396 // for success. An ErrBadNumRequired will be returned if nrequired is larger 397 // than the number of keys provided. 398 func MultiSigScript(pubkeys []*btcutil.AddressPubKey, nrequired int) ([]byte, error) { 399 if len(pubkeys) < nrequired { 400 return nil, ErrBadNumRequired 401 } 402 403 builder := NewScriptBuilder().AddInt64(int64(nrequired)) 404 for _, key := range pubkeys { 405 builder.AddData(key.ScriptAddress()) 406 } 407 builder.AddInt64(int64(len(pubkeys))) 408 builder.AddOp(OP_CHECKMULTISIG) 409 410 return builder.Script() 411 } 412 413 // PushedData returns an array of byte slices containing any pushed data found 414 // in the passed script. This includes OP_0, but not OP_1 - OP_16. 415 func PushedData(script []byte) ([][]byte, error) { 416 pops, err := ParseScript(script) 417 if err != nil { 418 return nil, err 419 } 420 421 var data [][]byte 422 for _, pop := range pops { 423 if pop.data != nil { 424 data = append(data, pop.data) 425 } else if pop.opcode.value == OP_0 { 426 data = append(data, nil) 427 } 428 } 429 return data, nil 430 } 431 432 // ExtractPkScriptAddrs returns the type of script, addresses and required 433 // signatures associated with the passed PkScript. Note that it only works for 434 // 'standard' transaction script types. Any data such as public keys which are 435 // invalid are omitted from the results. 436 func ExtractPkScriptAddrs(pkScript []byte, chainParams *coinparam.Params) (ScriptClass, []btcutil.Address, int, error) { 437 var addrs []btcutil.Address 438 var requiredSigs int 439 440 // No valid addresses or required signatures if the script doesn't 441 // parse. 442 pops, err := ParseScript(pkScript) 443 if err != nil { 444 return NonStandardTy, nil, 0, err 445 } 446 447 scriptClass := typeOfScript(pops) 448 switch scriptClass { 449 case PubKeyHashTy: 450 // A pay-to-pubkey-hash script is of the form: 451 // OP_DUP OP_HASH160 <hash> OP_EQUALVERIFY OP_CHECKSIG 452 // Therefore the pubkey hash is the 3rd item on the stack. 453 // Skip the pubkey hash if it's invalid for some reason. 454 requiredSigs = 1 455 addr, err := btcutil.NewAddressPubKeyHash(pops[2].data, 456 chainParams) 457 if err == nil { 458 addrs = append(addrs, addr) 459 } 460 461 // case WitnessPubKeyHashTy: 462 // // A pay-to-witness-pubkey-hash script is of thw form: 463 // // OP_0 <20-byte hash> 464 // // Therefore, the pubkey hash is the second item on the stack. 465 // // Skip the pubkey hash if it's invalid for some reason. 466 // requiredSigs = 1 467 // addr, err := btcutil.NewAddressWitnessPubKeyHash(pops[1].data, 468 // chainParams) 469 // if err == nil { 470 // addrs = append(addrs, addr) 471 // } 472 473 case PubKeyTy: 474 // A pay-to-pubkey script is of the form: 475 // <pubkey> OP_CHECKSIG 476 // Therefore the pubkey is the first item on the stack. 477 // Skip the pubkey if it's invalid for some reason. 478 requiredSigs = 1 479 addr, err := btcutil.NewAddressPubKey(pops[0].data, chainParams) 480 if err == nil { 481 addrs = append(addrs, addr) 482 } 483 484 case ScriptHashTy: 485 // A pay-to-script-hash script is of the form: 486 // OP_HASH160 <scripthash> OP_EQUAL 487 // Therefore the script hash is the 2nd item on the stack. 488 // Skip the script hash if it's invalid for some reason. 489 requiredSigs = 1 490 addr, err := btcutil.NewAddressScriptHashFromHash(pops[1].data, 491 chainParams) 492 if err == nil { 493 addrs = append(addrs, addr) 494 } 495 496 // case WitnessScriptHashTy: 497 // // A pay-to-witness-script-hash script is of the form: 498 // // OP_0 <32-byte hash> 499 // // Therefore, the script hash is the second item on the stack. 500 // // Skip the script hash if it's invalid for some reason. 501 // requiredSigs = 1 502 // addr, err := btcutil.NewAddressWitnessScriptHashFromHash(pops[1].data, 503 // chainParams) 504 // if err == nil { 505 // addrs = append(addrs, addr) 506 // } 507 508 case MultiSigTy: 509 // A multi-signature script is of the form: 510 // <numsigs> <pubkey> <pubkey> <pubkey>... <numpubkeys> OP_CHECKMULTISIG 511 // Therefore the number of required signatures is the 1st item 512 // on the stack and the number of public keys is the 2nd to last 513 // item on the stack. 514 requiredSigs = asSmallInt(pops[0].opcode) 515 numPubKeys := asSmallInt(pops[len(pops)-2].opcode) 516 517 // Extract the public keys while skipping any that are invalid. 518 addrs = make([]btcutil.Address, 0, numPubKeys) 519 for i := 0; i < numPubKeys; i++ { 520 addr, err := btcutil.NewAddressPubKey(pops[i+1].data, 521 chainParams) 522 if err == nil { 523 addrs = append(addrs, addr) 524 } 525 } 526 527 case NullDataTy: 528 // Null data transactions have no addresses or required 529 // signatures. 530 531 case NonStandardTy: 532 // Don't attempt to extract addresses or required signatures for 533 // nonstandard transactions. 534 } 535 536 return scriptClass, addrs, requiredSigs, nil 537 }