2014-08-27 14:11:41 -04:00
// Copyright (c) 2009-2010 Satoshi Nakamoto
2020-04-16 13:14:08 -04:00
// Copyright (c) 2009-2020 The Bitcoin Core developers
2014-09-09 05:00:42 -03:00
// Distributed under the MIT software license, see the accompanying
2014-08-27 14:11:41 -04:00
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
2017-11-09 21:57:53 -03:00
# include <script/interpreter.h>
# include <crypto/ripemd160.h>
# include <crypto/sha1.h>
# include <crypto/sha256.h>
# include <pubkey.h>
# include <script/script.h>
# include <uint256.h>
2014-08-27 14:11:41 -04:00
2017-01-04 02:42:14 -03:00
typedef std : : vector < unsigned char > valtype ;
2014-08-27 14:11:41 -04:00
2014-11-01 00:29:12 -03:00
namespace {
inline bool set_success ( ScriptError * ret )
{
if ( ret )
* ret = SCRIPT_ERR_OK ;
return true ;
}
inline bool set_error ( ScriptError * ret , const ScriptError serror )
{
if ( ret )
* ret = serror ;
return false ;
}
2017-05-31 16:21:25 -04:00
} // namespace
2014-11-01 00:29:12 -03:00
2014-08-27 14:11:41 -04:00
bool CastToBool ( const valtype & vch )
{
for ( unsigned int i = 0 ; i < vch . size ( ) ; i + + )
{
if ( vch [ i ] ! = 0 )
{
// Can be negative zero
if ( i = = vch . size ( ) - 1 & & vch [ i ] = = 0x80 )
return false ;
return true ;
}
}
return false ;
}
2014-11-10 03:40:01 -03:00
/**
* Script is a stack machine ( like Forth ) that evaluates a predicate
* returning a bool indicating valid or not . There are no loops .
*/
2014-08-27 14:11:41 -04:00
# define stacktop(i) (stack.at(stack.size()+(i)))
# define altstacktop(i) (altstack.at(altstack.size()+(i)))
2017-01-04 02:42:14 -03:00
static inline void popstack ( std : : vector < valtype > & stack )
2014-08-27 14:11:41 -04:00
{
if ( stack . empty ( ) )
2017-01-04 02:42:14 -03:00
throw std : : runtime_error ( " popstack(): stack empty " ) ;
2014-08-27 14:11:41 -04:00
stack . pop_back ( ) ;
}
2014-10-06 21:22:47 -03:00
bool static IsCompressedOrUncompressedPubKey ( const valtype & vchPubKey ) {
2018-04-12 17:30:04 -03:00
if ( vchPubKey . size ( ) < CPubKey : : COMPRESSED_SIZE ) {
2014-11-01 00:29:12 -03:00
// Non-canonical public key: too short
return false ;
}
2014-08-27 14:11:41 -04:00
if ( vchPubKey [ 0 ] = = 0x04 ) {
2018-04-12 17:30:04 -03:00
if ( vchPubKey . size ( ) ! = CPubKey : : SIZE ) {
2014-11-01 00:29:12 -03:00
// Non-canonical public key: invalid length for uncompressed key
return false ;
}
2014-08-27 14:11:41 -04:00
} else if ( vchPubKey [ 0 ] = = 0x02 | | vchPubKey [ 0 ] = = 0x03 ) {
2018-04-12 17:30:04 -03:00
if ( vchPubKey . size ( ) ! = CPubKey : : COMPRESSED_SIZE ) {
2014-11-01 00:29:12 -03:00
// Non-canonical public key: invalid length for compressed key
return false ;
}
2014-08-27 14:11:41 -04:00
} else {
2016-10-01 14:19:33 -03:00
// Non-canonical public key: neither compressed nor uncompressed
return false ;
}
return true ;
}
bool static IsCompressedPubKey ( const valtype & vchPubKey ) {
2018-04-12 17:30:04 -03:00
if ( vchPubKey . size ( ) ! = CPubKey : : COMPRESSED_SIZE ) {
2016-10-01 14:19:33 -03:00
// Non-canonical public key: invalid length for compressed key
return false ;
}
if ( vchPubKey [ 0 ] ! = 0x02 & & vchPubKey [ 0 ] ! = 0x03 ) {
// Non-canonical public key: invalid prefix for compressed key
return false ;
2014-08-27 14:11:41 -04:00
}
return true ;
}
2014-11-10 03:40:01 -03:00
/**
* A canonical signature exists of : < 30 > < total len > < 02 > < len R > < R > < 02 > < len S > < S > < hashtype >
* Where R and S are not negative ( their first byte has its highest bit not set ) , and not
* excessively padded ( do not start with a 0 byte , unless an otherwise negative number follows ,
* in which case a single 0 byte is necessary and even required ) .
2018-07-24 11:59:49 -04:00
*
2014-11-10 03:40:01 -03:00
* See https : //bitcointalk.org/index.php?topic=8392.msg127623#msg127623
2015-01-12 23:15:39 -03:00
*
* This function is consensus - critical since BIP66 .
2014-11-10 03:40:01 -03:00
*/
2015-01-12 23:15:39 -03:00
bool static IsValidSignatureEncoding ( const std : : vector < unsigned char > & sig ) {
// Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] [sighash]
// * total-length: 1-byte length descriptor of everything that follows,
// excluding the sighash byte.
// * R-length: 1-byte length descriptor of the R value that follows.
// * R: arbitrary-length big-endian encoded R value. It must use the shortest
2018-03-18 11:26:45 -03:00
// possible encoding for a positive integer (which means no null bytes at
2015-01-12 23:15:39 -03:00
// the start, except a single one when the next byte has its highest bit set).
// * S-length: 1-byte length descriptor of the S value that follows.
// * S: arbitrary-length big-endian encoded S value. The same rules apply.
// * sighash: 1-byte value indicating what data is hashed (not part of the DER
// signature)
2014-11-10 03:40:01 -03:00
2015-01-12 23:15:39 -03:00
// Minimum and maximum size constraints.
if ( sig . size ( ) < 9 ) return false ;
if ( sig . size ( ) > 73 ) return false ;
2014-08-27 14:11:41 -04:00
2015-01-12 23:15:39 -03:00
// A signature is of type 0x30 (compound).
if ( sig [ 0 ] ! = 0x30 ) return false ;
// Make sure the length covers the entire signature.
if ( sig [ 1 ] ! = sig . size ( ) - 3 ) return false ;
// Extract the length of the R element.
unsigned int lenR = sig [ 3 ] ;
// Make sure the length of the S element is still inside the signature.
if ( 5 + lenR > = sig . size ( ) ) return false ;
// Extract the length of the S element.
unsigned int lenS = sig [ 5 + lenR ] ;
// Verify that the length of the signature matches the sum of the length
// of the elements.
if ( ( size_t ) ( lenR + lenS + 7 ) ! = sig . size ( ) ) return false ;
2018-07-24 11:59:49 -04:00
2015-01-12 23:15:39 -03:00
// Check whether the R element is an integer.
if ( sig [ 2 ] ! = 0x02 ) return false ;
// Zero-length integers are not allowed for R.
if ( lenR = = 0 ) return false ;
// Negative numbers are not allowed for R.
if ( sig [ 4 ] & 0x80 ) return false ;
// Null bytes at the start of R are not allowed, unless R would
// otherwise be interpreted as a negative number.
if ( lenR > 1 & & ( sig [ 4 ] = = 0x00 ) & & ! ( sig [ 5 ] & 0x80 ) ) return false ;
// Check whether the S element is an integer.
if ( sig [ lenR + 4 ] ! = 0x02 ) return false ;
// Zero-length integers are not allowed for S.
if ( lenS = = 0 ) return false ;
// Negative numbers are not allowed for S.
if ( sig [ lenR + 6 ] & 0x80 ) return false ;
// Null bytes at the start of S are not allowed, unless S would otherwise be
// interpreted as a negative number.
if ( lenS > 1 & & ( sig [ lenR + 6 ] = = 0x00 ) & & ! ( sig [ lenR + 7 ] & 0x80 ) ) return false ;
2014-08-27 14:11:41 -04:00
2014-10-06 21:22:47 -03:00
return true ;
}
2014-11-01 00:29:12 -03:00
bool static IsLowDERSignature ( const valtype & vchSig , ScriptError * serror ) {
2015-01-12 23:15:39 -03:00
if ( ! IsValidSignatureEncoding ( vchSig ) ) {
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_SIG_DER ) ;
2014-08-27 14:11:41 -04:00
}
2017-06-06 01:44:17 -04:00
// https://bitcoin.stackexchange.com/a/12556:
// Also note that inside transaction signatures, an extra hashtype byte
// follows the actual signature data.
2015-07-28 15:11:20 -03:00
std : : vector < unsigned char > vchSigCopy ( vchSig . begin ( ) , vchSig . begin ( ) + vchSig . size ( ) - 1 ) ;
2017-06-06 01:44:17 -04:00
// If the S value is above the order of the curve divided by two, its
// complement modulo the order could have been used instead, which is
// one byte shorter when encoded correctly.
2016-02-10 10:19:20 -03:00
if ( ! CPubKey : : CheckLowS ( vchSigCopy ) ) {
return set_error ( serror , SCRIPT_ERR_SIG_HIGH_S ) ;
}
return true ;
2014-08-27 14:11:41 -04:00
}
2014-10-06 21:22:47 -03:00
bool static IsDefinedHashtypeSignature ( const valtype & vchSig ) {
if ( vchSig . size ( ) = = 0 ) {
return false ;
}
unsigned char nHashType = vchSig [ vchSig . size ( ) - 1 ] & ( ~ ( SIGHASH_ANYONECANPAY ) ) ;
if ( nHashType < SIGHASH_ALL | | nHashType > SIGHASH_SINGLE )
2014-11-01 00:29:12 -03:00
return false ;
2014-10-06 21:22:47 -03:00
return true ;
}
2017-01-04 02:42:14 -03:00
bool CheckSignatureEncoding ( const std : : vector < unsigned char > & vchSig , unsigned int flags , ScriptError * serror ) {
2015-01-09 07:52:57 -03:00
// Empty signature. Not strictly DER encoded, but allowed to provide a
// compact way to provide an invalid signature for use with CHECK(MULTI)SIG
if ( vchSig . size ( ) = = 0 ) {
return true ;
}
2015-01-12 23:15:39 -03:00
if ( ( flags & ( SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC ) ) ! = 0 & & ! IsValidSignatureEncoding ( vchSig ) ) {
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_SIG_DER ) ;
} else if ( ( flags & SCRIPT_VERIFY_LOW_S ) ! = 0 & & ! IsLowDERSignature ( vchSig , serror ) ) {
// serror is set
2014-10-06 21:22:47 -03:00
return false ;
} else if ( ( flags & SCRIPT_VERIFY_STRICTENC ) ! = 0 & & ! IsDefinedHashtypeSignature ( vchSig ) ) {
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_SIG_HASHTYPE ) ;
2014-10-06 21:22:47 -03:00
}
return true ;
}
2016-10-01 14:19:33 -03:00
bool static CheckPubKeyEncoding ( const valtype & vchPubKey , unsigned int flags , const SigVersion & sigversion , ScriptError * serror ) {
if ( ( flags & SCRIPT_VERIFY_STRICTENC ) ! = 0 & & ! IsCompressedOrUncompressedPubKey ( vchPubKey ) ) {
2014-11-08 14:32:29 -03:00
return set_error ( serror , SCRIPT_ERR_PUBKEYTYPE ) ;
2014-10-06 21:22:47 -03:00
}
2016-10-01 14:19:33 -03:00
// Only compressed keys are accepted in segwit
2018-03-09 11:03:40 -03:00
if ( ( flags & SCRIPT_VERIFY_WITNESS_PUBKEYTYPE ) ! = 0 & & sigversion = = SigVersion : : WITNESS_V0 & & ! IsCompressedPubKey ( vchPubKey ) ) {
2016-10-01 14:19:33 -03:00
return set_error ( serror , SCRIPT_ERR_WITNESS_PUBKEYTYPE ) ;
}
2014-10-06 21:22:47 -03:00
return true ;
}
2014-10-08 22:48:59 -03:00
bool static CheckMinimalPush ( const valtype & data , opcodetype opcode ) {
2017-12-14 16:04:47 -03:00
// Excludes OP_1NEGATE, OP_1-16 since they are by definition minimal
assert ( 0 < = opcode & & opcode < = OP_PUSHDATA4 ) ;
2014-10-08 22:48:59 -03:00
if ( data . size ( ) = = 0 ) {
2018-03-07 12:49:28 -03:00
// Should have used OP_0.
2014-10-08 22:48:59 -03:00
return opcode = = OP_0 ;
} else if ( data . size ( ) = = 1 & & data [ 0 ] > = 1 & & data [ 0 ] < = 16 ) {
2018-03-07 12:49:28 -03:00
// Should have used OP_1 .. OP_16.
2017-12-14 16:04:47 -03:00
return false ;
2014-10-08 22:48:59 -03:00
} else if ( data . size ( ) = = 1 & & data [ 0 ] = = 0x81 ) {
2018-03-07 12:49:28 -03:00
// Should have used OP_1NEGATE.
2017-12-14 16:04:47 -03:00
return false ;
2014-10-08 22:48:59 -03:00
} else if ( data . size ( ) < = 75 ) {
2018-03-07 12:49:28 -03:00
// Must have used a direct push (opcode indicating number of bytes pushed + those bytes).
2014-10-08 22:48:59 -03:00
return opcode = = data . size ( ) ;
} else if ( data . size ( ) < = 255 ) {
2018-03-07 12:49:28 -03:00
// Must have used OP_PUSHDATA.
2014-10-08 22:48:59 -03:00
return opcode = = OP_PUSHDATA1 ;
} else if ( data . size ( ) < = 65535 ) {
2018-03-07 12:49:28 -03:00
// Must have used OP_PUSHDATA2.
2014-10-08 22:48:59 -03:00
return opcode = = OP_PUSHDATA2 ;
}
return true ;
}
2018-04-04 13:02:24 -03:00
int FindAndDelete ( CScript & script , const CScript & b )
{
int nFound = 0 ;
if ( b . empty ( ) )
return nFound ;
CScript result ;
CScript : : const_iterator pc = script . begin ( ) , pc2 = script . begin ( ) , end = script . end ( ) ;
opcodetype opcode ;
do
{
result . insert ( result . end ( ) , pc2 , pc ) ;
while ( static_cast < size_t > ( end - pc ) > = b . size ( ) & & std : : equal ( b . begin ( ) , b . end ( ) , pc ) )
{
pc = pc + b . size ( ) ;
+ + nFound ;
}
pc2 = pc ;
}
while ( script . GetOp ( pc , opcode ) ) ;
if ( nFound > 0 ) {
result . insert ( result . end ( ) , pc2 , end ) ;
script = std : : move ( result ) ;
}
return nFound ;
}
2019-09-18 02:49:29 -03:00
namespace {
/** A data type to abstract out the condition stack during script execution.
*
* Conceptually it acts like a vector of booleans , one for each level of nested
* IF / THEN / ELSE , indicating whether we ' re in the active or inactive branch of
* each .
*
* The elements on the stack cannot be observed individually ; we only need to
* expose whether the stack is empty and whether or not any false values are
* present at all . To implement OP_ELSE , a toggle_top modifier is added , which
* flips the last value without returning it .
2019-11-04 15:54:38 -03:00
*
* This uses an optimized implementation that does not materialize the
* actual stack . Instead , it just stores the size of the would - be stack ,
* and the position of the first false value in it .
2019-09-18 02:49:29 -03:00
*/
class ConditionStack {
private :
2019-11-04 15:54:38 -03:00
//! A constant for m_first_false_pos to indicate there are no falses.
static constexpr uint32_t NO_FALSE = std : : numeric_limits < uint32_t > : : max ( ) ;
//! The size of the implied stack.
uint32_t m_stack_size = 0 ;
//! The position of the first false value on the implied stack, or NO_FALSE if all true.
uint32_t m_first_false_pos = NO_FALSE ;
2019-09-18 02:49:29 -03:00
public :
2019-11-04 15:54:38 -03:00
bool empty ( ) { return m_stack_size = = 0 ; }
bool all_true ( ) { return m_first_false_pos = = NO_FALSE ; }
void push_back ( bool f )
{
if ( m_first_false_pos = = NO_FALSE & & ! f ) {
// The stack consists of all true values, and a false is added.
// The first false value will appear at the current size.
m_first_false_pos = m_stack_size ;
}
+ + m_stack_size ;
}
void pop_back ( )
{
assert ( m_stack_size > 0 ) ;
- - m_stack_size ;
if ( m_first_false_pos = = m_stack_size ) {
// When popping off the first false value, everything becomes true.
m_first_false_pos = NO_FALSE ;
}
}
void toggle_top ( )
{
assert ( m_stack_size > 0 ) ;
if ( m_first_false_pos = = NO_FALSE ) {
// The current stack is all true values; the first false will be the top.
m_first_false_pos = m_stack_size - 1 ;
} else if ( m_first_false_pos = = m_stack_size - 1 ) {
// The top is the first false value; toggling it will make everything true.
m_first_false_pos = NO_FALSE ;
} else {
// There is a false value, but not on top. No action is needed as toggling
// anything but the first false value is unobservable.
}
}
2019-09-18 02:49:29 -03:00
} ;
}
2019-10-18 19:23:42 -03:00
/** Helper for OP_CHECKSIG and OP_CHECKSIGVERIFY
*
* A return value of false means the script fails entirely . When true is returned , the
* fSuccess variable indicates whether the signature check itself succeeded .
*/
static bool EvalChecksig ( const valtype & vchSig , const valtype & vchPubKey , CScript : : const_iterator pbegincodehash , CScript : : const_iterator pend , unsigned int flags , const BaseSignatureChecker & checker , SigVersion sigversion , ScriptError * serror , bool & fSuccess )
{
// Subset of script starting at the most recent codeseparator
CScript scriptCode ( pbegincodehash , pend ) ;
// Drop the signature in pre-segwit scripts but not segwit scripts
if ( sigversion = = SigVersion : : BASE ) {
int found = FindAndDelete ( scriptCode , CScript ( ) < < vchSig ) ;
if ( found > 0 & & ( flags & SCRIPT_VERIFY_CONST_SCRIPTCODE ) )
return set_error ( serror , SCRIPT_ERR_SIG_FINDANDDELETE ) ;
}
if ( ! CheckSignatureEncoding ( vchSig , flags , serror ) | | ! CheckPubKeyEncoding ( vchPubKey , flags , sigversion , serror ) ) {
//serror is set
return false ;
}
2020-09-11 18:33:23 -03:00
fSuccess = checker . CheckECDSASignature ( vchSig , vchPubKey , scriptCode , sigversion ) ;
2019-10-18 19:23:42 -03:00
if ( ! fSuccess & & ( flags & SCRIPT_VERIFY_NULLFAIL ) & & vchSig . size ( ) )
return set_error ( serror , SCRIPT_ERR_SIG_NULLFAIL ) ;
return true ;
}
2017-01-04 02:42:14 -03:00
bool EvalScript ( std : : vector < std : : vector < unsigned char > > & stack , const CScript & script , unsigned int flags , const BaseSignatureChecker & checker , SigVersion sigversion , ScriptError * serror )
2014-08-27 14:11:41 -04:00
{
2014-11-24 16:49:43 -03:00
static const CScriptNum bnZero ( 0 ) ;
static const CScriptNum bnOne ( 1 ) ;
2017-03-28 03:40:16 -03:00
// static const CScriptNum bnFalse(0);
// static const CScriptNum bnTrue(1);
2014-11-24 16:49:43 -03:00
static const valtype vchFalse ( 0 ) ;
2017-03-28 03:40:16 -03:00
// static const valtype vchZero(0);
2014-11-24 16:49:43 -03:00
static const valtype vchTrue ( 1 , 1 ) ;
2014-08-27 14:11:41 -04:00
CScript : : const_iterator pc = script . begin ( ) ;
CScript : : const_iterator pend = script . end ( ) ;
CScript : : const_iterator pbegincodehash = script . begin ( ) ;
opcodetype opcode ;
valtype vchPushValue ;
2019-09-18 02:49:29 -03:00
ConditionStack vfExec ;
2017-01-04 02:42:14 -03:00
std : : vector < valtype > altstack ;
2014-11-01 00:29:12 -03:00
set_error ( serror , SCRIPT_ERR_UNKNOWN_ERROR ) ;
2016-04-25 07:31:45 -03:00
if ( script . size ( ) > MAX_SCRIPT_SIZE )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_SCRIPT_SIZE ) ;
2014-08-27 14:11:41 -04:00
int nOpCount = 0 ;
2014-10-08 22:48:59 -03:00
bool fRequireMinimal = ( flags & SCRIPT_VERIFY_MINIMALDATA ) ! = 0 ;
2014-08-27 14:11:41 -04:00
try
{
while ( pc < pend )
{
2019-09-18 02:49:29 -03:00
bool fExec = vfExec . all_true ( ) ;
2014-08-27 14:11:41 -04:00
//
// Read instruction
//
if ( ! script . GetOp ( pc , opcode , vchPushValue ) )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_BAD_OPCODE ) ;
2014-08-27 14:11:41 -04:00
if ( vchPushValue . size ( ) > MAX_SCRIPT_ELEMENT_SIZE )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_PUSH_SIZE ) ;
2014-08-27 14:11:41 -04:00
// Note how OP_RESERVED does not count towards the opcode limit.
2015-10-13 10:56:45 -03:00
if ( opcode > OP_16 & & + + nOpCount > MAX_OPS_PER_SCRIPT )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_OP_COUNT ) ;
2014-08-27 14:11:41 -04:00
if ( opcode = = OP_CAT | |
opcode = = OP_SUBSTR | |
opcode = = OP_LEFT | |
opcode = = OP_RIGHT | |
opcode = = OP_INVERT | |
opcode = = OP_AND | |
opcode = = OP_OR | |
opcode = = OP_XOR | |
opcode = = OP_2MUL | |
opcode = = OP_2DIV | |
opcode = = OP_MUL | |
opcode = = OP_DIV | |
opcode = = OP_MOD | |
opcode = = OP_LSHIFT | |
opcode = = OP_RSHIFT )
2018-11-10 14:11:22 -03:00
return set_error ( serror , SCRIPT_ERR_DISABLED_OPCODE ) ; // Disabled opcodes (CVE-2010-5137).
2014-08-27 14:11:41 -04:00
2018-04-26 16:56:29 -03:00
// With SCRIPT_VERIFY_CONST_SCRIPTCODE, OP_CODESEPARATOR in non-segwit script is rejected even in an unexecuted branch
if ( opcode = = OP_CODESEPARATOR & & sigversion = = SigVersion : : BASE & & ( flags & SCRIPT_VERIFY_CONST_SCRIPTCODE ) )
return set_error ( serror , SCRIPT_ERR_OP_CODESEPARATOR ) ;
2014-10-08 22:48:59 -03:00
if ( fExec & & 0 < = opcode & & opcode < = OP_PUSHDATA4 ) {
if ( fRequireMinimal & & ! CheckMinimalPush ( vchPushValue , opcode ) ) {
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_MINIMALDATA ) ;
2014-10-08 22:48:59 -03:00
}
2014-08-27 14:11:41 -04:00
stack . push_back ( vchPushValue ) ;
2014-10-08 22:48:59 -03:00
} else if ( fExec | | ( OP_IF < = opcode & & opcode < = OP_ENDIF ) )
2014-08-27 14:11:41 -04:00
switch ( opcode )
{
//
// Push value
//
case OP_1NEGATE :
case OP_1 :
case OP_2 :
case OP_3 :
case OP_4 :
case OP_5 :
case OP_6 :
case OP_7 :
case OP_8 :
case OP_9 :
case OP_10 :
case OP_11 :
case OP_12 :
case OP_13 :
case OP_14 :
case OP_15 :
case OP_16 :
{
// ( -- value)
CScriptNum bn ( ( int ) opcode - ( int ) ( OP_1 - 1 ) ) ;
stack . push_back ( bn . getvch ( ) ) ;
2014-10-08 22:48:59 -03:00
// The result of these opcodes should always be the minimal way to push the data
// they push, so no need for a CheckMinimalPush here.
2014-08-27 14:11:41 -04:00
}
break ;
//
// Control
//
case OP_NOP :
2014-09-29 04:44:25 -03:00
break ;
case OP_CHECKLOCKTIMEVERIFY :
{
if ( ! ( flags & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY ) ) {
// not enabled; treat as a NOP2
break ;
}
if ( stack . size ( ) < 1 )
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
// Note that elsewhere numeric opcodes are limited to
// operands in the range -2**31+1 to 2**31-1, however it is
// legal for opcodes to produce results exceeding that
// range. This limitation is implemented by CScriptNum's
// default 4-byte limit.
//
// If we kept to that limit we'd have a year 2038 problem,
// even though the nLockTime field in transactions
// themselves is uint32 which only becomes meaningless
// after the year 2106.
//
// Thus as a special case we tell CScriptNum to accept up
// to 5-byte bignums, which are good until 2**39-1, well
// beyond the 2**32-1 limit of the nLockTime field itself.
const CScriptNum nLockTime ( stacktop ( - 1 ) , fRequireMinimal , 5 ) ;
// In the rare event that the argument may be < 0 due to
// some arithmetic being done first, you can always use
// 0 MAX CHECKLOCKTIMEVERIFY.
if ( nLockTime < 0 )
return set_error ( serror , SCRIPT_ERR_NEGATIVE_LOCKTIME ) ;
// Actually compare the specified lock time with the transaction.
if ( ! checker . CheckLockTime ( nLockTime ) )
return set_error ( serror , SCRIPT_ERR_UNSATISFIED_LOCKTIME ) ;
break ;
}
2014-09-28 22:17:36 -03:00
2015-09-25 20:18:51 -03:00
case OP_CHECKSEQUENCEVERIFY :
{
if ( ! ( flags & SCRIPT_VERIFY_CHECKSEQUENCEVERIFY ) ) {
// not enabled; treat as a NOP3
break ;
}
if ( stack . size ( ) < 1 )
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
// nSequence, like nLockTime, is a 32-bit unsigned integer
// field. See the comment in CHECKLOCKTIMEVERIFY regarding
// 5-byte numeric operands.
const CScriptNum nSequence ( stacktop ( - 1 ) , fRequireMinimal , 5 ) ;
// In the rare event that the argument may be < 0 due to
// some arithmetic being done first, you can always use
// 0 MAX CHECKSEQUENCEVERIFY.
if ( nSequence < 0 )
return set_error ( serror , SCRIPT_ERR_NEGATIVE_LOCKTIME ) ;
// To provide for future soft-fork extensibility, if the
// operand has the disabled lock-time flag set,
// CHECKSEQUENCEVERIFY behaves as a NOP.
if ( ( nSequence & CTxIn : : SEQUENCE_LOCKTIME_DISABLE_FLAG ) ! = 0 )
break ;
// Compare the specified sequence number with the input.
if ( ! checker . CheckSequence ( nSequence ) )
return set_error ( serror , SCRIPT_ERR_UNSATISFIED_LOCKTIME ) ;
break ;
}
case OP_NOP1 : case OP_NOP4 : case OP_NOP5 :
2014-08-27 14:11:41 -04:00
case OP_NOP6 : case OP_NOP7 : case OP_NOP8 : case OP_NOP9 : case OP_NOP10 :
2014-09-28 22:17:36 -03:00
{
if ( flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS )
return set_error ( serror , SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS ) ;
}
2014-08-27 14:11:41 -04:00
break ;
case OP_IF :
case OP_NOTIF :
{
// <expression> if [statements] [else [statements]] endif
bool fValue = false ;
if ( fExec )
{
if ( stack . size ( ) < 1 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_UNBALANCED_CONDITIONAL ) ;
2014-08-27 14:11:41 -04:00
valtype & vch = stacktop ( - 1 ) ;
2018-03-09 11:03:40 -03:00
if ( sigversion = = SigVersion : : WITNESS_V0 & & ( flags & SCRIPT_VERIFY_MINIMALIF ) ) {
2016-09-23 02:06:45 -03:00
if ( vch . size ( ) > 1 )
return set_error ( serror , SCRIPT_ERR_MINIMALIF ) ;
if ( vch . size ( ) = = 1 & & vch [ 0 ] ! = 1 )
return set_error ( serror , SCRIPT_ERR_MINIMALIF ) ;
}
2014-08-27 14:11:41 -04:00
fValue = CastToBool ( vch ) ;
if ( opcode = = OP_NOTIF )
fValue = ! fValue ;
popstack ( stack ) ;
}
vfExec . push_back ( fValue ) ;
}
break ;
case OP_ELSE :
{
if ( vfExec . empty ( ) )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_UNBALANCED_CONDITIONAL ) ;
2019-09-18 02:49:29 -03:00
vfExec . toggle_top ( ) ;
2014-08-27 14:11:41 -04:00
}
break ;
case OP_ENDIF :
{
if ( vfExec . empty ( ) )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_UNBALANCED_CONDITIONAL ) ;
2014-08-27 14:11:41 -04:00
vfExec . pop_back ( ) ;
}
break ;
case OP_VERIFY :
{
// (true -- ) or
// (false -- false) and return
if ( stack . size ( ) < 1 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
bool fValue = CastToBool ( stacktop ( - 1 ) ) ;
if ( fValue )
popstack ( stack ) ;
else
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_VERIFY ) ;
2014-08-27 14:11:41 -04:00
}
break ;
case OP_RETURN :
{
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_OP_RETURN ) ;
2014-08-27 14:11:41 -04:00
}
break ;
//
// Stack ops
//
case OP_TOALTSTACK :
{
if ( stack . size ( ) < 1 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
altstack . push_back ( stacktop ( - 1 ) ) ;
popstack ( stack ) ;
}
break ;
case OP_FROMALTSTACK :
{
if ( altstack . size ( ) < 1 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_ALTSTACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
stack . push_back ( altstacktop ( - 1 ) ) ;
popstack ( altstack ) ;
}
break ;
case OP_2DROP :
{
// (x1 x2 -- )
if ( stack . size ( ) < 2 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
popstack ( stack ) ;
popstack ( stack ) ;
}
break ;
case OP_2DUP :
{
// (x1 x2 -- x1 x2 x1 x2)
if ( stack . size ( ) < 2 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
valtype vch1 = stacktop ( - 2 ) ;
valtype vch2 = stacktop ( - 1 ) ;
stack . push_back ( vch1 ) ;
stack . push_back ( vch2 ) ;
}
break ;
case OP_3DUP :
{
// (x1 x2 x3 -- x1 x2 x3 x1 x2 x3)
if ( stack . size ( ) < 3 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
valtype vch1 = stacktop ( - 3 ) ;
valtype vch2 = stacktop ( - 2 ) ;
valtype vch3 = stacktop ( - 1 ) ;
stack . push_back ( vch1 ) ;
stack . push_back ( vch2 ) ;
stack . push_back ( vch3 ) ;
}
break ;
case OP_2OVER :
{
// (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2)
if ( stack . size ( ) < 4 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
valtype vch1 = stacktop ( - 4 ) ;
valtype vch2 = stacktop ( - 3 ) ;
stack . push_back ( vch1 ) ;
stack . push_back ( vch2 ) ;
}
break ;
case OP_2ROT :
{
// (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2)
if ( stack . size ( ) < 6 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
valtype vch1 = stacktop ( - 6 ) ;
valtype vch2 = stacktop ( - 5 ) ;
stack . erase ( stack . end ( ) - 6 , stack . end ( ) - 4 ) ;
stack . push_back ( vch1 ) ;
stack . push_back ( vch2 ) ;
}
break ;
case OP_2SWAP :
{
// (x1 x2 x3 x4 -- x3 x4 x1 x2)
if ( stack . size ( ) < 4 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
swap ( stacktop ( - 4 ) , stacktop ( - 2 ) ) ;
swap ( stacktop ( - 3 ) , stacktop ( - 1 ) ) ;
}
break ;
case OP_IFDUP :
{
// (x - 0 | x x)
if ( stack . size ( ) < 1 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
valtype vch = stacktop ( - 1 ) ;
if ( CastToBool ( vch ) )
stack . push_back ( vch ) ;
}
break ;
case OP_DEPTH :
{
// -- stacksize
CScriptNum bn ( stack . size ( ) ) ;
stack . push_back ( bn . getvch ( ) ) ;
}
break ;
case OP_DROP :
{
// (x -- )
if ( stack . size ( ) < 1 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
popstack ( stack ) ;
}
break ;
case OP_DUP :
{
// (x -- x x)
if ( stack . size ( ) < 1 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
valtype vch = stacktop ( - 1 ) ;
stack . push_back ( vch ) ;
}
break ;
case OP_NIP :
{
// (x1 x2 -- x2)
if ( stack . size ( ) < 2 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
stack . erase ( stack . end ( ) - 2 ) ;
}
break ;
case OP_OVER :
{
// (x1 x2 -- x1 x2 x1)
if ( stack . size ( ) < 2 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
valtype vch = stacktop ( - 2 ) ;
stack . push_back ( vch ) ;
}
break ;
case OP_PICK :
case OP_ROLL :
{
// (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn)
// (xn ... x2 x1 x0 n - ... x2 x1 x0 xn)
if ( stack . size ( ) < 2 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-10-08 22:48:59 -03:00
int n = CScriptNum ( stacktop ( - 1 ) , fRequireMinimal ) . getint ( ) ;
2014-08-27 14:11:41 -04:00
popstack ( stack ) ;
if ( n < 0 | | n > = ( int ) stack . size ( ) )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
valtype vch = stacktop ( - n - 1 ) ;
if ( opcode = = OP_ROLL )
stack . erase ( stack . end ( ) - n - 1 ) ;
stack . push_back ( vch ) ;
}
break ;
case OP_ROT :
{
// (x1 x2 x3 -- x2 x3 x1)
// x2 x1 x3 after first swap
// x2 x3 x1 after second swap
if ( stack . size ( ) < 3 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
swap ( stacktop ( - 3 ) , stacktop ( - 2 ) ) ;
swap ( stacktop ( - 2 ) , stacktop ( - 1 ) ) ;
}
break ;
case OP_SWAP :
{
// (x1 x2 -- x2 x1)
if ( stack . size ( ) < 2 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
swap ( stacktop ( - 2 ) , stacktop ( - 1 ) ) ;
}
break ;
case OP_TUCK :
{
// (x1 x2 -- x2 x1 x2)
if ( stack . size ( ) < 2 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
valtype vch = stacktop ( - 1 ) ;
stack . insert ( stack . end ( ) - 2 , vch ) ;
}
break ;
case OP_SIZE :
{
// (in -- in size)
if ( stack . size ( ) < 1 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
CScriptNum bn ( stacktop ( - 1 ) . size ( ) ) ;
stack . push_back ( bn . getvch ( ) ) ;
}
break ;
//
// Bitwise logic
//
case OP_EQUAL :
case OP_EQUALVERIFY :
//case OP_NOTEQUAL: // use OP_NUMNOTEQUAL
{
// (x1 x2 - bool)
if ( stack . size ( ) < 2 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
valtype & vch1 = stacktop ( - 2 ) ;
valtype & vch2 = stacktop ( - 1 ) ;
bool fEqual = ( vch1 = = vch2 ) ;
// OP_NOTEQUAL is disabled because it would be too easy to say
// something like n != 1 and have some wiseguy pass in 1 with extra
// zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001)
//if (opcode == OP_NOTEQUAL)
// fEqual = !fEqual;
popstack ( stack ) ;
popstack ( stack ) ;
stack . push_back ( fEqual ? vchTrue : vchFalse ) ;
if ( opcode = = OP_EQUALVERIFY )
{
if ( fEqual )
popstack ( stack ) ;
else
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_EQUALVERIFY ) ;
2014-08-27 14:11:41 -04:00
}
}
break ;
//
// Numeric
//
case OP_1ADD :
case OP_1SUB :
case OP_NEGATE :
case OP_ABS :
case OP_NOT :
case OP_0NOTEQUAL :
{
// (in -- out)
if ( stack . size ( ) < 1 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-10-08 22:48:59 -03:00
CScriptNum bn ( stacktop ( - 1 ) , fRequireMinimal ) ;
2014-08-27 14:11:41 -04:00
switch ( opcode )
{
case OP_1ADD : bn + = bnOne ; break ;
case OP_1SUB : bn - = bnOne ; break ;
case OP_NEGATE : bn = - bn ; break ;
case OP_ABS : if ( bn < bnZero ) bn = - bn ; break ;
case OP_NOT : bn = ( bn = = bnZero ) ; break ;
case OP_0NOTEQUAL : bn = ( bn ! = bnZero ) ; break ;
default : assert ( ! " invalid opcode " ) ; break ;
}
popstack ( stack ) ;
stack . push_back ( bn . getvch ( ) ) ;
}
break ;
case OP_ADD :
case OP_SUB :
case OP_BOOLAND :
case OP_BOOLOR :
case OP_NUMEQUAL :
case OP_NUMEQUALVERIFY :
case OP_NUMNOTEQUAL :
case OP_LESSTHAN :
case OP_GREATERTHAN :
case OP_LESSTHANOREQUAL :
case OP_GREATERTHANOREQUAL :
case OP_MIN :
case OP_MAX :
{
// (x1 x2 -- out)
if ( stack . size ( ) < 2 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-10-08 22:48:59 -03:00
CScriptNum bn1 ( stacktop ( - 2 ) , fRequireMinimal ) ;
CScriptNum bn2 ( stacktop ( - 1 ) , fRequireMinimal ) ;
2014-08-27 14:11:41 -04:00
CScriptNum bn ( 0 ) ;
switch ( opcode )
{
case OP_ADD :
bn = bn1 + bn2 ;
break ;
case OP_SUB :
bn = bn1 - bn2 ;
break ;
case OP_BOOLAND : bn = ( bn1 ! = bnZero & & bn2 ! = bnZero ) ; break ;
case OP_BOOLOR : bn = ( bn1 ! = bnZero | | bn2 ! = bnZero ) ; break ;
case OP_NUMEQUAL : bn = ( bn1 = = bn2 ) ; break ;
case OP_NUMEQUALVERIFY : bn = ( bn1 = = bn2 ) ; break ;
case OP_NUMNOTEQUAL : bn = ( bn1 ! = bn2 ) ; break ;
case OP_LESSTHAN : bn = ( bn1 < bn2 ) ; break ;
case OP_GREATERTHAN : bn = ( bn1 > bn2 ) ; break ;
case OP_LESSTHANOREQUAL : bn = ( bn1 < = bn2 ) ; break ;
case OP_GREATERTHANOREQUAL : bn = ( bn1 > = bn2 ) ; break ;
case OP_MIN : bn = ( bn1 < bn2 ? bn1 : bn2 ) ; break ;
case OP_MAX : bn = ( bn1 > bn2 ? bn1 : bn2 ) ; break ;
default : assert ( ! " invalid opcode " ) ; break ;
}
popstack ( stack ) ;
popstack ( stack ) ;
stack . push_back ( bn . getvch ( ) ) ;
if ( opcode = = OP_NUMEQUALVERIFY )
{
if ( CastToBool ( stacktop ( - 1 ) ) )
popstack ( stack ) ;
else
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_NUMEQUALVERIFY ) ;
2014-08-27 14:11:41 -04:00
}
}
break ;
case OP_WITHIN :
{
// (x min max -- out)
if ( stack . size ( ) < 3 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-10-08 22:48:59 -03:00
CScriptNum bn1 ( stacktop ( - 3 ) , fRequireMinimal ) ;
CScriptNum bn2 ( stacktop ( - 2 ) , fRequireMinimal ) ;
CScriptNum bn3 ( stacktop ( - 1 ) , fRequireMinimal ) ;
2014-08-27 14:11:41 -04:00
bool fValue = ( bn2 < = bn1 & & bn1 < bn3 ) ;
popstack ( stack ) ;
popstack ( stack ) ;
popstack ( stack ) ;
stack . push_back ( fValue ? vchTrue : vchFalse ) ;
}
break ;
//
// Crypto
//
case OP_RIPEMD160 :
case OP_SHA1 :
case OP_SHA256 :
case OP_HASH160 :
case OP_HASH256 :
{
// (in -- hash)
if ( stack . size ( ) < 1 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
valtype & vch = stacktop ( - 1 ) ;
valtype vchHash ( ( opcode = = OP_RIPEMD160 | | opcode = = OP_SHA1 | | opcode = = OP_HASH160 ) ? 20 : 32 ) ;
if ( opcode = = OP_RIPEMD160 )
2016-12-09 00:01:37 -03:00
CRIPEMD160 ( ) . Write ( vch . data ( ) , vch . size ( ) ) . Finalize ( vchHash . data ( ) ) ;
2014-08-27 14:11:41 -04:00
else if ( opcode = = OP_SHA1 )
2016-12-09 00:01:37 -03:00
CSHA1 ( ) . Write ( vch . data ( ) , vch . size ( ) ) . Finalize ( vchHash . data ( ) ) ;
2014-08-27 14:11:41 -04:00
else if ( opcode = = OP_SHA256 )
2016-12-09 00:01:37 -03:00
CSHA256 ( ) . Write ( vch . data ( ) , vch . size ( ) ) . Finalize ( vchHash . data ( ) ) ;
2014-08-27 14:11:41 -04:00
else if ( opcode = = OP_HASH160 )
2020-06-18 20:19:46 -04:00
CHash160 ( ) . Write ( vch ) . Finalize ( vchHash ) ;
2014-08-27 14:11:41 -04:00
else if ( opcode = = OP_HASH256 )
2020-06-18 20:19:46 -04:00
CHash256 ( ) . Write ( vch ) . Finalize ( vchHash ) ;
2014-08-27 14:11:41 -04:00
popstack ( stack ) ;
stack . push_back ( vchHash ) ;
}
2018-07-24 11:59:49 -04:00
break ;
2014-08-27 14:11:41 -04:00
case OP_CODESEPARATOR :
{
2018-04-26 16:56:29 -03:00
// If SCRIPT_VERIFY_CONST_SCRIPTCODE flag is set, use of OP_CODESEPARATOR is rejected in pre-segwit
// script, even in an unexecuted branch (this is checked above the opcode case statement).
2014-08-27 14:11:41 -04:00
// Hash starts after the code separator
pbegincodehash = pc ;
}
break ;
case OP_CHECKSIG :
case OP_CHECKSIGVERIFY :
{
// (sig pubkey -- bool)
if ( stack . size ( ) < 2 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
valtype & vchSig = stacktop ( - 2 ) ;
valtype & vchPubKey = stacktop ( - 1 ) ;
2019-10-18 19:23:42 -03:00
bool fSuccess = true ;
if ( ! EvalChecksig ( vchSig , vchPubKey , pbegincodehash , pend , flags , checker , sigversion , serror , fSuccess ) ) return false ;
2014-08-27 14:11:41 -04:00
popstack ( stack ) ;
popstack ( stack ) ;
stack . push_back ( fSuccess ? vchTrue : vchFalse ) ;
if ( opcode = = OP_CHECKSIGVERIFY )
{
if ( fSuccess )
popstack ( stack ) ;
else
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_CHECKSIGVERIFY ) ;
2014-08-27 14:11:41 -04:00
}
}
break ;
case OP_CHECKMULTISIG :
case OP_CHECKMULTISIGVERIFY :
{
// ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool)
int i = 1 ;
if ( ( int ) stack . size ( ) < i )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
2014-10-08 22:48:59 -03:00
int nKeysCount = CScriptNum ( stacktop ( - i ) , fRequireMinimal ) . getint ( ) ;
2015-10-13 10:56:45 -03:00
if ( nKeysCount < 0 | | nKeysCount > MAX_PUBKEYS_PER_MULTISIG )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_PUBKEY_COUNT ) ;
2014-08-27 14:11:41 -04:00
nOpCount + = nKeysCount ;
2015-10-13 10:56:45 -03:00
if ( nOpCount > MAX_OPS_PER_SCRIPT )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_OP_COUNT ) ;
2014-08-27 14:11:41 -04:00
int ikey = + + i ;
2016-09-22 04:06:54 -03:00
// ikey2 is the position of last non-signature item in the stack. Top stack item = 1.
// With SCRIPT_VERIFY_NULLFAIL, this is used for cleanup if operation fails.
int ikey2 = nKeysCount + 2 ;
2014-08-27 14:11:41 -04:00
i + = nKeysCount ;
if ( ( int ) stack . size ( ) < i )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
2014-10-08 22:48:59 -03:00
int nSigsCount = CScriptNum ( stacktop ( - i ) , fRequireMinimal ) . getint ( ) ;
2014-08-27 14:11:41 -04:00
if ( nSigsCount < 0 | | nSigsCount > nKeysCount )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_SIG_COUNT ) ;
2014-08-27 14:11:41 -04:00
int isig = + + i ;
i + = nSigsCount ;
if ( ( int ) stack . size ( ) < i )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
// Subset of script starting at the most recent codeseparator
CScript scriptCode ( pbegincodehash , pend ) ;
2016-10-15 12:45:07 -03:00
// Drop the signature in pre-segwit scripts but not segwit scripts
2014-08-27 14:11:41 -04:00
for ( int k = 0 ; k < nSigsCount ; k + + )
{
valtype & vchSig = stacktop ( - isig - k ) ;
2018-03-09 11:03:40 -03:00
if ( sigversion = = SigVersion : : BASE ) {
2019-05-31 10:01:15 -04:00
int found = FindAndDelete ( scriptCode , CScript ( ) < < vchSig ) ;
2018-04-26 16:56:29 -03:00
if ( found > 0 & & ( flags & SCRIPT_VERIFY_CONST_SCRIPTCODE ) )
return set_error ( serror , SCRIPT_ERR_SIG_FINDANDDELETE ) ;
2015-12-27 15:49:08 -03:00
}
2014-08-27 14:11:41 -04:00
}
bool fSuccess = true ;
while ( fSuccess & & nSigsCount > 0 )
{
valtype & vchSig = stacktop ( - isig ) ;
valtype & vchPubKey = stacktop ( - ikey ) ;
2014-11-10 04:33:19 -03:00
// Note how this makes the exact order of pubkey/signature evaluation
// distinguishable by CHECKMULTISIG NOT if the STRICTENC flag is set.
// See the script_(in)valid tests for details.
2016-10-01 14:19:33 -03:00
if ( ! CheckSignatureEncoding ( vchSig , flags , serror ) | | ! CheckPubKeyEncoding ( vchPubKey , flags , sigversion , serror ) ) {
2014-11-01 00:29:12 -03:00
// serror is set
2014-10-06 21:22:47 -03:00
return false ;
}
2014-08-27 14:11:41 -04:00
// Check signature
2020-09-11 18:33:23 -03:00
bool fOk = checker . CheckECDSASignature ( vchSig , vchPubKey , scriptCode , sigversion ) ;
2014-08-27 14:11:41 -04:00
if ( fOk ) {
isig + + ;
nSigsCount - - ;
}
ikey + + ;
nKeysCount - - ;
// If there are more signatures left than keys left,
2014-11-10 04:33:19 -03:00
// then too many signatures have failed. Exit early,
// without checking any further signatures.
2014-08-27 14:11:41 -04:00
if ( nSigsCount > nKeysCount )
fSuccess = false ;
}
// Clean up stack of actual arguments
2016-09-22 04:06:54 -03:00
while ( i - - > 1 ) {
// If the operation failed, we require that all signatures must be empty vector
if ( ! fSuccess & & ( flags & SCRIPT_VERIFY_NULLFAIL ) & & ! ikey2 & & stacktop ( - 1 ) . size ( ) )
return set_error ( serror , SCRIPT_ERR_SIG_NULLFAIL ) ;
if ( ikey2 > 0 )
ikey2 - - ;
2014-08-27 14:11:41 -04:00
popstack ( stack ) ;
2016-09-22 04:06:54 -03:00
}
2014-08-27 14:11:41 -04:00
// A bug causes CHECKMULTISIG to consume one extra argument
// whose contents were not checked in any way.
//
// Unfortunately this is a potential source of mutability,
// so optionally verify it is exactly equal to zero prior
// to removing it from the stack.
if ( stack . size ( ) < 1 )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_INVALID_STACK_OPERATION ) ;
2014-08-27 14:11:41 -04:00
if ( ( flags & SCRIPT_VERIFY_NULLDUMMY ) & & stacktop ( - 1 ) . size ( ) )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_SIG_NULLDUMMY ) ;
2014-08-27 14:11:41 -04:00
popstack ( stack ) ;
stack . push_back ( fSuccess ? vchTrue : vchFalse ) ;
if ( opcode = = OP_CHECKMULTISIGVERIFY )
{
if ( fSuccess )
popstack ( stack ) ;
else
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_CHECKMULTISIGVERIFY ) ;
2014-08-27 14:11:41 -04:00
}
}
break ;
default :
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_BAD_OPCODE ) ;
2014-08-27 14:11:41 -04:00
}
// Size limits
2017-05-02 11:55:06 -03:00
if ( stack . size ( ) + altstack . size ( ) > MAX_STACK_SIZE )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_STACK_SIZE ) ;
2014-08-27 14:11:41 -04:00
}
}
catch ( . . . )
{
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_UNKNOWN_ERROR ) ;
2014-08-27 14:11:41 -04:00
}
if ( ! vfExec . empty ( ) )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_UNBALANCED_CONDITIONAL ) ;
2014-08-27 14:11:41 -04:00
2014-11-01 00:29:12 -03:00
return set_success ( serror ) ;
2014-08-27 14:11:41 -04:00
}
namespace {
2014-11-10 03:40:01 -03:00
/**
* Wrapper that serializes like CTransaction , but with the modifications
2014-08-27 14:11:41 -04:00
* required for the signature hash done in - place
*/
2018-05-20 16:47:14 -04:00
template < class T >
class CTransactionSignatureSerializer
{
2014-08-27 14:11:41 -04:00
private :
2018-05-20 16:47:14 -04:00
const T & txTo ; //!< reference to the spending transaction (the one being serialized)
2016-04-03 06:49:36 -03:00
const CScript & scriptCode ; //!< output script being consumed
const unsigned int nIn ; //!< input index of txTo being signed
const bool fAnyoneCanPay ; //!< whether the hashtype has the SIGHASH_ANYONECANPAY flag set
const bool fHashSingle ; //!< whether the hashtype is SIGHASH_SINGLE
const bool fHashNone ; //!< whether the hashtype is SIGHASH_NONE
2014-08-27 14:11:41 -04:00
public :
2018-05-20 16:47:14 -04:00
CTransactionSignatureSerializer ( const T & txToIn , const CScript & scriptCodeIn , unsigned int nInIn , int nHashTypeIn ) :
2014-08-27 14:11:41 -04:00
txTo ( txToIn ) , scriptCode ( scriptCodeIn ) , nIn ( nInIn ) ,
fAnyoneCanPay ( ! ! ( nHashTypeIn & SIGHASH_ANYONECANPAY ) ) ,
fHashSingle ( ( nHashTypeIn & 0x1f ) = = SIGHASH_SINGLE ) ,
fHashNone ( ( nHashTypeIn & 0x1f ) = = SIGHASH_NONE ) { }
/** Serialize the passed scriptCode, skipping OP_CODESEPARATORs */
template < typename S >
2016-10-28 20:29:17 -03:00
void SerializeScriptCode ( S & s ) const {
2014-08-27 14:11:41 -04:00
CScript : : const_iterator it = scriptCode . begin ( ) ;
CScript : : const_iterator itBegin = it ;
opcodetype opcode ;
unsigned int nCodeSeparators = 0 ;
while ( scriptCode . GetOp ( it , opcode ) ) {
if ( opcode = = OP_CODESEPARATOR )
nCodeSeparators + + ;
}
: : WriteCompactSize ( s , scriptCode . size ( ) - nCodeSeparators ) ;
it = itBegin ;
while ( scriptCode . GetOp ( it , opcode ) ) {
if ( opcode = = OP_CODESEPARATOR ) {
s . write ( ( char * ) & itBegin [ 0 ] , it - itBegin - 1 ) ;
itBegin = it ;
}
}
2014-09-23 17:53:58 -03:00
if ( itBegin ! = scriptCode . end ( ) )
s . write ( ( char * ) & itBegin [ 0 ] , it - itBegin ) ;
2014-08-27 14:11:41 -04:00
}
/** Serialize an input of txTo */
template < typename S >
2016-10-28 20:29:17 -03:00
void SerializeInput ( S & s , unsigned int nInput ) const {
2014-08-27 14:11:41 -04:00
// In case of SIGHASH_ANYONECANPAY, only the input being signed is serialized
if ( fAnyoneCanPay )
nInput = nIn ;
// Serialize the prevout
2016-10-28 20:29:17 -03:00
: : Serialize ( s , txTo . vin [ nInput ] . prevout ) ;
2014-08-27 14:11:41 -04:00
// Serialize the script
if ( nInput ! = nIn )
// Blank out other inputs' signatures
2017-07-07 03:54:42 -04:00
: : Serialize ( s , CScript ( ) ) ;
2014-08-27 14:11:41 -04:00
else
2016-10-28 20:29:17 -03:00
SerializeScriptCode ( s ) ;
2014-08-27 14:11:41 -04:00
// Serialize the nSequence
if ( nInput ! = nIn & & ( fHashSingle | | fHashNone ) )
// let the others update at will
2016-10-28 20:29:17 -03:00
: : Serialize ( s , ( int ) 0 ) ;
2014-08-27 14:11:41 -04:00
else
2016-10-28 20:29:17 -03:00
: : Serialize ( s , txTo . vin [ nInput ] . nSequence ) ;
2014-08-27 14:11:41 -04:00
}
/** Serialize an output of txTo */
template < typename S >
2016-10-28 20:29:17 -03:00
void SerializeOutput ( S & s , unsigned int nOutput ) const {
2014-08-27 14:11:41 -04:00
if ( fHashSingle & & nOutput ! = nIn )
// Do not lock-in the txout payee at other indices as txin
2016-10-28 20:29:17 -03:00
: : Serialize ( s , CTxOut ( ) ) ;
2014-08-27 14:11:41 -04:00
else
2016-10-28 20:29:17 -03:00
: : Serialize ( s , txTo . vout [ nOutput ] ) ;
2014-08-27 14:11:41 -04:00
}
/** Serialize txTo */
template < typename S >
2016-10-28 20:29:17 -03:00
void Serialize ( S & s ) const {
2014-08-27 14:11:41 -04:00
// Serialize nVersion
2016-10-28 20:29:17 -03:00
: : Serialize ( s , txTo . nVersion ) ;
2014-08-27 14:11:41 -04:00
// Serialize vin
unsigned int nInputs = fAnyoneCanPay ? 1 : txTo . vin . size ( ) ;
: : WriteCompactSize ( s , nInputs ) ;
for ( unsigned int nInput = 0 ; nInput < nInputs ; nInput + + )
2016-10-28 20:29:17 -03:00
SerializeInput ( s , nInput ) ;
2014-08-27 14:11:41 -04:00
// Serialize vout
unsigned int nOutputs = fHashNone ? 0 : ( fHashSingle ? nIn + 1 : txTo . vout . size ( ) ) ;
: : WriteCompactSize ( s , nOutputs ) ;
for ( unsigned int nOutput = 0 ; nOutput < nOutputs ; nOutput + + )
2016-10-28 20:29:17 -03:00
SerializeOutput ( s , nOutput ) ;
2014-11-10 03:40:01 -03:00
// Serialize nLockTime
2016-10-28 20:29:17 -03:00
: : Serialize ( s , txTo . nLockTime ) ;
2014-08-27 14:11:41 -04:00
}
} ;
2020-02-05 17:31:20 -03:00
/** Compute the (single) SHA256 of the concatenation of all prevouts of a tx. */
2018-05-20 16:47:14 -04:00
template < class T >
2020-02-05 17:31:20 -03:00
uint256 GetPrevoutsSHA256 ( const T & txTo )
2018-05-20 16:47:14 -04:00
{
2016-08-16 10:35:45 -03:00
CHashWriter ss ( SER_GETHASH , 0 ) ;
2017-05-18 03:42:14 -04:00
for ( const auto & txin : txTo . vin ) {
ss < < txin . prevout ;
2016-08-16 10:35:45 -03:00
}
2020-02-05 17:31:20 -03:00
return ss . GetSHA256 ( ) ;
2016-08-16 10:35:45 -03:00
}
2020-02-05 17:31:20 -03:00
/** Compute the (single) SHA256 of the concatenation of all nSequences of a tx. */
2018-05-20 16:47:14 -04:00
template < class T >
2020-02-05 17:31:20 -03:00
uint256 GetSequencesSHA256 ( const T & txTo )
2018-05-20 16:47:14 -04:00
{
2016-08-16 10:35:45 -03:00
CHashWriter ss ( SER_GETHASH , 0 ) ;
2017-05-18 03:42:14 -04:00
for ( const auto & txin : txTo . vin ) {
ss < < txin . nSequence ;
2016-08-16 10:35:45 -03:00
}
2020-02-05 17:31:20 -03:00
return ss . GetSHA256 ( ) ;
2016-08-16 10:35:45 -03:00
}
2020-02-05 17:31:20 -03:00
/** Compute the (single) SHA256 of the concatenation of all txouts of a tx. */
2018-05-20 16:47:14 -04:00
template < class T >
2020-02-05 17:31:20 -03:00
uint256 GetOutputsSHA256 ( const T & txTo )
2018-05-20 16:47:14 -04:00
{
2016-08-16 10:35:45 -03:00
CHashWriter ss ( SER_GETHASH , 0 ) ;
2017-05-18 03:42:14 -04:00
for ( const auto & txout : txTo . vout ) {
ss < < txout ;
2016-08-16 10:35:45 -03:00
}
2020-02-05 17:31:20 -03:00
return ss . GetSHA256 ( ) ;
2016-08-16 10:35:45 -03:00
}
2020-09-11 18:33:10 -03:00
/** Compute the (single) SHA256 of the concatenation of all amounts spent by a tx. */
uint256 GetSpentAmountsSHA256 ( const std : : vector < CTxOut > & outputs_spent )
{
CHashWriter ss ( SER_GETHASH , 0 ) ;
for ( const auto & txout : outputs_spent ) {
ss < < txout . nValue ;
}
return ss . GetSHA256 ( ) ;
}
/** Compute the (single) SHA256 of the concatenation of all scriptPubKeys spent by a tx. */
uint256 GetSpentScriptsSHA256 ( const std : : vector < CTxOut > & outputs_spent )
{
CHashWriter ss ( SER_GETHASH , 0 ) ;
for ( const auto & txout : outputs_spent ) {
ss < < txout . scriptPubKey ;
}
return ss . GetSHA256 ( ) ;
}
2017-05-31 16:21:25 -04:00
} // namespace
2014-08-27 14:11:41 -04:00
2018-05-20 16:47:14 -04:00
template < class T >
2020-09-11 18:33:00 -03:00
void PrecomputedTransactionData : : Init ( const T & txTo , std : : vector < CTxOut > & & spent_outputs )
2016-08-16 10:35:45 -03:00
{
2020-09-11 18:33:10 -03:00
assert ( ! m_spent_outputs_ready ) ;
2019-04-02 17:12:08 -03:00
2020-09-11 18:33:00 -03:00
m_spent_outputs = std : : move ( spent_outputs ) ;
2020-09-11 18:33:10 -03:00
if ( ! m_spent_outputs . empty ( ) ) {
assert ( m_spent_outputs . size ( ) = = txTo . vin . size ( ) ) ;
m_spent_outputs_ready = true ;
}
2020-09-11 18:33:00 -03:00
2020-09-11 18:33:10 -03:00
// Determine which precomputation-impacting features this transaction uses.
bool uses_bip143_segwit = false ;
bool uses_bip341_taproot = false ;
for ( size_t inpos = 0 ; inpos < txTo . vin . size ( ) ; + + inpos ) {
if ( ! txTo . vin [ inpos ] . scriptWitness . IsNull ( ) ) {
if ( m_spent_outputs_ready & & m_spent_outputs [ inpos ] . scriptPubKey . size ( ) = = 2 + WITNESS_V1_TAPROOT_SIZE & &
m_spent_outputs [ inpos ] . scriptPubKey [ 0 ] = = OP_1 ) {
// Treat every witness-bearing spend with 34-byte scriptPubKey that starts with OP_1 as a Taproot
// spend. This only works if spent_outputs was provided as well, but if it wasn't, actual validation
// will fail anyway. Note that this branch may trigger for scriptPubKeys that aren't actually segwit
// but in that case validation will fail as SCRIPT_ERR_WITNESS_UNEXPECTED anyway.
uses_bip341_taproot = true ;
} else {
// Treat every spend that's not known to native witness v1 as a Witness v0 spend. This branch may
// also be taken for unknown witness versions, but it is harmless, and being precise would require
// P2SH evaluation to find the redeemScript.
uses_bip143_segwit = true ;
}
}
if ( uses_bip341_taproot & & uses_bip143_segwit ) break ; // No need to scan further if we already need all.
2017-01-18 05:12:26 -03:00
}
2019-04-02 17:12:08 -03:00
2020-09-11 18:33:10 -03:00
if ( uses_bip143_segwit | | uses_bip341_taproot ) {
// Computations shared between both sighash schemes.
m_prevouts_single_hash = GetPrevoutsSHA256 ( txTo ) ;
m_sequences_single_hash = GetSequencesSHA256 ( txTo ) ;
m_outputs_single_hash = GetOutputsSHA256 ( txTo ) ;
}
if ( uses_bip143_segwit ) {
hashPrevouts = SHA256Uint256 ( m_prevouts_single_hash ) ;
hashSequence = SHA256Uint256 ( m_sequences_single_hash ) ;
hashOutputs = SHA256Uint256 ( m_outputs_single_hash ) ;
m_bip143_segwit_ready = true ;
}
if ( uses_bip341_taproot ) {
m_spent_amounts_single_hash = GetSpentAmountsSHA256 ( m_spent_outputs ) ;
m_spent_scripts_single_hash = GetSpentScriptsSHA256 ( m_spent_outputs ) ;
m_bip341_taproot_ready = true ;
}
2019-04-02 17:12:08 -03:00
}
template < class T >
PrecomputedTransactionData : : PrecomputedTransactionData ( const T & txTo )
{
2020-09-11 18:33:00 -03:00
Init ( txTo , { } ) ;
2016-08-16 10:35:45 -03:00
}
2018-05-20 16:47:14 -04:00
// explicit instantiation
2020-09-11 18:33:00 -03:00
template void PrecomputedTransactionData : : Init ( const CTransaction & txTo , std : : vector < CTxOut > & & spent_outputs ) ;
template void PrecomputedTransactionData : : Init ( const CMutableTransaction & txTo , std : : vector < CTxOut > & & spent_outputs ) ;
2018-05-20 16:47:14 -04:00
template PrecomputedTransactionData : : PrecomputedTransactionData ( const CTransaction & txTo ) ;
template PrecomputedTransactionData : : PrecomputedTransactionData ( const CMutableTransaction & txTo ) ;
2020-09-11 18:33:10 -03:00
static const CHashWriter HASHER_TAPSIGHASH = TaggedHash ( " TapSighash " ) ;
template < typename T >
bool SignatureHashSchnorr ( uint256 & hash_out , const T & tx_to , uint32_t in_pos , uint8_t hash_type , SigVersion sigversion , const PrecomputedTransactionData & cache )
{
uint8_t ext_flag ;
switch ( sigversion ) {
case SigVersion : : TAPROOT :
ext_flag = 0 ;
break ;
default :
assert ( false ) ;
}
assert ( in_pos < tx_to . vin . size ( ) ) ;
assert ( cache . m_bip341_taproot_ready & & cache . m_spent_outputs_ready ) ;
CHashWriter ss = HASHER_TAPSIGHASH ;
// Epoch
static constexpr uint8_t EPOCH = 0 ;
ss < < EPOCH ;
// Hash type
const uint8_t output_type = ( hash_type = = SIGHASH_DEFAULT ) ? SIGHASH_ALL : ( hash_type & SIGHASH_OUTPUT_MASK ) ; // Default (no sighash byte) is equivalent to SIGHASH_ALL
const uint8_t input_type = hash_type & SIGHASH_INPUT_MASK ;
if ( ! ( hash_type < = 0x03 | | ( hash_type > = 0x81 & & hash_type < = 0x83 ) ) ) return false ;
ss < < hash_type ;
// Transaction level data
ss < < tx_to . nVersion ;
ss < < tx_to . nLockTime ;
if ( input_type ! = SIGHASH_ANYONECANPAY ) {
ss < < cache . m_prevouts_single_hash ;
ss < < cache . m_spent_amounts_single_hash ;
ss < < cache . m_spent_scripts_single_hash ;
ss < < cache . m_sequences_single_hash ;
}
if ( output_type = = SIGHASH_ALL ) {
ss < < cache . m_outputs_single_hash ;
}
// Data about the input/prevout being spent
const auto & witstack = tx_to . vin [ in_pos ] . scriptWitness . stack ;
bool have_annex = witstack . size ( ) > 1 & & witstack . back ( ) . size ( ) > 0 & & witstack . back ( ) [ 0 ] = = ANNEX_TAG ;
const uint8_t spend_type = ( ext_flag < < 1 ) + ( have_annex ? 1 : 0 ) ; // The low bit indicates whether an annex is present.
ss < < spend_type ;
if ( input_type = = SIGHASH_ANYONECANPAY ) {
ss < < tx_to . vin [ in_pos ] . prevout ;
ss < < cache . m_spent_outputs [ in_pos ] ;
ss < < tx_to . vin [ in_pos ] . nSequence ;
} else {
ss < < in_pos ;
}
if ( have_annex ) {
ss < < ( CHashWriter ( SER_GETHASH , 0 ) < < witstack . back ( ) ) . GetSHA256 ( ) ;
}
// Data about the output (if only one).
if ( output_type = = SIGHASH_SINGLE ) {
if ( in_pos > = tx_to . vout . size ( ) ) return false ;
CHashWriter sha_single_output ( SER_GETHASH , 0 ) ;
sha_single_output < < tx_to . vout [ in_pos ] ;
ss < < sha_single_output . GetSHA256 ( ) ;
}
hash_out = ss . GetSHA256 ( ) ;
return true ;
}
2018-05-20 16:47:14 -04:00
template < class T >
uint256 SignatureHash ( const CScript & scriptCode , const T & txTo , unsigned int nIn , int nHashType , const CAmount & amount , SigVersion sigversion , const PrecomputedTransactionData * cache )
2014-08-27 14:11:41 -04:00
{
2017-09-27 23:49:18 -03:00
assert ( nIn < txTo . vin . size ( ) ) ;
2018-03-09 11:03:40 -03:00
if ( sigversion = = SigVersion : : WITNESS_V0 ) {
2015-12-27 15:49:08 -03:00
uint256 hashPrevouts ;
uint256 hashSequence ;
uint256 hashOutputs ;
2020-09-11 18:33:10 -03:00
const bool cacheready = cache & & cache - > m_bip143_segwit_ready ;
2015-12-27 15:49:08 -03:00
if ( ! ( nHashType & SIGHASH_ANYONECANPAY ) ) {
2020-02-05 17:31:20 -03:00
hashPrevouts = cacheready ? cache - > hashPrevouts : SHA256Uint256 ( GetPrevoutsSHA256 ( txTo ) ) ;
2015-12-27 15:49:08 -03:00
}
if ( ! ( nHashType & SIGHASH_ANYONECANPAY ) & & ( nHashType & 0x1f ) ! = SIGHASH_SINGLE & & ( nHashType & 0x1f ) ! = SIGHASH_NONE ) {
2020-02-05 17:31:20 -03:00
hashSequence = cacheready ? cache - > hashSequence : SHA256Uint256 ( GetSequencesSHA256 ( txTo ) ) ;
2015-12-27 15:49:08 -03:00
}
2016-08-16 10:35:45 -03:00
2015-12-27 15:49:08 -03:00
if ( ( nHashType & 0x1f ) ! = SIGHASH_SINGLE & & ( nHashType & 0x1f ) ! = SIGHASH_NONE ) {
2020-02-05 17:31:20 -03:00
hashOutputs = cacheready ? cache - > hashOutputs : SHA256Uint256 ( GetOutputsSHA256 ( txTo ) ) ;
2015-12-27 15:49:08 -03:00
} else if ( ( nHashType & 0x1f ) = = SIGHASH_SINGLE & & nIn < txTo . vout . size ( ) ) {
CHashWriter ss ( SER_GETHASH , 0 ) ;
ss < < txTo . vout [ nIn ] ;
hashOutputs = ss . GetHash ( ) ;
}
CHashWriter ss ( SER_GETHASH , 0 ) ;
// Version
ss < < txTo . nVersion ;
// Input prevouts/nSequence (none/all, depending on flags)
ss < < hashPrevouts ;
ss < < hashSequence ;
// The input being signed (replacing the scriptSig with scriptCode + amount)
// The prevout may already be contained in hashPrevout, and the nSequence
// may already be contain in hashSequence.
ss < < txTo . vin [ nIn ] . prevout ;
2017-07-07 03:54:42 -04:00
ss < < scriptCode ;
2015-12-27 15:49:08 -03:00
ss < < amount ;
ss < < txTo . vin [ nIn ] . nSequence ;
// Outputs (none/one/all, depending on flags)
ss < < hashOutputs ;
// Locktime
ss < < txTo . nLockTime ;
// Sighash type
ss < < nHashType ;
return ss . GetHash ( ) ;
}
2014-08-27 14:11:41 -04:00
// Check for invalid use of SIGHASH_SINGLE
if ( ( nHashType & 0x1f ) = = SIGHASH_SINGLE ) {
if ( nIn > = txTo . vout . size ( ) ) {
2014-11-01 00:29:12 -03:00
// nOut out of range
2020-09-26 03:01:56 -03:00
return uint256 : : ONE ;
2014-08-27 14:11:41 -04:00
}
}
// Wrapper to serialize only the necessary parts of the transaction being signed
2018-05-20 16:47:14 -04:00
CTransactionSignatureSerializer < T > txTmp ( txTo , scriptCode , nIn , nHashType ) ;
2014-08-27 14:11:41 -04:00
// Serialize and hash
CHashWriter ss ( SER_GETHASH , 0 ) ;
ss < < txTmp < < nHashType ;
return ss . GetHash ( ) ;
}
2018-05-20 16:47:14 -04:00
template < class T >
2020-09-11 18:33:23 -03:00
bool GenericTransactionSignatureChecker < T > : : VerifyECDSASignature ( const std : : vector < unsigned char > & vchSig , const CPubKey & pubkey , const uint256 & sighash ) const
2014-08-27 14:11:41 -04:00
{
2014-09-10 11:16:09 -03:00
return pubkey . Verify ( sighash , vchSig ) ;
}
2014-08-27 14:11:41 -04:00
2020-09-11 18:33:30 -03:00
template < class T >
bool GenericTransactionSignatureChecker < T > : : VerifySchnorrSignature ( Span < const unsigned char > sig , const XOnlyPubKey & pubkey , const uint256 & sighash ) const
{
return pubkey . VerifySchnorr ( sighash , sig ) ;
}
2018-05-20 16:47:14 -04:00
template < class T >
2020-09-11 18:33:23 -03:00
bool GenericTransactionSignatureChecker < T > : : CheckECDSASignature ( const std : : vector < unsigned char > & vchSigIn , const std : : vector < unsigned char > & vchPubKey , const CScript & scriptCode , SigVersion sigversion ) const
2014-08-27 14:11:41 -04:00
{
CPubKey pubkey ( vchPubKey ) ;
if ( ! pubkey . IsValid ( ) )
return false ;
// Hash type is one byte tacked on to the end of the signature
2017-01-04 02:42:14 -03:00
std : : vector < unsigned char > vchSig ( vchSigIn ) ;
2014-08-27 14:11:41 -04:00
if ( vchSig . empty ( ) )
return false ;
2014-07-18 12:47:10 -04:00
int nHashType = vchSig . back ( ) ;
2014-08-27 14:11:41 -04:00
vchSig . pop_back ( ) ;
2016-08-26 13:38:20 -03:00
uint256 sighash = SignatureHash ( scriptCode , * txTo , nIn , nHashType , amount , sigversion , this - > txdata ) ;
2014-08-27 14:11:41 -04:00
2020-09-11 18:33:23 -03:00
if ( ! VerifyECDSASignature ( vchSig , pubkey , sighash ) )
2014-08-27 14:11:41 -04:00
return false ;
return true ;
}
2020-09-11 18:33:30 -03:00
template < class T >
bool GenericTransactionSignatureChecker < T > : : CheckSchnorrSignature ( Span < const unsigned char > sig , Span < const unsigned char > pubkey_in , SigVersion sigversion , ScriptError * serror ) const
{
assert ( sigversion = = SigVersion : : TAPROOT ) ;
// Schnorr signatures have 32-byte public keys. The caller is responsible for enforcing this.
assert ( pubkey_in . size ( ) = = 32 ) ;
if ( sig . size ( ) ! = 64 & & sig . size ( ) ! = 65 ) return set_error ( serror , SCRIPT_ERR_SCHNORR_SIG_SIZE ) ;
XOnlyPubKey pubkey { pubkey_in } ;
uint8_t hashtype = SIGHASH_DEFAULT ;
if ( sig . size ( ) = = 65 ) {
hashtype = SpanPopBack ( sig ) ;
if ( hashtype = = SIGHASH_DEFAULT ) return set_error ( serror , SCRIPT_ERR_SCHNORR_SIG_HASHTYPE ) ;
}
uint256 sighash ;
assert ( this - > txdata ) ;
if ( ! SignatureHashSchnorr ( sighash , * txTo , nIn , hashtype , sigversion , * this - > txdata ) ) {
return set_error ( serror , SCRIPT_ERR_SCHNORR_SIG_HASHTYPE ) ;
}
if ( ! VerifySchnorrSignature ( sig , pubkey , sighash ) ) return set_error ( serror , SCRIPT_ERR_SCHNORR_SIG ) ;
return true ;
}
2018-05-20 16:47:14 -04:00
template < class T >
bool GenericTransactionSignatureChecker < T > : : CheckLockTime ( const CScriptNum & nLockTime ) const
2014-09-29 04:44:25 -03:00
{
2015-08-10 22:08:30 -03:00
// There are two kinds of nLockTime: lock-by-blockheight
2014-09-29 04:44:25 -03:00
// and lock-by-blocktime, distinguished by whether
2016-02-12 17:02:46 -03:00
// nLockTime < LOCKTIME_THRESHOLD.
2014-09-29 04:44:25 -03:00
//
// We want to compare apples to apples, so fail the script
// unless the type of nLockTime being tested is the same as
// the nLockTime in the transaction.
if ( ! (
2016-02-12 17:02:46 -03:00
( txTo - > nLockTime < LOCKTIME_THRESHOLD & & nLockTime < LOCKTIME_THRESHOLD ) | |
( txTo - > nLockTime > = LOCKTIME_THRESHOLD & & nLockTime > = LOCKTIME_THRESHOLD )
2014-09-29 04:44:25 -03:00
) )
return false ;
// Now that we know we're comparing apples-to-apples, the
// comparison is a simple numeric one.
2016-02-12 17:02:46 -03:00
if ( nLockTime > ( int64_t ) txTo - > nLockTime )
2014-09-29 04:44:25 -03:00
return false ;
2016-02-12 17:02:46 -03:00
// Finally the nLockTime feature can be disabled and thus
2014-09-29 04:44:25 -03:00
// CHECKLOCKTIMEVERIFY bypassed if every txin has been
// finalized by setting nSequence to maxint. The
// transaction would be allowed into the blockchain, making
// the opcode ineffective.
//
// Testing if this vin is not final is sufficient to
// prevent this condition. Alternatively we could test all
// inputs, but testing just this input minimizes the data
// required to prove correct CHECKLOCKTIMEVERIFY execution.
2015-12-07 17:44:16 -03:00
if ( CTxIn : : SEQUENCE_FINAL = = txTo - > vin [ nIn ] . nSequence )
2014-09-29 04:44:25 -03:00
return false ;
2015-09-25 20:18:51 -03:00
return true ;
}
2018-05-20 16:47:14 -04:00
template < class T >
bool GenericTransactionSignatureChecker < T > : : CheckSequence ( const CScriptNum & nSequence ) const
2015-09-25 20:18:51 -03:00
{
// Relative lock times are supported by comparing the passed
// in operand to the sequence number of the input.
const int64_t txToSequence = ( int64_t ) txTo - > vin [ nIn ] . nSequence ;
// Fail if the transaction's version number is not set high
// enough to trigger BIP 68 rules.
if ( static_cast < uint32_t > ( txTo - > nVersion ) < 2 )
return false ;
// Sequence numbers with their most significant bit set are not
// consensus constrained. Testing that the transaction's sequence
// number do not have this bit set prevents using this property
// to get around a CHECKSEQUENCEVERIFY check.
if ( txToSequence & CTxIn : : SEQUENCE_LOCKTIME_DISABLE_FLAG )
return false ;
// Mask off any bits that do not have consensus-enforced meaning
2016-02-12 17:02:46 -03:00
// before doing the integer comparisons
const uint32_t nLockTimeMask = CTxIn : : SEQUENCE_LOCKTIME_TYPE_FLAG | CTxIn : : SEQUENCE_LOCKTIME_MASK ;
const int64_t txToSequenceMasked = txToSequence & nLockTimeMask ;
const CScriptNum nSequenceMasked = nSequence & nLockTimeMask ;
// There are two kinds of nSequence: lock-by-blockheight
// and lock-by-blocktime, distinguished by whether
// nSequenceMasked < CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG.
//
// We want to compare apples to apples, so fail the script
// unless the type of nSequenceMasked being tested is the same as
// the nSequenceMasked in the transaction.
if ( ! (
( txToSequenceMasked < CTxIn : : SEQUENCE_LOCKTIME_TYPE_FLAG & & nSequenceMasked < CTxIn : : SEQUENCE_LOCKTIME_TYPE_FLAG ) | |
( txToSequenceMasked > = CTxIn : : SEQUENCE_LOCKTIME_TYPE_FLAG & & nSequenceMasked > = CTxIn : : SEQUENCE_LOCKTIME_TYPE_FLAG )
2016-02-16 06:39:44 -03:00
) ) {
2016-02-12 17:02:46 -03:00
return false ;
2016-02-16 06:39:44 -03:00
}
2015-09-25 20:18:51 -03:00
2016-02-12 17:02:46 -03:00
// Now that we know we're comparing apples-to-apples, the
// comparison is a simple numeric one.
if ( nSequenceMasked > txToSequenceMasked )
2015-09-25 20:18:51 -03:00
return false ;
2014-09-29 04:44:25 -03:00
return true ;
}
2018-05-20 16:47:14 -04:00
// explicit instantiation
template class GenericTransactionSignatureChecker < CTransaction > ;
template class GenericTransactionSignatureChecker < CMutableTransaction > ;
2020-03-18 00:02:48 -03:00
static bool ExecuteWitnessScript ( const Span < const valtype > & stack_span , const CScript & scriptPubKey , unsigned int flags , SigVersion sigversion , const BaseSignatureChecker & checker , ScriptError * serror )
2019-10-06 16:13:20 -03:00
{
2020-03-18 00:02:48 -03:00
std : : vector < valtype > stack { stack_span . begin ( ) , stack_span . end ( ) } ;
2019-10-06 16:13:20 -03:00
// Disallow stack item size > MAX_SCRIPT_ELEMENT_SIZE in witness stack
for ( const valtype & elem : stack ) {
if ( elem . size ( ) > MAX_SCRIPT_ELEMENT_SIZE ) return set_error ( serror , SCRIPT_ERR_PUSH_SIZE ) ;
}
// Run the script interpreter.
if ( ! EvalScript ( stack , scriptPubKey , flags , checker , sigversion , serror ) ) return false ;
// Scripts inside witness implicitly require cleanstack behaviour
if ( stack . size ( ) ! = 1 ) return set_error ( serror , SCRIPT_ERR_CLEANSTACK ) ;
if ( ! CastToBool ( stack . back ( ) ) ) return set_error ( serror , SCRIPT_ERR_EVAL_FALSE ) ;
return true ;
}
2015-11-07 21:16:45 -03:00
static bool VerifyWitnessProgram ( const CScriptWitness & witness , int witversion , const std : : vector < unsigned char > & program , unsigned int flags , const BaseSignatureChecker & checker , ScriptError * serror )
2014-08-27 14:11:41 -04:00
{
2020-09-11 18:33:37 -03:00
CScript exec_script ; //!< Actually executed script (last stack item in P2WSH; implied P2PKH script in P2WPKH)
2020-03-29 21:42:38 -03:00
Span < const valtype > stack { witness . stack } ;
2015-11-07 21:16:45 -03:00
if ( witversion = = 0 ) {
2018-04-11 00:13:32 -03:00
if ( program . size ( ) = = WITNESS_V0_SCRIPTHASH_SIZE ) {
2015-11-07 21:16:45 -03:00
// Version 0 segregated witness program: SHA256(CScript) inside the program, CScript + inputs in witness
2020-03-18 00:02:48 -03:00
if ( stack . size ( ) = = 0 ) {
2015-11-07 21:16:45 -03:00
return set_error ( serror , SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY ) ;
}
2020-03-18 00:02:48 -03:00
const valtype & script_bytes = SpanPopBack ( stack ) ;
2020-09-11 18:33:37 -03:00
exec_script = CScript ( script_bytes . begin ( ) , script_bytes . end ( ) ) ;
uint256 hash_exec_script ;
CSHA256 ( ) . Write ( & exec_script [ 0 ] , exec_script . size ( ) ) . Finalize ( hash_exec_script . begin ( ) ) ;
if ( memcmp ( hash_exec_script . begin ( ) , program . data ( ) , 32 ) ) {
2015-11-07 21:16:45 -03:00
return set_error ( serror , SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH ) ;
}
2020-09-11 18:33:37 -03:00
return ExecuteWitnessScript ( stack , exec_script , flags , SigVersion : : WITNESS_V0 , checker , serror ) ;
2018-04-11 00:13:32 -03:00
} else if ( program . size ( ) = = WITNESS_V0_KEYHASH_SIZE ) {
2015-11-07 21:16:45 -03:00
// Special case for pay-to-pubkeyhash; signature + pubkey in witness
2020-03-18 00:02:48 -03:00
if ( stack . size ( ) ! = 2 ) {
2015-11-07 21:16:45 -03:00
return set_error ( serror , SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH ) ; // 2 items in witness
}
2020-09-11 18:33:37 -03:00
exec_script < < OP_DUP < < OP_HASH160 < < program < < OP_EQUALVERIFY < < OP_CHECKSIG ;
return ExecuteWitnessScript ( stack , exec_script , flags , SigVersion : : WITNESS_V0 , checker , serror ) ;
2015-11-07 21:16:45 -03:00
} else {
return set_error ( serror , SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH ) ;
}
} else {
2019-10-06 16:13:20 -03:00
if ( flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM ) {
return set_error ( serror , SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM ) ;
}
2015-11-07 21:16:45 -03:00
// Higher version witness scripts return true for future softfork compatibility
2019-10-06 16:13:20 -03:00
return true ;
2015-11-07 21:16:45 -03:00
}
2019-10-06 16:13:20 -03:00
// There is intentionally no return statement here, to be able to use "control reaches end of non-void function" warnings to detect gaps in the logic above.
2015-11-07 21:16:45 -03:00
}
bool VerifyScript ( const CScript & scriptSig , const CScript & scriptPubKey , const CScriptWitness * witness , unsigned int flags , const BaseSignatureChecker & checker , ScriptError * serror )
{
static const CScriptWitness emptyWitness ;
2017-08-07 01:36:37 -04:00
if ( witness = = nullptr ) {
2015-11-07 21:16:45 -03:00
witness = & emptyWitness ;
}
bool hadWitness = false ;
2014-11-01 00:29:12 -03:00
set_error ( serror , SCRIPT_ERR_UNKNOWN_ERROR ) ;
2014-10-08 20:29:45 -03:00
if ( ( flags & SCRIPT_VERIFY_SIGPUSHONLY ) ! = 0 & & ! scriptSig . IsPushOnly ( ) ) {
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_SIG_PUSHONLY ) ;
2014-10-08 20:29:45 -03:00
}
2018-11-10 14:11:22 -03:00
// scriptSig and scriptPubKey must be evaluated sequentially on the same stack
// rather than being simply concatenated (see CVE-2010-5141)
2017-01-04 02:42:14 -03:00
std : : vector < std : : vector < unsigned char > > stack , stackCopy ;
2018-03-09 11:03:40 -03:00
if ( ! EvalScript ( stack , scriptSig , flags , checker , SigVersion : : BASE , serror ) )
2014-11-01 00:29:12 -03:00
// serror is set
2014-08-27 14:11:41 -04:00
return false ;
if ( flags & SCRIPT_VERIFY_P2SH )
stackCopy = stack ;
2018-03-09 11:03:40 -03:00
if ( ! EvalScript ( stack , scriptPubKey , flags , checker , SigVersion : : BASE , serror ) )
2014-11-01 00:29:12 -03:00
// serror is set
2014-08-27 14:11:41 -04:00
return false ;
if ( stack . empty ( ) )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_EVAL_FALSE ) ;
2014-08-27 14:11:41 -04:00
if ( CastToBool ( stack . back ( ) ) = = false )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_EVAL_FALSE ) ;
2014-08-27 14:11:41 -04:00
2015-11-07 21:16:45 -03:00
// Bare witness programs
int witnessversion ;
std : : vector < unsigned char > witnessprogram ;
if ( flags & SCRIPT_VERIFY_WITNESS ) {
if ( scriptPubKey . IsWitnessProgram ( witnessversion , witnessprogram ) ) {
hadWitness = true ;
if ( scriptSig . size ( ) ! = 0 ) {
// The scriptSig must be _exactly_ CScript(), otherwise we reintroduce malleability.
return set_error ( serror , SCRIPT_ERR_WITNESS_MALLEATED ) ;
}
if ( ! VerifyWitnessProgram ( * witness , witnessversion , witnessprogram , flags , checker , serror ) ) {
return false ;
}
// Bypass the cleanstack check at the end. The actual stack is obviously not clean
// for witness programs.
stack . resize ( 1 ) ;
}
}
2014-08-27 14:11:41 -04:00
// Additional validation for spend-to-script-hash transactions:
if ( ( flags & SCRIPT_VERIFY_P2SH ) & & scriptPubKey . IsPayToScriptHash ( ) )
{
2014-11-01 00:29:12 -03:00
// scriptSig must be literals-only or validation fails
if ( ! scriptSig . IsPushOnly ( ) )
return set_error ( serror , SCRIPT_ERR_SIG_PUSHONLY ) ;
2014-08-27 14:11:41 -04:00
2014-10-25 09:24:14 -03:00
// Restore stack.
swap ( stack , stackCopy ) ;
// stack cannot be empty here, because if it was the
2014-08-27 14:11:41 -04:00
// P2SH HASH <> EQUAL scriptPubKey would be evaluated with
// an empty stack and the EvalScript above would return false.
2014-10-25 09:24:14 -03:00
assert ( ! stack . empty ( ) ) ;
2014-08-27 14:11:41 -04:00
2014-10-25 09:24:14 -03:00
const valtype & pubKeySerialized = stack . back ( ) ;
2014-08-27 14:11:41 -04:00
CScript pubKey2 ( pubKeySerialized . begin ( ) , pubKeySerialized . end ( ) ) ;
2014-10-25 09:24:14 -03:00
popstack ( stack ) ;
2014-08-27 14:11:41 -04:00
2018-03-09 11:03:40 -03:00
if ( ! EvalScript ( stack , pubKey2 , flags , checker , SigVersion : : BASE , serror ) )
2014-11-01 00:29:12 -03:00
// serror is set
2014-08-27 14:11:41 -04:00
return false ;
2014-10-25 09:24:14 -03:00
if ( stack . empty ( ) )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_EVAL_FALSE ) ;
2014-10-25 09:24:14 -03:00
if ( ! CastToBool ( stack . back ( ) ) )
2014-11-01 00:29:12 -03:00
return set_error ( serror , SCRIPT_ERR_EVAL_FALSE ) ;
2015-11-07 21:16:45 -03:00
// P2SH witness program
if ( flags & SCRIPT_VERIFY_WITNESS ) {
if ( pubKey2 . IsWitnessProgram ( witnessversion , witnessprogram ) ) {
hadWitness = true ;
if ( scriptSig ! = CScript ( ) < < std : : vector < unsigned char > ( pubKey2 . begin ( ) , pubKey2 . end ( ) ) ) {
// The scriptSig must be _exactly_ a single push of the redeemScript. Otherwise we
// reintroduce malleability.
return set_error ( serror , SCRIPT_ERR_WITNESS_MALLEATED_P2SH ) ;
}
if ( ! VerifyWitnessProgram ( * witness , witnessversion , witnessprogram , flags , checker , serror ) ) {
return false ;
}
// Bypass the cleanstack check at the end. The actual stack is obviously not clean
// for witness programs.
stack . resize ( 1 ) ;
}
}
2014-10-12 22:39:47 -03:00
}
// The CLEANSTACK check is only performed after potential P2SH evaluation,
// as the non-P2SH evaluation of a P2SH script will obviously not result in
2015-11-07 21:16:45 -03:00
// a clean stack (the P2SH inputs remain). The same holds for witness evaluation.
2014-10-12 22:39:47 -03:00
if ( ( flags & SCRIPT_VERIFY_CLEANSTACK ) ! = 0 ) {
// Disallow CLEANSTACK without P2SH, as otherwise a switch CLEANSTACK->P2SH+CLEANSTACK
// would be possible, which is not a softfork (and P2SH should be one).
assert ( ( flags & SCRIPT_VERIFY_P2SH ) ! = 0 ) ;
2015-11-07 21:16:45 -03:00
assert ( ( flags & SCRIPT_VERIFY_WITNESS ) ! = 0 ) ;
2014-10-12 22:39:47 -03:00
if ( stack . size ( ) ! = 1 ) {
return set_error ( serror , SCRIPT_ERR_CLEANSTACK ) ;
}
2014-08-27 14:11:41 -04:00
}
2015-11-07 21:16:45 -03:00
if ( flags & SCRIPT_VERIFY_WITNESS ) {
// We can't check for correct unexpected witness data if P2SH was off, so require
// that WITNESS implies P2SH. Otherwise, going from WITNESS->P2SH+WITNESS would be
// possible, which is not a softfork.
assert ( ( flags & SCRIPT_VERIFY_P2SH ) ! = 0 ) ;
if ( ! hadWitness & & ! witness - > IsNull ( ) ) {
return set_error ( serror , SCRIPT_ERR_WITNESS_UNEXPECTED ) ;
}
}
2014-11-01 00:29:12 -03:00
return set_success ( serror ) ;
2014-08-27 14:11:41 -04:00
}
2016-01-03 14:54:50 -03:00
2018-06-27 17:26:52 -04:00
size_t static WitnessSigOps ( int witversion , const std : : vector < unsigned char > & witprogram , const CScriptWitness & witness )
2016-01-03 14:54:50 -03:00
{
if ( witversion = = 0 ) {
2018-04-11 00:13:32 -03:00
if ( witprogram . size ( ) = = WITNESS_V0_KEYHASH_SIZE )
2016-01-03 14:54:50 -03:00
return 1 ;
2018-04-11 00:13:32 -03:00
if ( witprogram . size ( ) = = WITNESS_V0_SCRIPTHASH_SIZE & & witness . stack . size ( ) > 0 ) {
2016-01-03 14:54:50 -03:00
CScript subscript ( witness . stack . back ( ) . begin ( ) , witness . stack . back ( ) . end ( ) ) ;
return subscript . GetSigOpCount ( true ) ;
}
}
// Future flags may be implemented here.
return 0 ;
}
size_t CountWitnessSigOps ( const CScript & scriptSig , const CScript & scriptPubKey , const CScriptWitness * witness , unsigned int flags )
{
static const CScriptWitness witnessEmpty ;
if ( ( flags & SCRIPT_VERIFY_WITNESS ) = = 0 ) {
return 0 ;
}
assert ( ( flags & SCRIPT_VERIFY_P2SH ) ! = 0 ) ;
int witnessversion ;
std : : vector < unsigned char > witnessprogram ;
if ( scriptPubKey . IsWitnessProgram ( witnessversion , witnessprogram ) ) {
2018-06-27 17:26:52 -04:00
return WitnessSigOps ( witnessversion , witnessprogram , witness ? * witness : witnessEmpty ) ;
2016-01-03 14:54:50 -03:00
}
if ( scriptPubKey . IsPayToScriptHash ( ) & & scriptSig . IsPushOnly ( ) ) {
CScript : : const_iterator pc = scriptSig . begin ( ) ;
2017-01-04 02:42:14 -03:00
std : : vector < unsigned char > data ;
2016-01-03 14:54:50 -03:00
while ( pc < scriptSig . end ( ) ) {
opcodetype opcode ;
scriptSig . GetOp ( pc , opcode , data ) ;
}
CScript subscript ( data . begin ( ) , data . end ( ) ) ;
if ( subscript . IsWitnessProgram ( witnessversion , witnessprogram ) ) {
2018-06-27 17:26:52 -04:00
return WitnessSigOps ( witnessversion , witnessprogram , witness ? * witness : witnessEmpty ) ;
2016-01-03 14:54:50 -03:00
}
}
return 0 ;
}