Browse Source

Merge pull request #6124

ffd75ad Enable CHECKLOCKTIMEVERIFY as a standard script verify flag (Peter Todd)
bc60b2b Replace NOP2 with CHECKLOCKTIMEVERIFY (BIP65) (Peter Todd)
48e9c57 Move LOCKTIME_THRESHOLD to src/script/script.h (Peter Todd)
99088d6 Make CScriptNum() take nMaxNumSize as an argument (Peter Todd)
0.13
Wladimir J. van der Laan 10 years ago
parent
commit
41076aad0c
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 2
      src/consensus/consensus.h
  2. 81
      src/script/interpreter.cpp
  3. 11
      src/script/interpreter.h
  4. 12
      src/script/script.h
  5. 4
      src/script/script_error.cpp
  6. 4
      src/script/script_error.h
  7. 3
      src/script/standard.h
  8. 64
      src/test/data/tx_invalid.json
  9. 42
      src/test/data/tx_valid.json
  10. 2
      src/test/scriptnum_tests.cpp
  11. 3
      src/test/transaction_tests.cpp

2
src/consensus/consensus.h

@ -12,7 +12,5 @@ static const unsigned int MAX_BLOCK_SIZE = 1000000; @@ -12,7 +12,5 @@ static const unsigned int MAX_BLOCK_SIZE = 1000000;
static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
/** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */
static const int COINBASE_MATURITY = 100;
/** Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp. */
static const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC
#endif // BITCOIN_CONSENSUS_CONSENSUS_H

81
src/script/interpreter.cpp

@ -337,7 +337,49 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un @@ -337,7 +337,49 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
case OP_NOP:
break;
case OP_NOP1: case OP_NOP2: case OP_NOP3: case OP_NOP4: case OP_NOP5:
case OP_CHECKLOCKTIMEVERIFY:
{
if (!(flags & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)) {
// not enabled; treat as a NOP2
if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
}
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;
}
case OP_NOP1: case OP_NOP3: case OP_NOP4: case OP_NOP5:
case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10:
{
if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
@ -1084,6 +1126,43 @@ bool TransactionSignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn @@ -1084,6 +1126,43 @@ bool TransactionSignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn
return true;
}
bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) const
{
// There are two times of nLockTime: lock-by-blockheight
// and lock-by-blocktime, distinguished by whether
// nLockTime < LOCKTIME_THRESHOLD.
//
// 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 (!(
(txTo->nLockTime < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) ||
(txTo->nLockTime >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD)
))
return false;
// Now that we know we're comparing apples-to-apples, the
// comparison is a simple numeric one.
if (nLockTime > (int64_t)txTo->nLockTime)
return false;
// Finally the nLockTime feature can be disabled and thus
// 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.
if (txTo->vin[nIn].IsFinal())
return false;
return true;
}
bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror)
{
set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR);

11
src/script/interpreter.h

@ -76,6 +76,11 @@ enum @@ -76,6 +76,11 @@ enum
// (softfork safe, BIP62 rule 6)
// Note: CLEANSTACK should never be used without P2SH.
SCRIPT_VERIFY_CLEANSTACK = (1U << 8),
// Verify CHECKLOCKTIMEVERIFY
//
// See BIP65 for details.
SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9),
};
uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
@ -88,6 +93,11 @@ public: @@ -88,6 +93,11 @@ public:
return false;
}
virtual bool CheckLockTime(const CScriptNum& nLockTime) const
{
return false;
}
virtual ~BaseSignatureChecker() {}
};
@ -103,6 +113,7 @@ protected: @@ -103,6 +113,7 @@ protected:
public:
TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn) : txTo(txToIn), nIn(nInIn) {}
bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode) const;
bool CheckLockTime(const CScriptNum& nLockTime) const;
};
class MutableTransactionSignatureChecker : public TransactionSignatureChecker

12
src/script/script.h

@ -19,6 +19,10 @@ @@ -19,6 +19,10 @@
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // bytes
// Threshold for nLockTime: below this value it is interpreted as block number,
// otherwise as UNIX timestamp.
static const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC
template <typename T>
std::vector<unsigned char> ToByteVector(const T& in)
{
@ -151,6 +155,7 @@ enum opcodetype @@ -151,6 +155,7 @@ enum opcodetype
// expansion
OP_NOP1 = 0xb0,
OP_NOP2 = 0xb1,
OP_CHECKLOCKTIMEVERIFY = OP_NOP2,
OP_NOP3 = 0xb2,
OP_NOP4 = 0xb3,
OP_NOP5 = 0xb4,
@ -196,7 +201,10 @@ public: @@ -196,7 +201,10 @@ public:
m_value = n;
}
explicit CScriptNum(const std::vector<unsigned char>& vch, bool fRequireMinimal)
static const size_t nDefaultMaxNumSize = 4;
explicit CScriptNum(const std::vector<unsigned char>& vch, bool fRequireMinimal,
const size_t nMaxNumSize = nDefaultMaxNumSize)
{
if (vch.size() > nMaxNumSize) {
throw scriptnum_error("script number overflow");
@ -319,8 +327,6 @@ public: @@ -319,8 +327,6 @@ public:
return result;
}
static const size_t nMaxNumSize = 4;
private:
static int64_t set_vch(const std::vector<unsigned char>& vch)
{

4
src/script/script_error.cpp

@ -47,6 +47,10 @@ const char* ScriptErrorString(const ScriptError serror) @@ -47,6 +47,10 @@ const char* ScriptErrorString(const ScriptError serror)
return "OP_RETURN was encountered";
case SCRIPT_ERR_UNBALANCED_CONDITIONAL:
return "Invalid OP_IF construction";
case SCRIPT_ERR_NEGATIVE_LOCKTIME:
return "Negative locktime";
case SCRIPT_ERR_UNSATISFIED_LOCKTIME:
return "Locktime requirement not satisfied";
case SCRIPT_ERR_SIG_HASHTYPE:
return "Signature hash type missing or not understood";
case SCRIPT_ERR_SIG_DER:

4
src/script/script_error.h

@ -35,6 +35,10 @@ typedef enum ScriptError_t @@ -35,6 +35,10 @@ typedef enum ScriptError_t
SCRIPT_ERR_INVALID_ALTSTACK_OPERATION,
SCRIPT_ERR_UNBALANCED_CONDITIONAL,
/* OP_CHECKLOCKTIMEVERIFY */
SCRIPT_ERR_NEGATIVE_LOCKTIME,
SCRIPT_ERR_UNSATISFIED_LOCKTIME,
/* BIP62 */
SCRIPT_ERR_SIG_HASHTYPE,
SCRIPT_ERR_SIG_DER,

3
src/script/standard.h

@ -50,7 +50,8 @@ static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY @@ -50,7 +50,8 @@ static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY
SCRIPT_VERIFY_MINIMALDATA |
SCRIPT_VERIFY_NULLDUMMY |
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS |
SCRIPT_VERIFY_CLEANSTACK;
SCRIPT_VERIFY_CLEANSTACK |
SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
/** For convenience, standard but not mandatory verify flags. */
static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS;

64
src/test/data/tx_invalid.json

@ -120,6 +120,70 @@ @@ -120,6 +120,70 @@
[[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "IF CODESEPARATOR ENDIF 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 CHECKSIGVERIFY CODESEPARATOR 1"]],
"010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a9000000004a483045022100fa4a74ba9fd59c59f46c3960cf90cbe0d2b743c471d24a3d5d6db6002af5eebb02204d70ec490fd0f7055a7c45f86514336e3a7f03503dacecabb247fc23f15c83510100ffffffff010000000000000000016a00000000", "P2SH"],
["CHECKLOCKTIMEVERIFY tests"],
["By-height locks, with argument just beyond tx nLockTime"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1 NOP2 1"]],
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000fe64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
["By-time locks, with argument just beyond tx nLockTime (but within numerical boundries)"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000001 NOP2 1"]],
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000feffffff", "P2SH,CHECKLOCKTIMEVERIFY"],
["Argument missing"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "NOP2 1"]],
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
["Argument negative with by-blockheight nLockTime=0"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP2 1"]],
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
["Argument negative with by-blocktime nLockTime=500,000,000"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP2 1"]],
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
["Input locked"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]],
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
["Another input being unlocked isn't sufficient; the CHECKLOCKTIMEVERIFY-using input must be unlocked"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"] ,
["0000000000000000000000000000000000000000000000000000000000000200", 1, "1"]],
"010000000200010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00020000000000000000000000000000000000000000000000000000000000000100000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
["Argument/tx height/time mismatch, both versions"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]],
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]],
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]],
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
["Argument 2^32 with nLockTime=2^32-1"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967296 NOP2 1"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"],
["Same, but with nLockTime=2^31-1"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP2 1"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffff7f", "P2SH,CHECKLOCKTIMEVERIFY"],
["6 byte non-minimally-encoded arguments are invalid even in their contents are valid"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x06 0x000000000000 NOP2 1"]],
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
["Failure due to failing CHECKLOCKTIMEVERIFY in scriptSig"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]],
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000251b1000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
["Failure due to failing CHECKLOCKTIMEVERIFY in redeemScript"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xc5b93064159b3b2d6ab506a41b1f50463771b988 EQUAL"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000030251b1000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
["Make diffs cleaner by leaving a comment here without comma at the end"]
]

42
src/test/data/tx_valid.json

@ -187,5 +187,47 @@ @@ -187,5 +187,47 @@
"0100000002dbb33bdf185b17f758af243c5d3c6e164cc873f6bb9f40c0677d6e0f8ee5afce000000006b4830450221009627444320dc5ef8d7f68f35010b4c050a6ed0d96b67a84db99fda9c9de58b1e02203e4b4aaa019e012e65d69b487fdf8719df72f488fa91506a80c49a33929f1fd50121022b78b756e2258af13779c1a1f37ea6800259716ca4b7f0b87610e0bf3ab52a01ffffffffdbb33bdf185b17f758af243c5d3c6e164cc873f6bb9f40c0677d6e0f8ee5afce010000009300483045022015bd0139bcccf990a6af6ec5c1c52ed8222e03a0d51c334df139968525d2fcd20221009f9efe325476eb64c3958e4713e9eefe49bf1d820ed58d2112721b134e2a1a5303483045022015bd0139bcccf990a6af6ec5c1c52ed8222e03a0d51c334df139968525d2fcd20221009f9efe325476eb64c3958e4713e9eefe49bf1d820ed58d2112721b134e2a1a5303ffffffff01a0860100000000001976a9149bc0bbdd3024da4d0c38ed1aecf5c68dd1d3fa1288ac00000000", "P2SH"],
["CHECKLOCKTIMEVERIFY tests"],
["By-height locks, with argument == 0 and == tx nLockTime"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]],
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
["By-time locks, with argument just beyond tx nLockTime (but within numerical boundries)"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]],
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"],
["Any non-maxint nSequence is fine"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]],
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000feffffff0100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
["The argument can be calculated rather than created directly by a PUSHDATA"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 1ADD NOP2 1"]],
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
["Perhaps even by an ADD producing a 5-byte result that is out of bounds for other opcodes"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483647 2147483647 ADD NOP2 1"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000feffffff", "P2SH,CHECKLOCKTIMEVERIFY"],
["5 byte non-minimally-encoded arguments are valid"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x05 0x0000000000 NOP2 1"]],
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
["Valid CHECKLOCKTIMEVERIFY in scriptSig"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]],
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000251b1000000000100000000000000000001000000", "P2SH,CHECKLOCKTIMEVERIFY"],
["Valid CHECKLOCKTIMEVERIFY in redeemScript"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xc5b93064159b3b2d6ab506a41b1f50463771b988 EQUAL"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000030251b1000000000100000000000000000001000000", "P2SH,CHECKLOCKTIMEVERIFY"],
["Make diffs cleaner by leaving a comment here without comma at the end"]
]

2
src/test/scriptnum_tests.cpp

@ -145,7 +145,7 @@ static void RunCreate(const int64_t& num) @@ -145,7 +145,7 @@ static void RunCreate(const int64_t& num)
{
CheckCreateInt(num);
CScriptNum scriptnum(num);
if (scriptnum.getvch().size() <= CScriptNum::nMaxNumSize)
if (scriptnum.getvch().size() <= CScriptNum::nDefaultMaxNumSize)
CheckCreateVch(num);
else
{

3
src/test/transaction_tests.cpp

@ -41,7 +41,8 @@ static std::map<string, unsigned int> mapFlagNames = boost::assign::map_list_of @@ -41,7 +41,8 @@ static std::map<string, unsigned int> mapFlagNames = boost::assign::map_list_of
(string("MINIMALDATA"), (unsigned int)SCRIPT_VERIFY_MINIMALDATA)
(string("NULLDUMMY"), (unsigned int)SCRIPT_VERIFY_NULLDUMMY)
(string("DISCOURAGE_UPGRADABLE_NOPS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
(string("CLEANSTACK"), (unsigned int)SCRIPT_VERIFY_CLEANSTACK);
(string("CLEANSTACK"), (unsigned int)SCRIPT_VERIFY_CLEANSTACK)
(string("CHECKLOCKTIMEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY);
unsigned int ParseScriptFlags(string strFlags)
{

Loading…
Cancel
Save