github.com/btcsuite/btcd@v0.24.0/txscript/script.go (about) 1 // Copyright (c) 2013-2017 The btcsuite developers 2 // Copyright (c) 2015-2019 The Decred developers 3 // Use of this source code is governed by an ISC 4 // license that can be found in the LICENSE file. 5 6 package txscript 7 8 import ( 9 "bytes" 10 "fmt" 11 "strings" 12 "time" 13 14 "github.com/btcsuite/btcd/wire" 15 ) 16 17 // Bip16Activation is the timestamp where BIP0016 is valid to use in the 18 // blockchain. To be used to determine if BIP0016 should be called for or not. 19 // This timestamp corresponds to Sun Apr 1 00:00:00 UTC 2012. 20 var Bip16Activation = time.Unix(1333238400, 0) 21 22 const ( 23 // TaprootAnnexTag is the tag for an annex. This value is used to 24 // identify the annex during tapscript spends. If there're at least two 25 // elements in the taproot witness stack, and the first byte of the 26 // last element matches this tag, then we'll extract this as a distinct 27 // item. 28 TaprootAnnexTag = 0x50 29 30 // TaprootLeafMask is the mask applied to the control block to extract 31 // the leaf version and parity of the y-coordinate of the output key if 32 // the taproot script leaf being spent. 33 TaprootLeafMask = 0xfe 34 ) 35 36 // These are the constants specified for maximums in individual scripts. 37 const ( 38 MaxOpsPerScript = 201 // Max number of non-push operations. 39 MaxPubKeysPerMultiSig = 20 // Multisig can't have more sigs than this. 40 MaxScriptElementSize = 520 // Max bytes pushable to the stack. 41 ) 42 43 // IsSmallInt returns whether or not the opcode is considered a small integer, 44 // which is an OP_0, or OP_1 through OP_16. 45 // 46 // NOTE: This function is only valid for version 0 opcodes. Since the function 47 // does not accept a script version, the results are undefined for other script 48 // versions. 49 func IsSmallInt(op byte) bool { 50 return op == OP_0 || (op >= OP_1 && op <= OP_16) 51 } 52 53 // IsPayToPubKey returns true if the script is in the standard pay-to-pubkey 54 // (P2PK) format, false otherwise. 55 func IsPayToPubKey(script []byte) bool { 56 return isPubKeyScript(script) 57 } 58 59 // IsPayToPubKeyHash returns true if the script is in the standard 60 // pay-to-pubkey-hash (P2PKH) format, false otherwise. 61 func IsPayToPubKeyHash(script []byte) bool { 62 return isPubKeyHashScript(script) 63 } 64 65 // IsPayToScriptHash returns true if the script is in the standard 66 // pay-to-script-hash (P2SH) format, false otherwise. 67 // 68 // WARNING: This function always treats the passed script as version 0. Great 69 // care must be taken if introducing a new script version because it is used in 70 // consensus which, unfortunately as of the time of this writing, does not check 71 // script versions before determining if the script is a P2SH which means nodes 72 // on existing rules will analyze new version scripts as if they were version 0. 73 func IsPayToScriptHash(script []byte) bool { 74 return isScriptHashScript(script) 75 } 76 77 // IsPayToWitnessScriptHash returns true if the script is in the standard 78 // pay-to-witness-script-hash (P2WSH) format, false otherwise. 79 func IsPayToWitnessScriptHash(script []byte) bool { 80 return isWitnessScriptHashScript(script) 81 } 82 83 // IsPayToWitnessPubKeyHash returns true if the script is in the standard 84 // pay-to-witness-pubkey-hash (P2WKH) format, false otherwise. 85 func IsPayToWitnessPubKeyHash(script []byte) bool { 86 return isWitnessPubKeyHashScript(script) 87 } 88 89 // IsPayToTaproot returns true if the passed script is a standard 90 // pay-to-taproot (PTTR) scripts, and false otherwise. 91 func IsPayToTaproot(script []byte) bool { 92 return isWitnessTaprootScript(script) 93 } 94 95 // IsWitnessProgram returns true if the passed script is a valid witness 96 // program which is encoded according to the passed witness program version. A 97 // witness program must be a small integer (from 0-16), followed by 2-40 bytes 98 // of pushed data. 99 func IsWitnessProgram(script []byte) bool { 100 return isWitnessProgramScript(script) 101 } 102 103 // IsNullData returns true if the passed script is a null data script, false 104 // otherwise. 105 func IsNullData(script []byte) bool { 106 const scriptVersion = 0 107 return isNullDataScript(scriptVersion, script) 108 } 109 110 // ExtractWitnessProgramInfo attempts to extract the witness program version, 111 // as well as the witness program itself from the passed script. 112 func ExtractWitnessProgramInfo(script []byte) (int, []byte, error) { 113 // If at this point, the scripts doesn't resemble a witness program, 114 // then we'll exit early as there isn't a valid version or program to 115 // extract. 116 version, program, valid := extractWitnessProgramInfo(script) 117 if !valid { 118 return 0, nil, fmt.Errorf("script is not a witness program, " + 119 "unable to extract version or witness program") 120 } 121 122 return version, program, nil 123 } 124 125 // IsPushOnlyScript returns whether or not the passed script only pushes data 126 // according to the consensus definition of pushing data. 127 // 128 // WARNING: This function always treats the passed script as version 0. Great 129 // care must be taken if introducing a new script version because it is used in 130 // consensus which, unfortunately as of the time of this writing, does not check 131 // script versions before checking if it is a push only script which means nodes 132 // on existing rules will treat new version scripts as if they were version 0. 133 func IsPushOnlyScript(script []byte) bool { 134 const scriptVersion = 0 135 tokenizer := MakeScriptTokenizer(scriptVersion, script) 136 for tokenizer.Next() { 137 // All opcodes up to OP_16 are data push instructions. 138 // NOTE: This does consider OP_RESERVED to be a data push instruction, 139 // but execution of OP_RESERVED will fail anyway and matches the 140 // behavior required by consensus. 141 if tokenizer.Opcode() > OP_16 { 142 return false 143 } 144 } 145 return tokenizer.Err() == nil 146 } 147 148 // DisasmString formats a disassembled script for one line printing. When the 149 // script fails to parse, the returned string will contain the disassembled 150 // script up to the point the failure occurred along with the string '[error]' 151 // appended. In addition, the reason the script failed to parse is returned 152 // if the caller wants more information about the failure. 153 // 154 // NOTE: This function is only valid for version 0 scripts. Since the function 155 // does not accept a script version, the results are undefined for other script 156 // versions. 157 func DisasmString(script []byte) (string, error) { 158 const scriptVersion = 0 159 160 var disbuf strings.Builder 161 tokenizer := MakeScriptTokenizer(scriptVersion, script) 162 if tokenizer.Next() { 163 disasmOpcode(&disbuf, tokenizer.op, tokenizer.Data(), true) 164 } 165 for tokenizer.Next() { 166 disbuf.WriteByte(' ') 167 disasmOpcode(&disbuf, tokenizer.op, tokenizer.Data(), true) 168 } 169 if tokenizer.Err() != nil { 170 if tokenizer.ByteIndex() != 0 { 171 disbuf.WriteByte(' ') 172 } 173 disbuf.WriteString("[error]") 174 } 175 return disbuf.String(), tokenizer.Err() 176 } 177 178 // removeOpcodeRaw will return the script after removing any opcodes that match 179 // `opcode`. If the opcode does not appear in script, the original script will 180 // be returned unmodified. Otherwise, a new script will be allocated to contain 181 // the filtered script. This metehod assumes that the script parses 182 // successfully. 183 // 184 // NOTE: This function is only valid for version 0 scripts. Since the function 185 // does not accept a script version, the results are undefined for other script 186 // versions. 187 func removeOpcodeRaw(script []byte, opcode byte) []byte { 188 // Avoid work when possible. 189 if len(script) == 0 { 190 return script 191 } 192 193 const scriptVersion = 0 194 var result []byte 195 var prevOffset int32 196 197 tokenizer := MakeScriptTokenizer(scriptVersion, script) 198 for tokenizer.Next() { 199 if tokenizer.Opcode() == opcode { 200 if result == nil { 201 result = make([]byte, 0, len(script)) 202 result = append(result, script[:prevOffset]...) 203 } 204 } else if result != nil { 205 result = append(result, script[prevOffset:tokenizer.ByteIndex()]...) 206 } 207 prevOffset = tokenizer.ByteIndex() 208 } 209 if result == nil { 210 return script 211 } 212 return result 213 } 214 215 // isCanonicalPush returns true if the opcode is either not a push instruction 216 // or the data associated with the push instruction uses the smallest 217 // instruction to do the job. False otherwise. 218 // 219 // For example, it is possible to push a value of 1 to the stack as "OP_1", 220 // "OP_DATA_1 0x01", "OP_PUSHDATA1 0x01 0x01", and others, however, the first 221 // only takes a single byte, while the rest take more. Only the first is 222 // considered canonical. 223 func isCanonicalPush(opcode byte, data []byte) bool { 224 dataLen := len(data) 225 if opcode > OP_16 { 226 return true 227 } 228 229 if opcode < OP_PUSHDATA1 && opcode > OP_0 && (dataLen == 1 && data[0] <= 16) { 230 return false 231 } 232 if opcode == OP_PUSHDATA1 && dataLen < OP_PUSHDATA1 { 233 return false 234 } 235 if opcode == OP_PUSHDATA2 && dataLen <= 0xff { 236 return false 237 } 238 if opcode == OP_PUSHDATA4 && dataLen <= 0xffff { 239 return false 240 } 241 return true 242 } 243 244 // removeOpcodeByData will return the script minus any opcodes that perform a 245 // canonical push of data that contains the passed data to remove. This 246 // function assumes it is provided a version 0 script as any future version of 247 // script should avoid this functionality since it is unncessary due to the 248 // signature scripts not being part of the witness-free transaction hash. 249 // 250 // WARNING: This will return the passed script unmodified unless a modification 251 // is necessary in which case the modified script is returned. This implies 252 // callers may NOT rely on being able to safely mutate either the passed or 253 // returned script without potentially modifying the same data. 254 // 255 // NOTE: This function is only valid for version 0 scripts. Since the function 256 // does not accept a script version, the results are undefined for other script 257 // versions. 258 func removeOpcodeByData(script []byte, dataToRemove []byte) []byte { 259 // Avoid work when possible. 260 if len(script) == 0 || len(dataToRemove) == 0 { 261 return script 262 } 263 264 // Parse through the script looking for a canonical data push that contains 265 // the data to remove. 266 const scriptVersion = 0 267 var result []byte 268 var prevOffset int32 269 tokenizer := MakeScriptTokenizer(scriptVersion, script) 270 for tokenizer.Next() { 271 // In practice, the script will basically never actually contain the 272 // data since this function is only used during signature verification 273 // to remove the signature itself which would require some incredibly 274 // non-standard code to create. 275 // 276 // Thus, as an optimization, avoid allocating a new script unless there 277 // is actually a match that needs to be removed. 278 op, data := tokenizer.Opcode(), tokenizer.Data() 279 if isCanonicalPush(op, data) && bytes.Contains(data, dataToRemove) { 280 if result == nil { 281 fullPushLen := tokenizer.ByteIndex() - prevOffset 282 result = make([]byte, 0, int32(len(script))-fullPushLen) 283 result = append(result, script[0:prevOffset]...) 284 } 285 } else if result != nil { 286 result = append(result, script[prevOffset:tokenizer.ByteIndex()]...) 287 } 288 289 prevOffset = tokenizer.ByteIndex() 290 } 291 if result == nil { 292 result = script 293 } 294 return result 295 } 296 297 // AsSmallInt returns the passed opcode, which must be true according to 298 // IsSmallInt(), as an integer. 299 func AsSmallInt(op byte) int { 300 if op == OP_0 { 301 return 0 302 } 303 304 return int(op - (OP_1 - 1)) 305 } 306 307 // countSigOpsV0 returns the number of signature operations in the provided 308 // script up to the point of the first parse failure or the entire script when 309 // there are no parse failures. The precise flag attempts to accurately count 310 // the number of operations for a multisig operation versus using the maximum 311 // allowed. 312 // 313 // WARNING: This function always treats the passed script as version 0. Great 314 // care must be taken if introducing a new script version because it is used in 315 // consensus which, unfortunately as of the time of this writing, does not check 316 // script versions before counting their signature operations which means nodes 317 // on existing rules will count new version scripts as if they were version 0. 318 func countSigOpsV0(script []byte, precise bool) int { 319 const scriptVersion = 0 320 321 numSigOps := 0 322 tokenizer := MakeScriptTokenizer(scriptVersion, script) 323 prevOp := byte(OP_INVALIDOPCODE) 324 for tokenizer.Next() { 325 switch tokenizer.Opcode() { 326 case OP_CHECKSIG, OP_CHECKSIGVERIFY: 327 numSigOps++ 328 329 case OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY: 330 // Note that OP_0 is treated as the max number of sigops here in 331 // precise mode despite it being a valid small integer in order to 332 // highly discourage multisigs with zero pubkeys. 333 // 334 // Also, even though this is referred to as "precise" counting, it's 335 // not really precise at all due to the small int opcodes only 336 // covering 1 through 16 pubkeys, which means this will count any 337 // more than that value (e.g. 17, 18 19) as the maximum number of 338 // allowed pubkeys. This is, unfortunately, now part of 339 // the Bitcoin consensus rules, due to historical 340 // reasons. This could be made more correct with a new 341 // script version, however, ideally all multisignaure 342 // operations in new script versions should move to 343 // aggregated schemes such as Schnorr instead. 344 if precise && prevOp >= OP_1 && prevOp <= OP_16 { 345 numSigOps += AsSmallInt(prevOp) 346 } else { 347 numSigOps += MaxPubKeysPerMultiSig 348 } 349 350 default: 351 // Not a sigop. 352 } 353 354 prevOp = tokenizer.Opcode() 355 } 356 357 return numSigOps 358 } 359 360 // GetSigOpCount provides a quick count of the number of signature operations 361 // in a script. a CHECKSIG operations counts for 1, and a CHECK_MULTISIG for 20. 362 // If the script fails to parse, then the count up to the point of failure is 363 // returned. 364 // 365 // WARNING: This function always treats the passed script as version 0. Great 366 // care must be taken if introducing a new script version because it is used in 367 // consensus which, unfortunately as of the time of this writing, does not check 368 // script versions before counting their signature operations which means nodes 369 // on existing rules will count new version scripts as if they were version 0. 370 func GetSigOpCount(script []byte) int { 371 return countSigOpsV0(script, false) 372 } 373 374 // finalOpcodeData returns the data associated with the final opcode in the 375 // script. It will return nil if the script fails to parse. 376 func finalOpcodeData(scriptVersion uint16, script []byte) []byte { 377 // Avoid unnecessary work. 378 if len(script) == 0 { 379 return nil 380 } 381 382 var data []byte 383 tokenizer := MakeScriptTokenizer(scriptVersion, script) 384 for tokenizer.Next() { 385 data = tokenizer.Data() 386 } 387 if tokenizer.Err() != nil { 388 return nil 389 } 390 return data 391 } 392 393 // GetPreciseSigOpCount returns the number of signature operations in 394 // scriptPubKey. If bip16 is true then scriptSig may be searched for the 395 // Pay-To-Script-Hash script in order to find the precise number of signature 396 // operations in the transaction. If the script fails to parse, then the count 397 // up to the point of failure is returned. 398 // 399 // WARNING: This function always treats the passed script as version 0. Great 400 // care must be taken if introducing a new script version because it is used in 401 // consensus which, unfortunately as of the time of this writing, does not check 402 // script versions before counting their signature operations which means nodes 403 // on existing rules will count new version scripts as if they were version 0. 404 // 405 // The third parameter is DEPRECATED and is unused. 406 func GetPreciseSigOpCount(scriptSig, scriptPubKey []byte, _ bool) int { 407 const scriptVersion = 0 408 409 // Treat non P2SH transactions as normal. Note that signature operation 410 // counting includes all operations up to the first parse failure. 411 if !isScriptHashScript(scriptPubKey) { 412 return countSigOpsV0(scriptPubKey, true) 413 } 414 415 // The signature script must only push data to the stack for P2SH to be 416 // a valid pair, so the signature operation count is 0 when that is not 417 // the case. 418 if len(scriptSig) == 0 || !IsPushOnlyScript(scriptSig) { 419 return 0 420 } 421 422 // The P2SH script is the last item the signature script pushes to the 423 // stack. When the script is empty, there are no signature operations. 424 // 425 // Notice that signature scripts that fail to fully parse count as 0 426 // signature operations unlike public key and redeem scripts. 427 redeemScript := finalOpcodeData(scriptVersion, scriptSig) 428 if len(redeemScript) == 0 { 429 return 0 430 } 431 432 // Return the more precise sigops count for the redeem script. Note that 433 // signature operation counting includes all operations up to the first 434 // parse failure. 435 return countSigOpsV0(redeemScript, true) 436 } 437 438 // GetWitnessSigOpCount returns the number of signature operations generated by 439 // spending the passed pkScript with the specified witness, or sigScript. 440 // Unlike GetPreciseSigOpCount, this function is able to accurately count the 441 // number of signature operations generated by spending witness programs, and 442 // nested p2sh witness programs. If the script fails to parse, then the count 443 // up to the point of failure is returned. 444 func GetWitnessSigOpCount(sigScript, pkScript []byte, witness wire.TxWitness) int { 445 // If this is a regular witness program, then we can proceed directly 446 // to counting its signature operations without any further processing. 447 if isWitnessProgramScript(pkScript) { 448 return getWitnessSigOps(pkScript, witness) 449 } 450 451 // Next, we'll check the sigScript to see if this is a nested p2sh 452 // witness program. This is a case wherein the sigScript is actually a 453 // datapush of a p2wsh witness program. 454 if isScriptHashScript(pkScript) && IsPushOnlyScript(sigScript) && 455 len(sigScript) > 0 && isWitnessProgramScript(sigScript[1:]) { 456 return getWitnessSigOps(sigScript[1:], witness) 457 } 458 459 return 0 460 } 461 462 // getWitnessSigOps returns the number of signature operations generated by 463 // spending the passed witness program wit the passed witness. The exact 464 // signature counting heuristic is modified by the version of the passed 465 // witness program. If the version of the witness program is unable to be 466 // extracted, then 0 is returned for the sig op count. 467 func getWitnessSigOps(pkScript []byte, witness wire.TxWitness) int { 468 // Attempt to extract the witness program version. 469 witnessVersion, witnessProgram, err := ExtractWitnessProgramInfo( 470 pkScript, 471 ) 472 if err != nil { 473 return 0 474 } 475 476 switch witnessVersion { 477 case BaseSegwitWitnessVersion: 478 switch { 479 case len(witnessProgram) == payToWitnessPubKeyHashDataSize: 480 return 1 481 case len(witnessProgram) == payToWitnessScriptHashDataSize && 482 len(witness) > 0: 483 484 witnessScript := witness[len(witness)-1] 485 return countSigOpsV0(witnessScript, true) 486 } 487 488 // Taproot signature operations don't count towards the block-wide sig 489 // op limit, instead a distinct weight-based accounting method is used. 490 case TaprootWitnessVersion: 491 return 0 492 } 493 494 return 0 495 } 496 497 // checkScriptParses returns an error if the provided script fails to parse. 498 func checkScriptParses(scriptVersion uint16, script []byte) error { 499 tokenizer := MakeScriptTokenizer(scriptVersion, script) 500 for tokenizer.Next() { 501 // Nothing to do. 502 } 503 return tokenizer.Err() 504 } 505 506 // IsUnspendable returns whether the passed public key script is unspendable, or 507 // guaranteed to fail at execution. This allows outputs to be pruned instantly 508 // when entering the UTXO set. 509 // 510 // NOTE: This function is only valid for version 0 scripts. Since the function 511 // does not accept a script version, the results are undefined for other script 512 // versions. 513 func IsUnspendable(pkScript []byte) bool { 514 // The script is unspendable if starts with OP_RETURN or is guaranteed 515 // to fail at execution due to being larger than the max allowed script 516 // size. 517 switch { 518 case len(pkScript) > 0 && pkScript[0] == OP_RETURN: 519 return true 520 case len(pkScript) > MaxScriptSize: 521 return true 522 } 523 524 // The script is unspendable if it is guaranteed to fail at execution. 525 const scriptVersion = 0 526 return checkScriptParses(scriptVersion, pkScript) != nil 527 } 528 529 // ScriptHasOpSuccess returns true if any op codes in the script contain an 530 // OP_SUCCESS op code. 531 func ScriptHasOpSuccess(witnessScript []byte) bool { 532 // First, create a new script tokenizer so we can run through all the 533 // elements. 534 tokenizer := MakeScriptTokenizer(0, witnessScript) 535 536 // Run through all the op codes, returning true if we find anything 537 // that is marked as a new op success. 538 for tokenizer.Next() { 539 if _, ok := successOpcodes[tokenizer.Opcode()]; ok { 540 return true 541 } 542 } 543 544 return false 545 }