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