17 #if defined(HAVE_CONSENSUS_LIB)
21 #include <boost/algorithm/string/classification.hpp>
22 #include <boost/test/unit_test.hpp>
42 BOOST_ERROR(
"Parse error.");
90 for (
unsigned int i=0; i<
ARRAYLEN(script_errors); ++i)
91 if (script_errors[i].err == err)
92 return script_errors[i].
name;
93 BOOST_ERROR(
"Unknown scripterror enumeration value, update script_errors in script_tests.cpp.");
99 for (
unsigned int i=0; i<
ARRAYLEN(script_errors); ++i)
101 return script_errors[i].
err;
102 BOOST_ERROR(
"Unknown scripterror \"" <<
name <<
"\" in test description");
113 txCredit.
vin.resize(1);
114 txCredit.
vout.resize(1);
115 txCredit.
vin[0].prevout.SetNull();
118 txCredit.
vout[0].scriptPubKey = scriptPubKey;
119 txCredit.
vout[0].nValue = 0;
129 txSpend.
vin.resize(1);
130 txSpend.
vout.resize(1);
131 txSpend.
vin[0].prevout.hash = txCredit.
GetHash();
132 txSpend.
vin[0].prevout.n = 0;
133 txSpend.
vin[0].scriptSig = scriptSig;
136 txSpend.
vout[0].nValue = 0;
147 static const CAmount amountZero = 0;
151 #if defined(HAVE_CONSENSUS_LIB)
158 void static NegateSignatureS(std::vector<unsigned char>& vchSig) {
160 std::vector<unsigned char> r, s;
161 r = std::vector<unsigned char>(vchSig.begin() + 4, vchSig.begin() + 4 + vchSig[3]);
162 s = std::vector<unsigned char>(vchSig.begin() + 6 + vchSig[3], vchSig.begin() + 6 + vchSig[3] + vchSig[5 + vchSig[3]]);
165 static const unsigned char order[33] = {
167 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
168 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
169 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
170 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41
172 while (s.size() < 33) {
173 s.insert(s.begin(), 0x00);
176 for (
int p = 32; p >= 1; p--) {
177 int n = (int)order[p] - s[p] - carry;
178 s[p] = (n + 256) & 0xFF;
182 if (s.size() > 1 && s[0] == 0 && s[1] < 0x80) {
188 vchSig.push_back(0x30);
189 vchSig.push_back(4 + r.size() + s.size());
190 vchSig.push_back(0x02);
191 vchSig.push_back(r.size());
192 vchSig.insert(vchSig.end(), r.begin(), r.end());
193 vchSig.push_back(0x02);
194 vchSig.push_back(s.size());
195 vchSig.insert(vchSig.end(), s.begin(), s.end());
200 const unsigned char vchKey0[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
201 const unsigned char vchKey1[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0};
202 const unsigned char vchKey2[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0};
206 CKey key0, key0C, key1, key1C, key2, key2C;
207 CPubKey pubkey0, pubkey0C, pubkey0H;
214 key0.
Set(vchKey0, vchKey0 + 32,
false);
215 key0C.
Set(vchKey0, vchKey0 + 32,
true);
219 *
const_cast<unsigned char*
>(&pubkey0H[0]) = 0x06 | (pubkey0H[64] & 1);
221 key1.
Set(vchKey1, vchKey1 + 32,
false);
222 key1C.
Set(vchKey1, vchKey1 + 32,
true);
226 key2.
Set(vchKey2, vchKey2 + 32,
false);
227 key2C.
Set(vchKey2, vchKey2 + 32,
true);
241 std::vector<unsigned char> push;
249 spendTx.
vin[0].scriptSig << push;
254 void DoPush(
const std::vector<unsigned char>& data)
262 TestBuilder(
const CScript& redeemScript,
const std::string& comment_,
int flags_,
bool P2SH =
false) : scriptPubKey(redeemScript), havePush(
false), comment(comment_),
flags(flags_), scriptError(
SCRIPT_ERR_OK)
278 TestBuilder& Add(
const CScript& script)
281 spendTx.
vin[0].scriptSig += script;
285 TestBuilder& Num(
int num)
288 spendTx.
vin[0].scriptSig << num;
292 TestBuilder& Push(
const std::string& hex)
298 TestBuilder& PushSig(
const CKey& key,
int nHashType =
SIGHASH_ALL,
unsigned int lenR = 32,
unsigned int lenS = 32)
301 std::vector<unsigned char> vchSig, r, s;
304 key.
Sign(hash, vchSig, iter++);
305 if ((lenS == 33) != (vchSig[5 + vchSig[3]] == 33)) {
306 NegateSignatureS(vchSig);
308 r = std::vector<unsigned char>(vchSig.begin() + 4, vchSig.begin() + 4 + vchSig[3]);
309 s = std::vector<unsigned char>(vchSig.begin() + 6 + vchSig[3], vchSig.begin() + 6 + vchSig[3] + vchSig[5 + vchSig[3]]);
310 }
while (lenR != r.size() || lenS != s.size());
311 vchSig.push_back(
static_cast<unsigned char>(nHashType));
316 TestBuilder& Push(
const CPubKey& pubkey)
318 DoPush(std::vector<unsigned char>(pubkey.
begin(), pubkey.
end()));
322 TestBuilder& PushRedeem()
324 DoPush(std::vector<unsigned char>(scriptPubKey.
begin(), scriptPubKey.
end()));
328 TestBuilder& EditPush(
unsigned int pos,
const std::string& hexin,
const std::string& hexout)
331 std::vector<unsigned char> datain =
ParseHex(hexin);
332 std::vector<unsigned char> dataout =
ParseHex(hexout);
333 assert(pos + datain.size() <= push.size());
334 BOOST_CHECK_MESSAGE(std::vector<unsigned char>(push.begin() + pos, push.begin() + pos + datain.size()) == datain, comment);
335 push.erase(push.begin() + pos, push.begin() + pos + datain.size());
336 push.insert(push.begin() + pos, dataout.begin(), dataout.end());
340 TestBuilder& DamagePush(
unsigned int pos)
343 assert(pos < push.size());
350 TestBuilder copy = *
this;
352 DoTest(creditTx->vout[0].scriptPubKey, spendTx.
vin[0].scriptSig,
flags, comment, scriptError);
362 array.push_back(
FormatScript(creditTx->vout[0].scriptPubKey));
365 array.push_back(comment);
369 std::string GetComment()
375 std::string JSONPrettyPrint(
const UniValue& univalue)
377 std::string ret = univalue.
write(4);
380 while ((pos = ret.find(
" \n", pos)) != std::string::npos) {
381 ret.replace(pos, 2,
"\n");
392 std::vector<TestBuilder> tests;
396 ).PushSig(keys.key0));
403 ).PushSig(keys.key1).Push(keys.pubkey1C));
405 "P2PKH, bad pubkey", 0
409 "P2PK anyonecanpay", 0
412 "P2PK anyonecanpay marked with normal hashtype", 0
417 ).PushSig(keys.key0).PushRedeem());
424 ).PushSig(keys.key0).Push(keys.pubkey0).PushRedeem());
426 "P2SH(P2PKH), bad sig but no VERIFY_P2SH", 0,
true
427 ).PushSig(keys.key0).DamagePush(10).PushRedeem());
434 ).Num(0).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2));
441 ).Num(0).PushSig(keys.key1).PushSig(keys.key2).PushRedeem());
447 "P2PK with too much R padding but no DERSIG", 0
448 ).PushSig(keys.key1,
SIGHASH_ALL, 31, 32).EditPush(1,
"43021F",
"44022000"));
453 "P2PK with too much S padding but no DERSIG", 0
454 ).PushSig(keys.key1,
SIGHASH_ALL).EditPush(1,
"44",
"45").EditPush(37,
"20",
"2100"));
459 "P2PK with too little R padding but no DERSIG", 0
460 ).PushSig(keys.key1,
SIGHASH_ALL, 33, 32).EditPush(1,
"45022100",
"440220"));
465 "P2PK NOT with bad sig with too much R padding but no DERSIG", 0
466 ).PushSig(keys.key2,
SIGHASH_ALL, 31, 32).EditPush(1,
"43021F",
"44022000").DamagePush(10));
471 "P2PK NOT with too much R padding but no DERSIG", 0
478 "BIP66 example 1, without DERSIG", 0
479 ).PushSig(keys.key1,
SIGHASH_ALL, 33, 32).EditPush(1,
"45022100",
"440220"));
484 "BIP66 example 2, without DERSIG", 0
490 "BIP66 example 3, without DERSIG", 0
496 "BIP66 example 4, without DERSIG", 0
502 "BIP66 example 5, without DERSIG", 0
508 "BIP66 example 6, without DERSIG", 0
514 "BIP66 example 7, without DERSIG", 0
515 ).Num(0).PushSig(keys.key1,
SIGHASH_ALL, 33, 32).EditPush(1,
"45022100",
"440220").PushSig(keys.key2));
520 "BIP66 example 8, without DERSIG", 0
526 "BIP66 example 9, without DERSIG", 0
532 "BIP66 example 10, without DERSIG", 0
533 ).Num(0).Num(0).PushSig(keys.key2,
SIGHASH_ALL, 33, 32).EditPush(1,
"45022100",
"440220"));
538 "BIP66 example 11, without DERSIG", 0
544 "BIP66 example 12, without DERSIG", 0
545 ).Num(0).PushSig(keys.key1,
SIGHASH_ALL, 33, 32).EditPush(1,
"45022100",
"440220").Num(0));
548 ).Num(0).PushSig(keys.key1,
SIGHASH_ALL, 33, 32).EditPush(1,
"45022100",
"440220").Num(0));
550 "P2PK with multi-byte hashtype, without DERSIG", 0
551 ).PushSig(keys.key2,
SIGHASH_ALL).EditPush(70,
"01",
"0101"));
557 "P2PK with high S but no LOW_S", 0
564 "P2PK with hybrid pubkey but no STRICTENC", 0
570 "P2PK NOT with hybrid pubkey but no STRICTENC", 0
576 "P2PK NOT with invalid hybrid pubkey but no STRICTENC", 0
582 "1-of-2 with the second 1 hybrid pubkey and no STRICTENC", 0
592 "P2PK with undefined hashtype but no STRICTENC", 0
593 ).PushSig(keys.key1, 5));
598 "P2PK NOT with invalid sig and undefined hashtype but no STRICTENC", 0
599 ).PushSig(keys.key1, 5).DamagePush(10));
605 "3-of-3 with nonzero dummy but no NULLDUMMY", 0
606 ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2));
611 "3-of-3 NOT with invalid sig and nonzero dummy but no NULLDUMMY", 0
612 ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).DamagePush(10));
615 ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).DamagePush(10).ScriptError(
SCRIPT_ERR_SIG_NULLDUMMY));
618 "2-of-2 with two identical keys and sigs pushed using OP_DUP but no SIGPUSHONLY", 0
624 "P2SH(P2PK) with non-push scriptSig but no P2SH or SIGPUSHONLY", 0,
true
627 "P2PK with non-push scriptSig but with P2SH validation", 0
637 ).Num(0).PushSig(keys.key1).PushSig(keys.key1));
640 ).Num(11).PushSig(keys.key0));
646 ).Num(11).PushSig(keys.key0).PushRedeem());
652 ).PushSig(keys.key0).PushRedeem());
655 std::set<std::string> tests_set;
658 UniValue json_tests =
read_json(std::string(json_tests::script_tests, json_tests::script_tests +
sizeof(json_tests::script_tests)));
660 for (
unsigned int idx = 0; idx <
json_tests.size(); idx++) {
662 tests_set.insert(JSONPrettyPrint(tv.
get_array()));
668 for (TestBuilder& test : tests) {
670 std::string str = JSONPrettyPrint(test.GetJSON());
671 #ifndef UPDATE_JSON_TESTS
672 if (tests_set.count(str) == 0) {
673 BOOST_CHECK_MESSAGE(
false,
"Missing auto script_valid test: " + test.GetComment());
676 strGen += str +
",\n";
679 #ifdef UPDATE_JSON_TESTS
680 FILE* file =
fopen(
"script_tests.json.gen",
"w");
681 fputs(strGen.c_str(), file);
693 UniValue tests =
read_json(std::string(json_tests::script_tests, json_tests::script_tests +
sizeof(json_tests::script_tests)));
695 for (
unsigned int idx = 0; idx < tests.
size(); idx++) {
697 std::string strTest = test.
write();
700 if (test.
size() != 1) {
701 BOOST_ERROR(
"Bad test: " << strTest);
705 std::string scriptSigString = test[0].
get_str();
707 std::string scriptPubKeyString = test[1].
get_str();
712 DoTest(scriptPubKey, scriptSig, scriptflags, strTest, scriptError);
720 static const unsigned char direct[] = { 1, 0x5a };
721 static const unsigned char pushdata1[] = {
OP_PUSHDATA1, 1, 0x5a };
722 static const unsigned char pushdata2[] = {
OP_PUSHDATA2, 1, 0, 0x5a };
723 static const unsigned char pushdata4[] = {
OP_PUSHDATA4, 1, 0, 0, 0, 0x5a };
726 std::vector<std::vector<unsigned char> > directStack;
730 std::vector<std::vector<unsigned char> > pushdata1Stack;
735 std::vector<std::vector<unsigned char> > pushdata2Stack;
740 std::vector<std::vector<unsigned char> > pushdata4Stack;
761 for (
const CKey &key : keys)
763 std::vector<unsigned char> vchSig;
773 std::vector<CKey> keys;
781 CKey key1, key2, key3;
796 txTo12.
vout[0].nValue = 2;
812 CKey key1, key2, key3, key4;
825 std::vector<CKey> keys;
826 keys.push_back(key1); keys.push_back(key2);
832 keys.push_back(key1); keys.push_back(key3);
838 keys.push_back(key2); keys.push_back(key3);
844 keys.push_back(key2); keys.push_back(key2);
850 keys.push_back(key2); keys.push_back(key1);
856 keys.push_back(key3); keys.push_back(key2);
862 keys.push_back(key4); keys.push_back(key2);
868 keys.push_back(key1); keys.push_back(key4);
884 std::vector<CKey> keys;
885 std::vector<CPubKey> pubkeys;
886 for (
int i = 0; i < 3; i++)
897 CScript& scriptPubKey = txFrom.
vout[0].scriptPubKey;
910 CScript scriptSigCopy = scriptSig;
925 scriptSigCopy = scriptSig;
930 scriptSigCopy =
CScript() << OP_0 << std::vector<unsigned char>(pkSingle.
begin(), pkSingle.
end());
946 std::vector<unsigned char> sig1;
950 std::vector<unsigned char> sig2;
954 std::vector<unsigned char> sig3;
993 for (
int i=0; i<67000; i++) {
996 BOOST_CHECK_MESSAGE(script.
IsPushOnly(),
"Number " << i <<
" is not pure push.");
1001 for (
unsigned int i=0; i<=MAX_SCRIPT_ELEMENT_SIZE; i++) {
1002 std::vector<unsigned char> data(i,
'\111');
1005 BOOST_CHECK_MESSAGE(script.
IsPushOnly(),
"Length " << i <<
" is not pure push.");
1018 static const unsigned char direct[] = { 1 };
1029 std::string derSig(
"304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090");
1030 std::string pubKey(
"03b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb2");
1054 ScriptFromHex(
const char* hex)
1056 std::vector<unsigned char> data =
ParseHex(hex);
1057 return CScript(data.begin(), data.end());
1086 s = ScriptFromHex(
"0302ff03");
1087 d = ScriptFromHex(
"0302ff03");
1092 s = ScriptFromHex(
"0302ff030302ff03");
1093 d = ScriptFromHex(
"0302ff03");
1098 s = ScriptFromHex(
"0302ff030302ff03");
1099 d = ScriptFromHex(
"02");
1104 s = ScriptFromHex(
"0302ff030302ff03");
1105 d = ScriptFromHex(
"ff");
1112 s = ScriptFromHex(
"0302ff030302ff03");
1113 d = ScriptFromHex(
"03");
1119 s = ScriptFromHex(
"02feed5169");
1120 d = ScriptFromHex(
"feed51");
1125 s = ScriptFromHex(
"02feed5169");
1126 d = ScriptFromHex(
"02feed51");
1127 expect = ScriptFromHex(
"69");
1131 s = ScriptFromHex(
"516902feed5169");
1132 d = ScriptFromHex(
"feed51");
1137 s = ScriptFromHex(
"516902feed5169");
1138 d = ScriptFromHex(
"02feed51");
1139 expect = ScriptFromHex(
"516969");
1157 s = ScriptFromHex(
"0003feed");
1158 d = ScriptFromHex(
"03feed");
1159 expect = ScriptFromHex(
"00");
1163 s = ScriptFromHex(
"0003feed");
1164 d = ScriptFromHex(
"00");
1165 expect = ScriptFromHex(
"03feed");
1174 s = ScriptFromHex(
"00");
1176 d = ScriptFromHex(
"0000");
1180 static const char hex[] =
"04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f";
int64_t CAmount
Amount in PIV (Can be negative)
int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, const unsigned char *txTo, unsigned int txToLen, unsigned int nIn, unsigned int flags, bitcoinconsensus_error *err)
Returns 1 if the input nIn of the serialized transaction pointed to by txTo correctly spends the scri...
Basic key store, that keeps keys in an address->secret map.
virtual bool AddCScript(const CScript &redeemScript)
Support for BIP 0013 : see https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki.
An encapsulated private key.
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
CPubKey GetPubKey() const
Compute the public key from a private key.
bool Sign(const uint256 &hash, std::vector< unsigned char > &vchSig, uint32_t test_case=0) const
Create a DER-serialized signature.
void Set(const T pbegin, const T pend, bool fCompressedIn)
Initialize using begin and end iterators to byte data.
virtual bool AddKey(const CKey &key)
An encapsulated public key.
const unsigned char * end() const
const unsigned char * begin() const
Serialized script, used inside transaction inputs and outputs.
bool IsPushOnly(const_iterator pc) const
Called by IsStandardTx and P2SH/BIP62 VerifyScript (which makes it consensus-critical).
int FindAndDelete(const CScript &b)
A reference to a CScript: the Hash160 of its serialization (see script.h)
The basic transaction that is broadcasted on the network and contained in blocks.
static const uint32_t SEQUENCE_FINAL
const std::string & get_str() const
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
const UniValue & get_array() const
bool read(const char *raw, size_t len)
void push_back(const T &value)
CScript ParseScript(std::string s)
std::string FormatScript(const CScript &script)
std::string ScriptToAsmStr(const CScript &script, const bool fAttemptSighashDecode=false)
Create the assembly string representation of a CScript object.
BOOST_AUTO_TEST_SUITE_END()
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, unsigned int flags, const BaseSignatureChecker &checker, SigVersion sigversion, ScriptError *serror)
bool EvalScript(std::vector< std::vector< unsigned char > > &stack, const CScript &script, unsigned int flags, const BaseSignatureChecker &checker, SigVersion sigversion, ScriptError *serror)
uint256 SignatureHash(const CScript &scriptCode, const CTransaction &txTo, unsigned int nIn, int nHashType, const CAmount &amount, SigVersion sigversion, const PrecomputedTransactionData *cache)
@ SCRIPT_VERIFY_NULLDUMMY
@ SCRIPT_VERIFY_SIGPUSHONLY
@ SCRIPT_VERIFY_STRICTENC
@ SCRIPT_VERIFY_CLEANSTACK
@ SCRIPT_VERIFY_MINIMALDATA
FILE * fopen(const fs::path &p, const char *mode)
#define BOOST_FIXTURE_TEST_SUITE(a, b)
#define BOOST_CHECK_EQUAL(v1, v2)
#define BOOST_CHECK(expr)
std::vector< unsigned char > ToByteVector(const T &in)
const char * ScriptErrorString(const ScriptError serror)
enum ScriptError_t ScriptError
@ SCRIPT_ERR_SIG_PUSHONLY
@ SCRIPT_ERR_NUMEQUALVERIFY
@ SCRIPT_ERR_DISABLED_OPCODE
@ SCRIPT_ERR_INVALID_ALTSTACK_OPERATION
@ SCRIPT_ERR_UNKNOWN_ERROR
@ SCRIPT_ERR_SIG_HASHTYPE
@ SCRIPT_ERR_CHECKSIGVERIFY
@ SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS
@ SCRIPT_ERR_INVALID_STACK_OPERATION
@ SCRIPT_ERR_NEGATIVE_LOCKTIME
@ SCRIPT_ERR_SIG_NULLDUMMY
@ SCRIPT_ERR_CHECKMULTISIGVERIFY
@ SCRIPT_ERR_UNSATISFIED_LOCKTIME
@ SCRIPT_ERR_PUBKEY_COUNT
@ SCRIPT_ERR_UNBALANCED_CONDITIONAL
CScript sign_multisig(const CScript &scriptPubKey, const std::vector< CKey > &keys, const CTransaction &transaction)
CMutableTransaction BuildCreditingTransaction(const CScript &scriptPubKey)
UniValue read_json(const std::string &jsondata)
ScriptError_t ParseScriptError(const std::string &name)
CMutableTransaction BuildSpendingTransaction(const CScript &scriptSig, const CMutableTransaction &txCredit)
unsigned int ParseScriptFlags(std::string strFlags)
BOOST_AUTO_TEST_CASE(script_build)
std::string FormatScriptFlags(unsigned int flags)
const char * FormatScriptError(ScriptError_t err)
void DoTest(const CScript &scriptPubKey, const CScript &scriptSig, int flags, const std::string &message, int scriptError)
SignatureData CombineSignatures(const CScript &scriptPubKey, const BaseSignatureChecker &checker, const SignatureData &scriptSig1, const SignatureData &scriptSig2)
Combine two script signatures using a generic signature checker, intelligently, possibly with OP_0 pl...
bool SignSignature(const CKeyStore &keystore, const CScript &fromPubKey, CMutableTransaction &txTo, unsigned int nIn, const CAmount &amount, int nHashType, bool fColdStake)
Produce a script signature for a transaction.
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a PIVX scriptPubKey for the given CTxDestination.
A mutable version of CTransaction.
uint256 GetHash() const
Compute the hash of this CMutableTransaction.
SigVersion GetRequiredSigVersion() const
std::vector< CTxOut > vout
std::shared_ptr< const CTransaction > CTransactionRef
std::vector< unsigned char > ParseHex(const char *psz)