NewEngine returns a new script engine for the provided public key script, transaction, and input index. The flags modify the behavior of the script engine according to the description provided by each flag.
(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags, sigCache *SigCache, hashCache *TxSigHashes, inputAmount int64, prevOutFetcher PrevOutputFetcher)
| 1582 | // transaction, and input index. The flags modify the behavior of the script |
| 1583 | // engine according to the description provided by each flag. |
| 1584 | func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags, |
| 1585 | sigCache *SigCache, hashCache *TxSigHashes, inputAmount int64, |
| 1586 | prevOutFetcher PrevOutputFetcher) (*Engine, error) { |
| 1587 | |
| 1588 | const scriptVersion = 0 |
| 1589 | |
| 1590 | // The provided transaction input index must refer to a valid input. |
| 1591 | if txIdx < 0 || txIdx >= len(tx.TxIn) { |
| 1592 | str := fmt.Sprintf("transaction input index %d is negative or "+ |
| 1593 | ">= %d", txIdx, len(tx.TxIn)) |
| 1594 | return nil, scriptError(ErrInvalidIndex, str) |
| 1595 | } |
| 1596 | scriptSig := tx.TxIn[txIdx].SignatureScript |
| 1597 | |
| 1598 | // When both the signature script and public key script are empty the result |
| 1599 | // is necessarily an error since the stack would end up being empty which is |
| 1600 | // equivalent to a false top element. Thus, just return the relevant error |
| 1601 | // now as an optimization. |
| 1602 | if len(scriptSig) == 0 && len(scriptPubKey) == 0 { |
| 1603 | return nil, scriptError(ErrEvalFalse, |
| 1604 | "false stack entry at end of script execution") |
| 1605 | } |
| 1606 | |
| 1607 | // The clean stack flag (ScriptVerifyCleanStack) is not allowed without |
| 1608 | // either the pay-to-script-hash (P2SH) evaluation (ScriptBip16) |
| 1609 | // flag or the Segregated Witness (ScriptVerifyWitness) flag. |
| 1610 | // |
| 1611 | // Recall that evaluating a P2SH script without the flag set results in |
| 1612 | // non-P2SH evaluation which leaves the P2SH inputs on the stack. |
| 1613 | // Thus, allowing the clean stack flag without the P2SH flag would make |
| 1614 | // it possible to have a situation where P2SH would not be a soft fork |
| 1615 | // when it should be. The same goes for segwit which will pull in |
| 1616 | // additional scripts for execution from the witness stack. |
| 1617 | vm := Engine{ |
| 1618 | flags: flags, |
| 1619 | sigCache: sigCache, |
| 1620 | hashCache: hashCache, |
| 1621 | inputAmount: inputAmount, |
| 1622 | prevOutFetcher: prevOutFetcher, |
| 1623 | } |
| 1624 | if vm.hasFlag(ScriptVerifyCleanStack) && (!vm.hasFlag(ScriptBip16) && |
| 1625 | !vm.hasFlag(ScriptVerifyWitness)) { |
| 1626 | return nil, scriptError(ErrInvalidFlags, |
| 1627 | "invalid flags combination") |
| 1628 | } |
| 1629 | |
| 1630 | // The signature script must only contain data pushes when the |
| 1631 | // associated flag is set. |
| 1632 | if vm.hasFlag(ScriptVerifySigPushOnly) && !IsPushOnlyScript(scriptSig) { |
| 1633 | return nil, scriptError(ErrNotPushOnly, |
| 1634 | "signature script is not push only") |
| 1635 | } |
| 1636 | |
| 1637 | // The signature script must only contain data pushes for PS2H which is |
| 1638 | // determined based on the form of the public key script. |
| 1639 | if vm.hasFlag(ScriptBip16) && isScriptHashScript(scriptPubKey) { |
| 1640 | // Only accept input scripts that push data for P2SH. |
| 1641 | // Notice that the push only checks have already been done when |
searching dependent graphs…