From cb97745e369db97dc50a799c7823b6df1bd944b3 Mon Sep 17 00:00:00 2001 From: Alessandro Rezzi Date: Fri, 2 Feb 2024 09:57:19 +0100 Subject: [PATCH 01/16] feat: add dip143 sigversion --- src/script/interpreter.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 573164e8f431..b0c7801cd16f 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -127,6 +127,7 @@ struct PrecomputedTransactionData enum class SigVersion { BASE = 0, + DIP0143 = 1, }; template From 8ba048303b7afdd8d339fe0496ecff3e9d914f55 Mon Sep 17 00:00:00 2001 From: Alessandro Rezzi Date: Sat, 10 Feb 2024 14:34:09 +0100 Subject: [PATCH 02/16] feat: add SIGHASH_DIP0143 --- src/script/interpreter.cpp | 2 +- src/script/interpreter.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 9ad410052422..7777abd9e688 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -190,7 +190,7 @@ bool static IsDefinedHashtypeSignature(const valtype &vchSig) { if (vchSig.size() == 0) { return false; } - unsigned char nHashType = vchSig[vchSig.size() - 1] & (~(SIGHASH_ANYONECANPAY)); + unsigned char nHashType = vchSig[vchSig.size() - 1] & (~(SIGHASH_ANYONECANPAY)) & (~(SIGHASH_DIP0143)); if (nHashType < SIGHASH_ALL || nHashType > SIGHASH_SINGLE) return false; diff --git a/src/script/interpreter.h b/src/script/interpreter.h index b0c7801cd16f..af593e751fbc 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -24,6 +24,7 @@ enum SIGHASH_ALL = 1, SIGHASH_NONE = 2, SIGHASH_SINGLE = 3, + SIGHASH_DIP0143 = 0x40, SIGHASH_ANYONECANPAY = 0x80, }; From 437ef2fdd296d0c6b59ed28fc8addbba58cdd84c Mon Sep 17 00:00:00 2001 From: Alessandro Rezzi Date: Sat, 10 Feb 2024 14:39:47 +0100 Subject: [PATCH 03/16] refactor: return directly the double sha256 when needed --- src/script/interpreter.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 7777abd9e688..7fc638a1bed5 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1481,37 +1481,37 @@ class CTransactionSignatureSerializer } }; -/** Compute the (single) SHA256 of the concatenation of all prevouts of a tx. */ +/** Compute the double SHA256 of the concatenation of all prevouts of a tx. */ template -uint256 GetPrevoutsSHA256(const T& txTo) +uint256 GetPrevoutsHash(const T& txTo) { CHashWriter ss(SER_GETHASH, 0); for (const auto& txin : txTo.vin) { ss << txin.prevout; } - return ss.GetSHA256(); + return ss.GetHash(); } -/** Compute the (single) SHA256 of the concatenation of all nSequences of a tx. */ +/** Compute the double SHA256 of the concatenation of all nSequences of a tx. */ template -uint256 GetSequencesSHA256(const T& txTo) +uint256 GetSequencesHash(const T& txTo) { CHashWriter ss(SER_GETHASH, 0); for (const auto& txin : txTo.vin) { ss << txin.nSequence; } - return ss.GetSHA256(); + return ss.GetHash(); } -/** Compute the (single) SHA256 of the concatenation of all txouts of a tx. */ +/** Compute the double SHA256 of the concatenation of all txouts of a tx. */ template -uint256 GetOutputsSHA256(const T& txTo) +uint256 GetOutputsHash(const T& txTo) { CHashWriter ss(SER_GETHASH, 0); for (const auto& txout : txTo.vout) { ss << txout; } - return ss.GetSHA256(); + return ss.GetHash(); } } // namespace From 7d33c86f700f0c8cb08269457af6d2ead94b4fa3 Mon Sep 17 00:00:00 2001 From: Alessandro Rezzi Date: Sat, 10 Feb 2024 14:32:04 +0100 Subject: [PATCH 04/16] feat: implement dip143 transaction sighash --- src/script/interpreter.cpp | 54 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 7fc638a1bed5..7f76012be8ea 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1522,6 +1522,9 @@ void PrecomputedTransactionData::Init(const T& txTo, std::vector&& spent assert(!m_ready); m_spent_outputs = std::move(spent_outputs); + hashPrevouts = GetPrevoutsHash(txTo); + hashSequence = GetSequencesHash(txTo); + hashOutputs = GetOutputsHash(txTo); m_ready = true; } @@ -1543,6 +1546,57 @@ uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn { assert(nIn < txTo.vin.size()); + if (sigversion == SigVersion::DIP0143) { + int32_t n32bitVersion = txTo.nVersion | (txTo.nType << 16); + uint256 hashPrevouts; + uint256 hashSequence; + uint256 hashOutputs; + const bool cacheready = cache && cache->m_ready; + + if (!(nHashType & SIGHASH_ANYONECANPAY)) { + hashPrevouts = cacheready ? cache->hashPrevouts : GetPrevoutsHash(txTo); + } + + if (!(nHashType & SIGHASH_ANYONECANPAY) && (nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { + hashSequence = cacheready ? cache->hashSequence : GetSequencesHash(txTo); + } + + if ((nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { + hashOutputs = cacheready ? cache->hashOutputs : GetOutputsHash(txTo); + } 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 and type + ss << n32bitVersion; + // 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; + ss << scriptCode; + ss << amount; + ss << txTo.vin[nIn].nSequence; + // Outputs (none/one/all, depending on flags) + ss << hashOutputs; + // Extra payload + if (txTo.nVersion == 3 && txTo.nType != TRANSACTION_NORMAL) { + ss << txTo.vExtraPayload; + } + // Locktime + ss << txTo.nLockTime; + // Sighash type + ss << nHashType; + + return ss.GetHash(); + } + // Check for invalid use of SIGHASH_SINGLE if ((nHashType & 0x1f) == SIGHASH_SINGLE) { if (nIn >= txTo.vout.size()) { From 67457dd634d21e5038eedd960d6cb3dc51a9ff6d Mon Sep 17 00:00:00 2001 From: Alessandro Rezzi Date: Sat, 10 Feb 2024 13:39:49 +0100 Subject: [PATCH 05/16] feat: add SCRIPT_ENABLE_DIP0143 Only if this flag is enabled it's possible to use the new sighash algorithm --- src/script/interpreter.cpp | 22 +++++++++++++++++++--- src/script/interpreter.h | 5 +++++ src/script/script_error.cpp | 2 ++ src/script/script_error.h | 3 +++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 7f76012be8ea..d13ef053b79e 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -348,6 +348,11 @@ static bool EvalChecksig(const valtype& vchSig, const valtype& vchPubKey, CScrip // Subset of script starting at the most recent codeseparator CScript scriptCode(pbegincodehash, pend); + int nHashType = vchSig.empty() ? 0 : vchSig.back(); + // Can't use using SIGHASH_DIP0143 hash type without SCRIPT_ENABLE_DIP0143 flag + if ((nHashType & SIGHASH_DIP0143) && (~flags & SCRIPT_ENABLE_DIP0143)) { + return set_error(serror, SCRIPT_ERR_SIGHASHTYPE_DIP0143); + } // Drop the signature, since there's no way for a signature to sign itself if (sigversion == SigVersion::BASE) { int found = FindAndDelete(scriptCode, CScript() << vchSig); @@ -359,7 +364,7 @@ static bool EvalChecksig(const valtype& vchSig, const valtype& vchPubKey, CScrip //serror is set return false; } - fSuccess = checker.CheckSig(vchSig, vchPubKey, scriptCode, sigversion); + fSuccess = checker.CheckSig(vchSig, vchPubKey, scriptCode, GetSigVersion(flags, nHashType)); if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && vchSig.size()) return set_error(serror, SCRIPT_ERR_SIG_NULLFAIL); @@ -1164,10 +1169,15 @@ bool EvalScript(std::vector >& stack, const CScript& // Subset of script starting at the most recent codeseparator CScript scriptCode(pbegincodehash, pend); - // Drop the signatures, since there's no way for a signature to sign itself for (int k = 0; k < nSigsCount; k++) { valtype& vchSig = stacktop(-isig-k); + int nHashType = vchSig.empty() ? 0 : vchSig.back(); + // Can't use using SIGHASH_DIP0143 hash type without SCRIPT_ENABLE_DIP0143 flag + if ((nHashType & SIGHASH_DIP0143) && (~flags & SCRIPT_ENABLE_DIP0143)) { + return set_error(serror, SCRIPT_ERR_SIGHASHTYPE_DIP0143); + } + // Drop the signatures, since there's no way for a signature to sign itself if (sigversion == SigVersion::BASE) { int found = FindAndDelete(scriptCode, CScript() << vchSig); if (found > 0 && (flags & SCRIPT_VERIFY_CONST_SCRIPTCODE)) @@ -1190,7 +1200,8 @@ bool EvalScript(std::vector >& stack, const CScript& } // Check signature - bool fOk = checker.CheckSig(vchSig, vchPubKey, scriptCode, sigversion); + int nHashType = vchSig.empty() ? 0 : vchSig.back(); + bool fOk = checker.CheckSig(vchSig, vchPubKey, scriptCode, GetSigVersion(flags, nHashType)); if (fOk) { isig++; @@ -1541,6 +1552,11 @@ template PrecomputedTransactionData::PrecomputedTransactionData(const CMutableTr template void PrecomputedTransactionData::Init(const CTransaction& txTo, std::vector&& spent_outputs); template void PrecomputedTransactionData::Init(const CMutableTransaction& txTo, std::vector&& spent_outputs); +SigVersion GetSigVersion(unsigned int flags, int nHashType) +{ + return (flags & SCRIPT_ENABLE_DIP0143) && (nHashType & SIGHASH_DIP0143) ? SigVersion::DIP0143 : SigVersion::BASE; +} + template uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache) { diff --git a/src/script/interpreter.h b/src/script/interpreter.h index af593e751fbc..13f24ab1cb58 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -103,6 +103,9 @@ enum : uint32_t { // SCRIPT_VERIFY_CONST_SCRIPTCODE = (1U << 16), + // Enable the use of SIGHASH_DIP0143 + SCRIPT_ENABLE_DIP0143 = (1U << 17), + // Constants to point to the highest flag in use. Add new flags above this line. // SCRIPT_VERIFY_END_MARKER @@ -131,6 +134,8 @@ enum class SigVersion DIP0143 = 1, }; +SigVersion GetSigVersion(unsigned int flags, int nHashType); + template uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache = nullptr); diff --git a/src/script/script_error.cpp b/src/script/script_error.cpp index 9870b150efe5..a0eb3cd3577b 100644 --- a/src/script/script_error.cpp +++ b/src/script/script_error.cpp @@ -92,6 +92,8 @@ std::string ScriptErrorString(const ScriptError serror) return "Using OP_CODESEPARATOR"; case SCRIPT_ERR_SIG_FINDANDDELETE: return "Signature is found in scriptCode"; + case SCRIPT_ERR_SIGHASHTYPE_DIP0143: + return "Attempted to use sigHashType SIGHASH_DIP0143"; case SCRIPT_ERR_UNKNOWN_ERROR: case SCRIPT_ERR_ERROR_COUNT: default: break; diff --git a/src/script/script_error.h b/src/script/script_error.h index 32afe4cd1b76..4e9d68732b1a 100644 --- a/src/script/script_error.h +++ b/src/script/script_error.h @@ -70,6 +70,9 @@ typedef enum ScriptError_t SCRIPT_ERR_OP_CODESEPARATOR, SCRIPT_ERR_SIG_FINDANDDELETE, + /* DIP0143 */ + SCRIPT_ERR_SIGHASHTYPE_DIP0143, + SCRIPT_ERR_ERROR_COUNT } ScriptError; From abad7f48f468b2c188c2af7b478f25e3d18f5418 Mon Sep 17 00:00:00 2001 From: Alessandro Rezzi Date: Sat, 10 Feb 2024 13:51:39 +0100 Subject: [PATCH 06/16] refactor: remove SigVersion from EvalScript Since Sigversion is now a local property of each input. --- src/bench/verify_script.cpp | 2 +- src/policy/policy.cpp | 2 +- src/script/interpreter.cpp | 38 +++++++++++++---------------- src/script/interpreter.h | 2 +- src/script/sign.cpp | 2 +- src/test/checkdatasig_tests.cpp | 4 +-- src/test/dip0020opcodes_tests.cpp | 4 +-- src/test/fuzz/eval_script.cpp | 6 ++--- src/test/fuzz/signature_checker.cpp | 2 +- src/test/script_tests.cpp | 16 ++++++------ 10 files changed, 36 insertions(+), 42 deletions(-) diff --git a/src/bench/verify_script.cpp b/src/bench/verify_script.cpp index 365b7c0a4651..ddb154777f85 100644 --- a/src/bench/verify_script.cpp +++ b/src/bench/verify_script.cpp @@ -24,7 +24,7 @@ static void VerifyNestedIfScript(benchmark::Bench& bench) { bench.run([&] { auto stack_copy = stack; ScriptError error; - bool ret = EvalScript(stack_copy, script, 0, BaseSignatureChecker(), SigVersion::BASE, &error); + bool ret = EvalScript(stack_copy, script, 0, BaseSignatureChecker(), &error); assert(ret); }); } diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 5776e5043b15..573b7413ce84 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -154,7 +154,7 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) } else if (whichType == TxoutType::SCRIPTHASH) { std::vector > stack; // convert the scriptSig into a stack, so we can inspect the redeemScript - if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SigVersion::BASE)) + if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker())) return false; if (stack.empty()) return false; diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index d13ef053b79e..4b5756daccde 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -214,7 +214,7 @@ bool CheckSignatureEncoding(const std::vector &vchSig, unsigned i return true; } -bool static CheckPubKeyEncoding(const valtype &vchPubKey, unsigned int flags, const SigVersion &sigversion, ScriptError* serror) { +bool static CheckPubKeyEncoding(const valtype &vchPubKey, unsigned int flags, ScriptError* serror) { if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsCompressedOrUncompressedPubKey(vchPubKey)) { return set_error(serror, SCRIPT_ERR_PUBKEYTYPE); } @@ -343,7 +343,7 @@ class ConditionStack { * 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) +static bool EvalChecksig(const valtype& vchSig, const valtype& vchPubKey, CScript::const_iterator pbegincodehash, CScript::const_iterator pend, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror, bool& fSuccess) { // Subset of script starting at the most recent codeseparator CScript scriptCode(pbegincodehash, pend); @@ -354,13 +354,11 @@ static bool EvalChecksig(const valtype& vchSig, const valtype& vchPubKey, CScrip return set_error(serror, SCRIPT_ERR_SIGHASHTYPE_DIP0143); } // Drop the signature, since there's no way for a signature to sign itself - 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); - } + 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)) { + if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) { //serror is set return false; } @@ -373,7 +371,7 @@ static bool EvalChecksig(const valtype& vchSig, const valtype& vchPubKey, CScrip } -bool EvalScript(std::vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* serror) +bool EvalScript(std::vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) { static const CScriptNum bnZero(0); static const CScriptNum bnOne(1); @@ -440,7 +438,7 @@ bool EvalScript(std::vector >& stack, const CScript& return set_error(serror, SCRIPT_ERR_DISABLED_OPCODE); // Disabled opcodes (CVE-2010-5137). // With SCRIPT_VERIFY_CONST_SCRIPTCODE, OP_CODESEPARATOR is rejected even in an unexecuted branch - if (opcode == OP_CODESEPARATOR && sigversion == SigVersion::BASE && (flags & SCRIPT_VERIFY_CONST_SCRIPTCODE)) + if (opcode == OP_CODESEPARATOR && (flags & SCRIPT_VERIFY_CONST_SCRIPTCODE)) return set_error(serror, SCRIPT_ERR_OP_CODESEPARATOR); if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4) { @@ -1078,7 +1076,7 @@ bool EvalScript(std::vector >& stack, const CScript& valtype& vchPubKey = stacktop(-1); bool fSuccess = true; - if (!EvalChecksig(vchSig, vchPubKey, pbegincodehash, pend, flags, checker, sigversion, serror, fSuccess)) return false; + if (!EvalChecksig(vchSig, vchPubKey, pbegincodehash, pend, flags, checker, serror, fSuccess)) return false; popstack(stack); popstack(stack); stack.push_back(fSuccess ? vchTrue : vchFalse); @@ -1103,7 +1101,7 @@ bool EvalScript(std::vector >& stack, const CScript& valtype &vchMessage = stacktop(-2); valtype &vchPubKey = stacktop(-1); - if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, sigversion, serror)) { + if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) { // serror is set return false; } @@ -1178,11 +1176,9 @@ bool EvalScript(std::vector >& stack, const CScript& return set_error(serror, SCRIPT_ERR_SIGHASHTYPE_DIP0143); } // Drop the signatures, since there's no way for a signature to sign itself - 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); - } + int found = FindAndDelete(scriptCode, CScript() << vchSig); + if (found > 0 && (flags & SCRIPT_VERIFY_CONST_SCRIPTCODE)) + return set_error(serror, SCRIPT_ERR_SIG_FINDANDDELETE); } bool fSuccess = true; @@ -1194,7 +1190,7 @@ bool EvalScript(std::vector >& stack, const CScript& // 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. - if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, sigversion, serror)) { + if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) { // serror is set return false; } @@ -1760,12 +1756,12 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigne // scriptSig and scriptPubKey must be evaluated sequentially on the same stack // rather than being simply concatenated (see CVE-2010-5141) std::vector > stack, stackCopy; - if (!EvalScript(stack, scriptSig, flags, checker, SigVersion::BASE, serror)) + if (!EvalScript(stack, scriptSig, flags, checker, serror)) // serror is set return false; if (flags & SCRIPT_VERIFY_P2SH) stackCopy = stack; - if (!EvalScript(stack, scriptPubKey, flags, checker, SigVersion::BASE, serror)) + if (!EvalScript(stack, scriptPubKey, flags, checker, serror)) // serror is set return false; if (stack.empty()) @@ -1792,7 +1788,7 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigne CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end()); popstack(stack); - if (!EvalScript(stack, pubKey2, flags, checker, SigVersion::BASE, serror)) + if (!EvalScript(stack, pubKey2, flags, checker, serror)) // serror is set return false; if (stack.empty()) diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 13f24ab1cb58..a37a4c16162b 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -183,7 +183,7 @@ class GenericTransactionSignatureChecker : public BaseSignatureChecker using TransactionSignatureChecker = GenericTransactionSignatureChecker; using MutableTransactionSignatureChecker = GenericTransactionSignatureChecker; -bool EvalScript(std::vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* error = nullptr); +bool EvalScript(std::vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = nullptr); bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = nullptr); int FindAndDelete(CScript& script, const CScript& b); diff --git a/src/script/sign.cpp b/src/script/sign.cpp index bb120d784c29..019c5830afee 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -227,7 +227,7 @@ struct Stacks Stacks() {} explicit Stacks(const std::vector& scriptSigStack_) : script(scriptSigStack_) {} explicit Stacks(const SignatureData& data) { - EvalScript(script, data.scriptSig, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker(), SigVersion::BASE); + EvalScript(script, data.scriptSig, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker()); } SignatureData Output() const { diff --git a/src/test/checkdatasig_tests.cpp b/src/test/checkdatasig_tests.cpp index 8e2f2ee119c2..b913a70f305a 100644 --- a/src/test/checkdatasig_tests.cpp +++ b/src/test/checkdatasig_tests.cpp @@ -42,7 +42,7 @@ static void CheckError(uint32_t flags, const stacktype& original_stack, BaseSignatureChecker sigchecker; ScriptError err = ScriptError::SCRIPT_ERR_OK; stacktype stack{original_stack}; - bool r = EvalScript(stack, script, flags | SCRIPT_ENABLE_DIP0020_OPCODES, sigchecker, SigVersion::BASE, &err); + bool r = EvalScript(stack, script, flags | SCRIPT_ENABLE_DIP0020_OPCODES, sigchecker, &err); BOOST_CHECK(!r); BOOST_CHECK(err == expected); } @@ -53,7 +53,7 @@ static void CheckPass(uint32_t flags, const stacktype& original_stack, BaseSignatureChecker sigchecker; ScriptError err = ScriptError::SCRIPT_ERR_OK; stacktype stack{original_stack}; - bool r = EvalScript(stack, script, flags | SCRIPT_ENABLE_DIP0020_OPCODES, sigchecker, SigVersion::BASE, &err); + bool r = EvalScript(stack, script, flags | SCRIPT_ENABLE_DIP0020_OPCODES, sigchecker, &err); BOOST_CHECK(r); BOOST_CHECK(err == ScriptError::SCRIPT_ERR_OK); BOOST_CHECK(stack == expected); diff --git a/src/test/dip0020opcodes_tests.cpp b/src/test/dip0020opcodes_tests.cpp index d44ffae71e64..f5f3537c255d 100644 --- a/src/test/dip0020opcodes_tests.cpp +++ b/src/test/dip0020opcodes_tests.cpp @@ -30,7 +30,7 @@ static void CheckTestResultForAllFlags(const stacktype& original_stack, for (uint32_t flags : flagset) { ScriptError err = ScriptError::SCRIPT_ERR_OK; stacktype stack{original_stack}; - bool r = EvalScript(stack, script, flags | SCRIPT_ENABLE_DIP0020_OPCODES, sigchecker, SigVersion::BASE, &err); + bool r = EvalScript(stack, script, flags | SCRIPT_ENABLE_DIP0020_OPCODES, sigchecker, &err); BOOST_CHECK(r); BOOST_CHECK(stack == expected); } @@ -42,7 +42,7 @@ static void CheckError(uint32_t flags, const stacktype& original_stack, BaseSignatureChecker sigchecker; ScriptError err = ScriptError::SCRIPT_ERR_OK; stacktype stack{original_stack}; - bool r = EvalScript(stack, script, flags | SCRIPT_ENABLE_DIP0020_OPCODES, sigchecker, SigVersion::BASE, &err); + bool r = EvalScript(stack, script, flags | SCRIPT_ENABLE_DIP0020_OPCODES, sigchecker, &err); BOOST_CHECK(!r); BOOST_CHECK(err == expected_error); } diff --git a/src/test/fuzz/eval_script.cpp b/src/test/fuzz/eval_script.cpp index bf1710de496a..b432d23ddc72 100644 --- a/src/test/fuzz/eval_script.cpp +++ b/src/test/fuzz/eval_script.cpp @@ -24,8 +24,6 @@ FUZZ_TARGET(eval_script) } }(); const CScript script(script_bytes.begin(), script_bytes.end()); - for (const auto sig_version : {SigVersion::BASE}) { - std::vector> stack; - (void)EvalScript(stack, script, flags, BaseSignatureChecker(), sig_version, nullptr); - } + std::vector> stack; + (void)EvalScript(stack, script, flags, BaseSignatureChecker(), nullptr); } diff --git a/src/test/fuzz/signature_checker.cpp b/src/test/fuzz/signature_checker.cpp index 175024b1f36c..1db26798710e 100644 --- a/src/test/fuzz/signature_checker.cpp +++ b/src/test/fuzz/signature_checker.cpp @@ -50,7 +50,7 @@ FUZZ_TARGET(signature_checker) const auto script_1 = ConsumeScript(fuzzed_data_provider, 65536); const auto script_2 = ConsumeScript(fuzzed_data_provider, 65536); std::vector> stack; - (void)EvalScript(stack, script_1, flags, FuzzedSignatureChecker(fuzzed_data_provider), SigVersion::BASE, nullptr); + (void)EvalScript(stack, script_1, flags, FuzzedSignatureChecker(fuzzed_data_provider), nullptr); if (!IsValidFlagCombination(flags)) { return; } diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index bd062b15ceab..1964b5282310 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -927,21 +927,21 @@ BOOST_AUTO_TEST_CASE(script_PushData) ScriptError err; std::vector > directStack; - BOOST_CHECK(EvalScript(directStack, CScript(direct, direct + sizeof(direct)), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err)); + BOOST_CHECK(EvalScript(directStack, CScript(direct, direct + sizeof(direct)), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); std::vector > pushdata1Stack; - BOOST_CHECK(EvalScript(pushdata1Stack, CScript(pushdata1, pushdata1 + sizeof(pushdata1)), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err)); + BOOST_CHECK(EvalScript(pushdata1Stack, CScript(pushdata1, pushdata1 + sizeof(pushdata1)), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err)); BOOST_CHECK(pushdata1Stack == directStack); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); std::vector > pushdata2Stack; - BOOST_CHECK(EvalScript(pushdata2Stack, CScript(pushdata2, pushdata2 + sizeof(pushdata2)), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err)); + BOOST_CHECK(EvalScript(pushdata2Stack, CScript(pushdata2, pushdata2 + sizeof(pushdata2)), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err)); BOOST_CHECK(pushdata2Stack == directStack); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); std::vector > pushdata4Stack; - BOOST_CHECK(EvalScript(pushdata4Stack, CScript(pushdata4, pushdata4 + sizeof(pushdata4)), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err)); + BOOST_CHECK(EvalScript(pushdata4Stack, CScript(pushdata4, pushdata4 + sizeof(pushdata4)), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err)); BOOST_CHECK(pushdata4Stack == directStack); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); @@ -950,11 +950,11 @@ BOOST_AUTO_TEST_CASE(script_PushData) const std::vector pushdata4_trunc{OP_PUSHDATA4, 1, 0, 0, 0}; std::vector> stack_ignore; - BOOST_CHECK(!EvalScript(stack_ignore, CScript(pushdata1_trunc.begin(), pushdata1_trunc.end()), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err)); + BOOST_CHECK(!EvalScript(stack_ignore, CScript(pushdata1_trunc.begin(), pushdata1_trunc.end()), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err)); BOOST_CHECK_EQUAL(err, SCRIPT_ERR_BAD_OPCODE); - BOOST_CHECK(!EvalScript(stack_ignore, CScript(pushdata2_trunc.begin(), pushdata2_trunc.end()), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err)); + BOOST_CHECK(!EvalScript(stack_ignore, CScript(pushdata2_trunc.begin(), pushdata2_trunc.end()), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err)); BOOST_CHECK_EQUAL(err, SCRIPT_ERR_BAD_OPCODE); - BOOST_CHECK(!EvalScript(stack_ignore, CScript(pushdata4_trunc.begin(), pushdata4_trunc.end()), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err)); + BOOST_CHECK(!EvalScript(stack_ignore, CScript(pushdata4_trunc.begin(), pushdata4_trunc.end()), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err)); BOOST_CHECK_EQUAL(err, SCRIPT_ERR_BAD_OPCODE); } @@ -964,7 +964,7 @@ BOOST_AUTO_TEST_CASE(script_cltv_truncated) std::vector> stack_ignore; ScriptError err; - BOOST_CHECK(!EvalScript(stack_ignore, script_cltv_trunc, SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, BaseSignatureChecker(), SigVersion::BASE, &err)); + BOOST_CHECK(!EvalScript(stack_ignore, script_cltv_trunc, SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, BaseSignatureChecker(), &err)); BOOST_CHECK_EQUAL(err, SCRIPT_ERR_INVALID_STACK_OPERATION); } From 1c313a9c3ac0e4b0cec8131c47af31bb6bf7566c Mon Sep 17 00:00:00 2001 From: Alessandro Rezzi Date: Thu, 22 Feb 2024 12:09:24 +0100 Subject: [PATCH 07/16] feat: add DIP0143 regtest params --- src/chainparams.cpp | 9 +++++++++ src/consensus/params.h | 3 ++- src/deploymentinfo.cpp | 4 ++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 10a67d73cdf0..9023feb44188 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -833,6 +833,15 @@ class CRegTestParams : public CChainParams { consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nFalloffCoeff = 5; // this corresponds to 10 periods consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].useEHF = true; + consensus.vDeployments[Consensus::DEPLOYMENT_DIP0143].bit = 11; + consensus.vDeployments[Consensus::DEPLOYMENT_DIP0143].nStartTime = 0; + consensus.vDeployments[Consensus::DEPLOYMENT_DIP0143].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; + consensus.vDeployments[Consensus::DEPLOYMENT_DIP0143].nWindowSize = 12; + consensus.vDeployments[Consensus::DEPLOYMENT_DIP0143].nThresholdStart = 9; // 80% of 12 + consensus.vDeployments[Consensus::DEPLOYMENT_DIP0143].nThresholdMin = 7; // 60% of 7 + consensus.vDeployments[Consensus::DEPLOYMENT_DIP0143].nFalloffCoeff = 5; // this corresponds to 10 periods + consensus.vDeployments[Consensus::DEPLOYMENT_DIP0143].useEHF = true; + // The best chain should have at least this much work. consensus.nMinimumChainWork = uint256S("0x00"); diff --git a/src/consensus/params.h b/src/consensus/params.h index caf17bac3f67..41fcdd309878 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -36,10 +36,11 @@ enum DeploymentPos : uint16_t DEPLOYMENT_TESTDUMMY, DEPLOYMENT_V20, // Deployment of EHF, LLMQ Randomness Beacon DEPLOYMENT_MN_RR, // Deployment of Masternode Reward Location Reallocation + DEPLOYMENT_DIP0143, // Deployment of a faster Signature Hash algorithm // NOTE: Also add new deployments to VersionBitsDeploymentInfo in deploymentinfo.cpp MAX_VERSION_BITS_DEPLOYMENTS }; -constexpr bool ValidDeployment(DeploymentPos dep) { return DEPLOYMENT_TESTDUMMY <= dep && dep <= DEPLOYMENT_MN_RR; } +constexpr bool ValidDeployment(DeploymentPos dep) { return DEPLOYMENT_TESTDUMMY <= dep && dep <= DEPLOYMENT_DIP0143; } /** * Struct for each individual consensus rule change using BIP9. diff --git a/src/deploymentinfo.cpp b/src/deploymentinfo.cpp index 17da5d3d36fa..a5fe2a483730 100644 --- a/src/deploymentinfo.cpp +++ b/src/deploymentinfo.cpp @@ -19,6 +19,10 @@ const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_B /*.name =*/"mn_rr", /*.gbt_force =*/true, }, + { + /*.name =*/"dip_0143", + /*.gbt_force =*/true, + }, }; std::string DeploymentName(Consensus::BuriedDeployment dep) From dd401ecad3d094c68349f4c847d1e4ada8c62b51 Mon Sep 17 00:00:00 2001 From: Alessandro Rezzi Date: Fri, 23 Feb 2024 10:59:45 +0100 Subject: [PATCH 08/16] feat: Use DIP0143 flag only when the corresponding EHF is active --- src/policy/policy.h | 3 ++- src/validation.cpp | 11 +++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/policy/policy.h b/src/policy/policy.h index 8052cebac397..dd09ca4aa49c 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -61,7 +61,8 @@ static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VE SCRIPT_VERIFY_CHECKSEQUENCEVERIFY | SCRIPT_VERIFY_LOW_S | SCRIPT_ENABLE_DIP0020_OPCODES | - SCRIPT_VERIFY_CONST_SCRIPTCODE; + SCRIPT_VERIFY_CONST_SCRIPTCODE | + SCRIPT_ENABLE_DIP0143; /** For convenience, standard but not mandatory verify flags. */ static constexpr unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS; diff --git a/src/validation.cpp b/src/validation.cpp index b56b4e055c15..b167a2b0669b 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1600,9 +1600,11 @@ bool CheckInputScripts(const CTransaction& tx, TxValidationState &state, const C check.swap(pvChecks->back()); } else if (!check()) { const bool hasNonMandatoryFlags = (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) != 0; + //TODO: to avoid this flag by flag check, group all ENABLE like flags in a group STANDARD_ENABLE_FLAGS? const bool hasDIP0020Opcodes = (flags & SCRIPT_ENABLE_DIP0020_OPCODES) != 0; + const bool hasDIP0143Flag = (flags & SCRIPT_ENABLE_DIP0143) != 0; - if (hasNonMandatoryFlags || !hasDIP0020Opcodes) { + if (hasNonMandatoryFlags || !hasDIP0020Opcodes || !hasDIP0143Flag) { // Check whether the failure was caused by a // non-mandatory script verification check, such as // non-standard DER encodings or non-null dummy @@ -1612,7 +1614,7 @@ bool CheckInputScripts(const CTransaction& tx, TxValidationState &state, const C // non-upgraded nodes by banning CONSENSUS-failing // data providers. CScriptCheck check2(coin.out, tx, i, - (flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS) | SCRIPT_ENABLE_DIP0020_OPCODES, cacheSigStore, &txdata); + (flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS) | SCRIPT_ENABLE_DIP0020_OPCODES | SCRIPT_ENABLE_DIP0143, cacheSigStore, &txdata); if (check2()) return state.Invalid(TxValidationResult::TX_NOT_STANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError()))); } @@ -2036,6 +2038,11 @@ static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consens flags |= SCRIPT_ENABLE_DIP0020_OPCODES; } + // Enforce DIP0143 + if (DeploymentActiveAt(*pindex, consensusparams, Consensus::DEPLOYMENT_DIP0143)){ + flags |= SCRIPT_ENABLE_DIP0143; + } + return flags; } From fe464fbda4ba0928c1c9c8b7537581a4201a17e5 Mon Sep 17 00:00:00 2001 From: Alessandro Rezzi Date: Sat, 24 Feb 2024 09:49:12 +0100 Subject: [PATCH 09/16] test: unit test coverage for the function SignatureHash --- src/Makefile.test.include | 1 + src/test/data/sighash_dip0143.json | 103 +++++++++++++++++++++++++++++ src/test/sighash_tests.cpp | 100 ++++++++++++++++------------ 3 files changed, 162 insertions(+), 42 deletions(-) create mode 100644 src/test/data/sighash_dip0143.json diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 16f3268d7641..edcad0d7775a 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -25,6 +25,7 @@ JSON_TEST_FILES = \ test/data/proposals_invalid.json \ test/data/script_tests.json \ test/data/sighash.json \ + test/data/sighash_dip0143.json \ test/data/trivially_invalid.json \ test/data/trivially_valid.json \ test/data/tx_invalid.json \ diff --git a/src/test/data/sighash_dip0143.json b/src/test/data/sighash_dip0143.json new file mode 100644 index 000000000000..3b2cea41f0e5 --- /dev/null +++ b/src/test/data/sighash_dip0143.json @@ -0,0 +1,103 @@ +[ + ["raw_transaction, script, input_index, amount, hashType, signature_hash (result)"], + ["020000000438d79b04c4e39e561137efbcbc4742235ea1021fdea8ef8153b13b7ef70ba62a0300000000ce0eb8c3b6a04c074a146a85486f3bbad3a451366dc66b67e4575404b19d852ab78beac102000000055200ab51658c46feebe3c1c527a6b3165ab0d06d0dc0aaf69fd2bec466010f7fbca19bf409dfd86ef7020000000400655152ffffffffbd7d18a0f2531735a68ee2402edd31a400f228b37fe889e3a7e02b87dc11c635010000000965656aac63abacab53ffffffff0432bcdf000000000004005300ab66838003000000000252abc9ee9b03000000000865ab520051515265f5404200000000000652005252636500000000", "6a53ac525200abab", 0, 9630820, 2001550825, "6e5dc37bd6c38a04d4b65dd22cbf150a7c007619ad2141c11001d58baf09f0f3"], + ["0100000002a430f2b20776d916a135bf72ff82f69af10389db5007189348b9126f4b8ccf85030000000852ac5253536a655158e0a0c4769b510f7a47f1a76b1c570c732ce1d6a40497aa2590c51932537229e65af46f0100000006006a53656552a0edad2d02a3fe21000000000006536500ac63abeb52360300000000036a52acd7e63fdd", "52abac", 1, 9695670, -1398221719, "3bf43353dcf19e4e8bb6c3e41757a4881771834e7d646f1a06219e3f2155136b"], + ["010000000214d8d570cc4408e455ef9f96cd7a9560a4adf31a648d46c4c552ccb766bdc83c0300000009630051ab5152ac52008c6f032a3d97c0ced056744945b31a51da9b0643335e85b3c930e743ebcd9a0c538236ae0300000009656a5100006a6aab6affffffff03cfa7d80400000000056a52ac51ace85a9500000000000463ac6363680122040000000009ab51ac0065acab635200000000", "ab51", 1, 3563747, -896631843, "bc08166208a6b8b07d48d234fac5387bec3c8f7a3c31425931820afd80ebd582"], + ["0200000003ec101b4137f0a13239d01bc10fb2284bfc47013016c2dc028d135bc0234c1558000000000500ac6352519ab9f7e417b20f6dd5e5cf4939bbe7e36c5fda549ef904bbde8836d1d72faf04ea4d2463010000000465655263ffffffffd1b427c2313f129168c0f5fa1061a5226701cade976b521a0d0a8afe8bbe462f03000000016affffffff04b7ba31010000000006ab516a63ab51beafbe0200000000096a6a6553650052ab6a8c38450400000000096553ab6a5153ab515201245c01000000000363650000000000", "6aac5353ac6563", 0, 750954, 704590428, "c17bc18f8f0f7fb89ffd9da8bdf938fe6a0512e5d20feaf4fff6e09c47f8ac8c"], + ["020000000250eaa7c7273d39f44e1891c6aa455f9fc47283bb2eef62de5893a91c255a0cea030000000163ffffffff4ff42b472a1d53a6dd4a1b306c8ca3ff2983ef1f4f765ac7037099337185741f0300000007516a636a5352acffffffff026d63d9010000000009ab00ac6a6551516551315104030000000005abac51ab5210a2fcc0", "5153536a", 0, 9930124, -1653966248, "53674635d28dea9549fe08b193cc38ef18aad1eda48cf91070718ff4e1b5960d"], + ["010000000182d0dcc9f7d7304363ede14fc6932f018d8b8a7505f0ec9dba26e14a20def1d80000000000ffffffff0333e56703000000000800656a63abab00521267b0030000000005006300ac5180423c040000000007516a636a6565aba85d631a", "ac0000abac", 0, 7017741, -1121799723, "1fee5e96a2558d2fa53abac7e6688c8152c07d53a63330a57e3c4152cfdf1619"], + ["02000000036580773e8dca842571b77a648d807ec777a3f6605d9ca73f14f219bc51f109260300000009ababab656300535253ffffffff0653a58b06e8d9ca73915af630a456cc7f833bb952e87335eadd0b711649b9b900000000076aac5153516553ffffffffdeaa5e280ab2a5d1b0e5d54ff2493138c232447ed9b64c842d0bd97c86a8821f030000000153ffffffff02fcc3b10400000000036551ac5d7e5e010000000004ac51525200000000", "", 2, 4835011, -300807189, "7d43032aea0d695afb55e5641b2fd1f7fdb459d1c38970a5728b0f469e90e4b4"], + ["0100000004a58355171df76ed85b7b668326245f6bc43ef990c34c35acda54d795b82a120c01000000065151536a0052ffffffffc896043084abc9e672ad3aed31c5a51469ed1bee23b68941b5d989c05be808b1000000000251abb4656fba6e8c70d4542dccb86ff511d60f5e4e010ff3efdfabfcf28634a723674908ac260300000009635352635252ab525306eb6603e54918d71fb17baa236ab65ba92f98de16883ad06d54e8e2e2c8f6bd550edd8a0300000002636a4f82caea034248860500000000075353acab536363eb41590000000000035363632be1c1020000000004acab6a6a00000000", "ac536353536551", 3, 5850970, -45033098, "c005229059c2f70a5651b1ba2226e81e210412520b8821d0f19b75f5dc74fc53"], + ["0200000003a5163d55e10cf4f4080c6db6f3631d3c0f58a2ca96dd0f16572521a17573e1a30200000009abab52656a650000abfffffffffe043b2d523354e72e980f0eef577a693d082c7af86b7696a97c5cb09d2b05e803000000066aabab006551b79033dcd4975db32706eb828521b6cd8bdf02abc59d2db23401363dbaa77fe1e62855d3000000000152ffffffff04de1737010000000000ed815f01000000000353006a3881fd01000000000863ac63516a51656ad95bd201000000000965ac5153ab516aabac00000000", "6551006353516353", 0, 6242559, -732237066, "5202c66a05b0020974b91e1b9ea8fdf8d18532e5c8e6fd1efd0d7efc8c3adf41"], + ["01000000013533227fdfd15a2ccb67a63b34c7595b0fcdf3604754b2580d345d1010a7581c030000000165ffffffff04054d1a05000000000853655100655253634f2ccb0400000000066a6a5152526503124d04000000000853ab006a536551acd7ae37000000000003abac6340d08874", "5200", 0, 5218198, -1261142171, "6864dbae27cf35b12120682e007a6e0f565c35f89fdab0e040439952858d873a"], + ["010000000131640b6a4743891641ad5ebbb572ece8c7f7ea4aa8f65f7f9bf21bbd45e1b10203000000085252abac63acab65ffffffff02355db40400000000060000abac5251b24d2a05000000000852636a5151abab6a00000000", "ab63ab", 0, 6414223, 684161005, "42e0b69541d224bb872f1c373faf754cb035eb33d5817beabd296e97088f9f5d"], + ["020000000407f9903e6690098ff8c3bc1b0fda9be16d2e77595d2c5eec0eaad6d4ea7521b60100000004ab6aac53de27d34fb1128809a00139b3a1b2470bbcb5c7934236178f8eeefcbd079a30b4fe13ec070000000005ac5252ac65bd56086ad00a026d1075fc07c8a471fb2831cbeca6dd70910536473781d78525be5bb330010000000663ab51abab53d5dca7c9028536b0f60811d417d13a694afe38c5a9aa6fc35c192085788f77d5db7dbc8a020000000152ffffffff023120a400000000000163bfc5c5000000000000157429f3", "53535300acac655352", 1, 5844121, 1987063261, "4de0a1b6b2b41c7fc817e1125b5b2b487435c1a84338eab5c80a6888d45bce6d"], + ["0100000003a933b96050fa1eefc81759d039fff6236c2fc5471988b5a22c528870ccb6c54802000000086565ac53525252ac9d01cc1176edbaf5608423edd1b829a5551bc2e82d9b46d0c827f5ae2a71e86ce2048b0900000000004bcf58ba65505d9ff47cbfeab0458e7a69a5959b245c7e731b928818b85361619d19cc7202000000035151005b72aa6703effa3700000000000853535251520052633966c80400000000085365515251ab516aa9656e030000000009ab656aab63ac51525196059e7f", "ab6565ac63516a", 1, 9350854, -1727873172, "9d01a3a948e81f1f9026fc0775f64fbca63a28c6e9ba76124d2b0ed65747c74b"], + ["0100000003037d40a173e3498c16f9e9116e350ae48677e22e962f42dff7ab87f607bfaac902000000086553005163ab52512718c1d10329bb098f3ebd686a04b7cec11d04cf2ef27edc0a42b1fe3305e47c19ba4fff00000000095151526a526500ab51b92516d5b05674224c02b349768051f582679aa1b2a0987cd9667f0a39e4ac60b491f3b00000000004acacabac7ff7303b044f3b7a01000000000152af201503000000000853656a515353525364ab6305000000000565ac6a655354df6504000000000265ab84368501", "ac63", 1, 8137023, 1529778296, "17f383e0e1727ad1cca13c6f87ebd8c0ed373f536fdb423842d1a55c123d1a3d"], + ["0100000004459441c647d15611df88d85f146920b5c9bdbc11a1ad929d40b4b3539c8eacde0000000004ac006351704afaa42da5b64d18aecbb24b2fc4793cd489a4e20549b03102e0dd7f972d64660de68f0100000009ac5300655100526a63920e2a3ead30cc32a4554965902d0c0329ace8960521f78234807a006c902b728abc6ae300000000096353006551ac535363ffffffff04fa2c7f7e67d759b4c08746461a4998727a80e13584520ab7d6d53f87d83a13000000000863ac5165ababac53ffffffff0385955104000000000153ceee5a000000000001ac293005040000000006526aacab005200000000", "0051ab53630052abac", 1, 1501699, -1053986844, "1a99040d0baf2becae0219f0e52fe0982273b3b12eb86f4516a89d9cb32f6548"], + ["0200000001d7162712dd172d78b4953b3d1e2ddae586e14a6d1f10d4c7789b4f34dacfc4df00000000086aab00006a536a63ffffffff0122d7e600000000000353636500000000", "63ac655152abac", 0, 8638111, 1449699923, "a2ab8aaa703b3fdab0f037c3362cd65fcad61e726155a97bf76e08b04e603f5c"], + ["0100000003f2c440ad965bf29c923b4a1e5c0e2ba99f20b0d0be0c72881f79e87d1b9c262600000000046a6a6aacf563d800ac6b0cdb68b51e71ffa78c4fd8ca0e29575e41bde5f602a05ca38a6c0ac4f29000000000076551ab51ac6500605f4e5484e742bb6aa6dac6aa0eed7ca61727be5f83c9ea48a501211d5e1d99226c0616010000000039bea9a802c7e122040000000006abac5165516ac2df1e010000000009655163536a636a005111d808ed", "6a63ababab51", 0, 5697671, 561986508, "27338f436bdfd72793d1d31e545d835abacae4d9e23f7c08fc09c1e4c1e8ae6b"], + ["0100000004d1041e3bd9486f4c83cf54a486a9c4913d9abb0d996fdc3341f923548d408dbe0000000003ac63abfffffffff24d9eb8185ab2678cda0a3f262e5447d30b7df7e92a14e8787662ae9dbca373030000000300ac5299d0862c9d313010e2f4a7324d7be7fbf2522894bb3db2c2cbaa25ab8f2024205b02cf1800000000076551635165656affffffff48b06bd41044f367f83edd0d1c85bcf73d9fc82d5414fc9659f7c68c4bc0cc56030000000751ac52520052654687e1ef04dabae800000000000652516553ac5212478502000000000153f61405050000000002ac6334e36c020000000004636a650000000000", "6300", 3, 3981823, 928634219, "5b27601afc9e8cf7cbac7c46d74e92e031dce454c0c52151454117f89a7535cd"], + ["01000000017f3bfc327b7a981652cbb6386af0865c8bb134536c406c0b8fe4b9a95a3d0687020000000451535252f23ed1810338dd2a0400000000006bd9760300000000096a6aab5100ac0063656e5cab0500000000056500ab515300000000", "63526a005352ab63ab", 0, 8349240, 1685348724, "e36730aabbd63ae7fdad42e831580bd67c3fc9b2d5c5f4a24a337bb4163546b7"], + ["0200000002d90f7b4262484f0b46f091a9b63b1e99a4897514e4727aa5cd6aecc6cfed585c010000000251513612abbbad466135b01733198cc0209d8e012f3c8b54534d279a2e61dfe2049f2d27d2fa030000000152cc22996904e0c28a00000000000040593805000000000200accedcde02000000000200ab31a4d80100000000065152ab51525200000000", "53635251", 1, 4610163, -54237752, "cde15fce3fe83a48bcd0f1d741a6341026fc51fb3e0ec05cae482df11fe7a938"], + ["0100000002c513a8853a2af01e8ebe82dcb82fddba71fab43f2ea03e0934089cafd56bc1fd0100000008656a6a6553ac65abffffffff9eb8da88687103efded1d1492add7989dcb0de7654fe6e6069ed07867c5cb2f0030000000465515163b7fb28410176266300000000000083de5044", "6351630052516353ac", 0, 7951538, -302702774, "7aa5527bbbe57272fa53121ed2c9aa7c6301a10c246bbd17a248ce46fbb47019"], + ["02000000031c9ba931047e1fe36f50f78ac3fee44738817782b50baf1d3f6b0fc913d5bf8a02000000075353acab006a53ffffffff19c37d4804ef8bfdf231ea02ad0e8d0a683ba30899b3adaceb230dd2045233de01000000076365ab63ab6352ffffffff7fec0f75f4941f7fd276b5bf1b024158ad9439ba7b6506cf9b4cac091416000b0000000000ffffffff01300aa90300000000016500000000", "53536552ac53", 0, 1654403, -840651947, "dc87594a7337fe63e406c0f46666225b069ad5d08ae33a49a6234eb621870113"], + ["0200000004274fe47585edfc71532e21eea1af6d8e480c41ae098ab3f6a8981f3acb52462f03000000008b5a5636c2fed244f4d85019aaae05a462e31c87739a00ca2b74926022d9367bee728fc902000000055351ac53acffffffff332954d652607c1fbadd2fce0895297c8a858a86f031b95a5184a9ecf8bfaa4f03000000016affffffff9bc4f9451e64f9149d7ee76319f75d186633c876deb50dcf12edd1d7ec13264802000000086563520052656a5387f4b012021ecd1b0300000000046a52526a6c23160300000000075263ac6a5151abe58c278a", "", 2, 1922226, 417896032, "98ddf032d5313f45ce2eaefaaaad99cfce0e4c7c7d95df0bfd269245578203c3"], + ["01000000018a9b0d10dcca5dbe8212ca42f24ce30cc39a308359d24a6121c503ea0fd505dd000000000163ffffffff01c3170901000000000000000000", "", 0, 7341917, 1423258318, "eed325ada4d489c714acfea05fc7c048747f7592519b8e8566fe5f0e76aa5c90"], + ["02000000010af6835a7600512143ae627c78440fa8ca38215c377f7b5fda7b6c848845ee9c020000000700ab530000ab51ffffffff033d1dba0100000000035165007ca42b020000000006ab6a6aab536afab8ee0200000000015300000000", "0052ac53ac63", 0, 7407300, -1200907298, "7b21b30907e7785b223598c8b6c7295d13133d89d0bdd125f48925795ac2c2eb"], + ["0100000002abf691c5c355f9fba029bbb8cce6ced2be92f388b07025400c91eb24b094e84d030000000763530065520053312facfda84de0a065343ec5598e94a15d0ed4fa5640309bb08a07f08f5a3085149d85fb01000000046a516551ffffffff0127bfec030000000000c755dca9", "ab51005365516a", 0, 8464522, 300360413, "85e8845b540d8de418afd498812c1818879ee67241c12cd13c382c027f302206"], + ["01000000047a9ab220f3b068c33c6a0d9169fe9022cec3d5adea30fe6fd7d9aec52af5465802000000096353ac005200526aabffffffffb614ffbed8799833ddcf171bb6571ab3feaf6e1ac80985d6c27dff2b5bd9b163010000000853ab5153acacab63ffffffff25689fd3b980c0ec4e842e8fe9652c1e42c0aad37d712b20e7aa56290194de080300000002516affffffffed16cfc6457e75191130089d4080240f9edefb7c17b81acb6220c9fd7c14e91502000000015170d814bb03be7e0704000000000163511f1005000000000763ab65acacab53e8eef60000000000065251ab00ab5200000000", "6551acab6a00", 1, 5046520, -23645870, "7863bac8e83be8f8aa76ff6348cac79637d8fde5df193033a1340889e7492ebc"], + ["0200000001305d9b1afae327a618fecac1f4c9f946bac2fddfe8f938a02d5f98428de4d30201000000066aab00655265ffffffff04e6c5ab010000000007ab5351006565ac1de2c80200000000016a529aaa050000000001632ebee9040000000004516a6a6300000000", "635353ab", 0, 8343749, 1814344569, "44bcd331bf94f19c43b41b573120efc84a0903de2f7177d51f136d580c3a00af"], + ["0100000001c1b21fc293777f4ef53ddce764c65016c8a263a2989c3e304c09e01bc87f991100000000095352636a53ac63ab6ae920b6570176240c000000000008ac516a536352ac00470bfa53", "6a6aab516365635200", 0, 2553513, 2121952100, "457f5d2238c7ea4f8f7f223f3c879d45b32aa9d2b4e7f3ddc2db417b57d64c94"], + ["01000000034da5d5abbe5ea4fc1386fc808cfc46da93407e0d88c9229ae1242055335f87dd0300000009006a520053535263ab4d629dbb27f42b42cebffe3d7d81df9280f814823fb8a2bbe2c00b302b6bf17bb99c43980300000002536ab9ecbc117c3b2929d7c15b21f8389d3670fdaf8d0ee69fbd59c5b3f06d227825098a46d801000000016389b55c2701906eb7040000000002530000000000", "", 1, 8084424, 642144626, "e462125428808e563a5ab98f3d6edfa72fb2cf2223d3b1f09919ec3bca61387e"], + ["010000000151b356fc48a480540cb4df31ee480555293b12f016e3a48992fb46a59e6efd2400000000026a51ffffffff0401d8330000000000086a6aabab6a525365ed576b030000000002ab005a36ed02000000000751ac6a0052ab518eb3950500000000085351ab516500516a00000000", "515152516351", 0, 4669914, -1652035607, "23ce19e13d72660159cc9586d3d0413c59f046fc5275097564b8793ec41499cc"], + ["020000000257cd8ba94469e79e105505e8273a26d712c186c102347bc434e4731eb68538f600000000025263ffffffff66c63e8e593be2d32d539b744c1c923e83649618ed8128e7093189d874367895000000000852ac65526a525200ad37572801fee80f02000000000300535300000000", "ac0063005151006aab", 0, 6367121, -1614163246, "0adf5eb16bbd12cfe4a450315fcb677c6944f1aaf24f698f3769fa626fc0d22d"], + ["0200000001f8d21b1e3a7e84048d93a7293206daeef14388a2c76ce8e94a909903c22b390202000000020000bd01215b03fe458b04000000000751ababab5351abc59bac0200000000016adcd6e7040000000001ab00000000", "6a5153526a005152", 0, 3569538, 1708962757, "9a36259ac65f43a0a7d12650b5b6120224c8277d209208b51f5b7c09db3ea22c"], + ["020000000379b5306c8a759b1797e3f73730a96390307af3d2028f7f146ea35bb19842e75203000000046a636365ffffffff98c0fd6af18b6cba92499c3c8df62a84a42caf54fd18f9a01a515f005673e7430000000002acacffffffff0f25c472265ec295635bce5281ec342ae56985c78d454ff7ad72f35e0407f88900000000055251636a53ffffffff01a65de305000000000751656aab656a63e424912a", "656363ac", 1, 6810714, 143200884, "0fdf1eaca8b7e017a3dc5e19d1dca4c804963bf33f71fba9db954d709f6c0df2"], + ["0200000001966177c59f5337e6cb1a68c3e4fff903c8477cb77736d4d95ad21de686615e3d020000000252abffffffff035e193c0500000000066a0063ab00526ea0990400000000066552005163534eabc004000000000652000063abac0c7549dc", "6aab51ab5252acabab", 0, 7185056, -1177641771, "7a1801a00a3866d5edb5e43e6e1469204b4b41577f44059a79f1795d2107c809"], + ["0200000003f48c3c88999d40c24144f1fdf2ed963129c119573da8b03812f4b3b8e7172595010000000100a79b84c8c015a7b5d26e462daaafe59b5ae7e322fe7cba9190b5ab3f6328b1214d1582eb020000000551ac6a5263cee4e25cf7b29b8e36e19767108c7f193f31f1e47d4dd2a1f3840443682484b6a83812ec010000000265ac0f1b8639018bd328030000000003ab6a5100000000", "6563abab5352", 1, 258101, 1165570301, "bacbf0d9ba17d2bdcb348f433e363203794cb202bb9f63332f9641b6f2fe28a6"], + ["01000000010c510b19d5a5903d898de087524e3d84bc9dd982222574255145d6f012a66d870100000000ffffffff03ba229902000000000153b3903d0400000000016ac13681010000000007abac655265abab8361f6dd", "52", 0, 5885769, 1717115982, "9794f64e7f9755a92b975ae165793aa427f66910c085b16aea2c1a2e44bb8482"], + ["0100000002a50f05df6fc8ea9d9ed46f2b607a5416473eb1a73da1a3d110ba20f14ec2adc40300000003005151aa090d7ff919fd7382ab306ca56071e694fb3d8b63634e299f42f065beff4580ca4ef92c0300000005ab51ac5352071f9a5302512a96040000000009656aac63ac5153005336f28604000000000000000000", "51ac52535153ab", 0, 6479595, 1558307934, "1e7ea2aab2eab52db57fc6fabe81d9e079b2e02fe309cfca5ecfee8b6a28fdfc"], + ["01000000031771eb93141031d60ea00ef16aded0f96e3309485e2bd17bcdd5d8f7d5782959010000000153ffffffff2f107f87134300ba75df9dd42b37b40b1625e3b9b5edf988f13ee6afcc3eddf3010000000865006aab516a526369991a3866378af1f5871ce54662ab53b172a9149f0b4d6cc846b9efaa203ca683ecddb8030000000965655351655353ab6a64cf75e30231e08b0100000000095152525353530053ab0afa50030000000001ac00000000", "ab6a510053516a", 2, 6528496, 1027141186, "27fe7f4cbcae4908efe385e20470e489905058176a0ef1bd45b3add93ee78c83"], + ["01000000029655931e7de8bcd90d4c40951265ea5cb5fcf0eafa36bb0a5d8fd8b49e9af2960000000003ab0052ffffffff56ca2576bc644077963d02b9525706044834c1ec0726cf22101de234a21797320000000000ffffffff01fe2fac03000000000152c4c862c0", "635363ac0053526a6a", 1, 5499871, -1970239909, "20f2fbcf68c6cce9d02ae0a5742e324ebc6ef1da8cf71f15f13ffd729b4ad6f2"], + ["0100000004bebd5a9dc10be91e88ef47a2b549f38ff88dfe192d7cc7e28ab2d2a4e9201f3701000000020000ffffffffccda2d50580db119fa75f08f2678d691b564df6d33eb9da0c627a3044b9cdf57010000000763ac0065005265ffffffff783c29a76ab9abdec5a0b579cb18a7aae3cd95c720c701c0d36e54751a6882010000000001acffffffff4b6d86683796bd114512e374ea1a32b1649ea97bc59e4025f04fc22fa92712e302000000075100abac536351ffffffff018d7f9a02000000000000000000", "520063636a6a", 2, 5542646, -1400286253, "dcc9bc5a6a07ec198081dd77dc989efbb8fcc836e62b97784b38defcc0eda631"], + ["0200000003641a06812447589c2eb4bd17097f0c3020c9184566657e4890987d6fc0158afd0000000002abac02a0e9e59e325ad3046581e5df19fb4903f2ee8f030085a844374dab8d50c526d7920b850200000003ac0052ffffffff22a066e2b63e287c3c239b52c4b999db478e7e309b0b42596e3d1f0b3edf22fe000000000753650053535251ffffffff0495d0a30000000000003676b503000000000500536a6aab84ba2b050000000004525200ab4463db05000000000351520000000000", "6a52006a5300", 0, 7683620, -1434439333, "f741015261040f54209c89ecf372229248ece7dbe1e93d204be7e2926a83b38e"], + ["0200000002417a39258274e22869cd716c094ad4518870352b99c2ff7d35dba838f5bff043020000000551ac53ab52e08feeaf8c4c7770d1333bb437fb700d3ef93e90672647234b2967d832566e295343d39f020000000651ab00006a6a1f5e975a013fd02a0300000000076a6552516a6a6a00000000", "ab5363656a", 0, 6434697, 23410921, "e4cd05a61098101bd2739fd89f8659303f289b028fca431858fc4792c22190b5"], + ["02000000024528943b0f582a2f57a9810980a4f571c66ba16a48fb5b071623ed029c07a879000000000665ab63656353ffffffff534d7a1c30aeefd86efebc83a01496af22473947a481ad7a37e2882b42249e0800000000045251ac534b461214045c59af000000000006abacacac00654f6dc40500000000010086b8ea0000000000046a525165db0c8100000000000163d08e5f40", "5152ab51", 0, 4874448, 1856438233, "614d75fbbe9393e7944f48c2eb6be3acefa0620e5d56ba1502948b002ac8be82"], + ["0100000001382989c89fc554e37819a806a576cf89c170532a72caba1697ba8cdc28bcc0ec0000000008655363655251ab529a04cdcc031e7f22050000000004ac530000338f2c000000000009ab0065ac63ab515365212aef030000000006636a0063536af8bbea7e", "516353536a", 0, 1346790, 1518049528, "b9d40b8f3953300ff8f0f3388f2f8ff6137e6b8a4ff7854ee1c4303999962663"], + ["0100000004684af38eabaa32eaf97691e2c7f750cd3e76be357c43bccda46c84e48900ec1d0300000000ffffffff89dcb9c1301decd126b15d864dc41c6df2c684d6c4208625a2073c0daf4ef4b3030000000863526a65ab630053c5f97e6b6ece35e9e7302d66c7b4f69bf8d6891f0c5b7084b14829b233abf111b2bdcb450300000003656500ffffffff406e642c766db281d753be75f3b9a02cc34af46893ee85d3ce903eda9c90b34c0300000000f57aef4503d087410300000000005613360300000000076a00005163ac65c3a1ca0200000000076aab6aac53516a00000000", "ab6563acab00ab656a", 3, 2843198, -294462345, "1dfef0eba92da616a23adebcf80f50e7aa8d3c06aef547203fb910ed1180fbd5"], + ["01000000011f89d4ae6161715c1815d6ca95051bfc8e326852a7029cdaba337478d03c128d0000000001ab4cfe6a610351d4960000000000096a6a535251ab5253651fe7120000000000075151ac5151526abc76ad050000000006006a6a6a51634729e903", "", 0, 1343072, 1967341650, "ee39f9f45a638a5fa9d0cee769b190774a15714adccd13a021c471ecaea07552"], + ["0200000002973277e6eb61d5699d2baabb69b18c4a59aed9a69d71ae5f55426c5ea02a12f70200000007acabab53005263ffffffff1188eafee7e0975135539ea280f99eff40921f162e073a312b057d882d292421000000000765515163acac00ffffffff01e99adf010000000007526a51006a53ab00000000", "5151655100ac52", 0, 5467668, -1520061974, "0b0eb05fcc73d21578a037d9ea276b211c68a15d5f8b8ed132564fe76151b704"], + ["020000000457b0df0fd66234acaf1cafbdbf01ec43940101d40584eec8e2d60d4d09cb90d80000000009516aac65ab65515251fffffffff7a6cac99f15385dacc17631dd0df5fe6701fcaf47be86c565b53558a4b3ff6b03000000085363ab00ac525365ffffffff771cedeefa88e5dee4de4fd98f42122ddd791a584fcee7d1693969cce3cc358200000000010059203d31fb326ef9ff0c836173dd1b984f5b0828407dc16caaf99fd649e325503fc427f50200000008526352ac6a6552abd9fc2b1101b3e84b040000000004ac53515225764905", "656563636a", 2, 5962946, 1274049514, "0571d9794e0760218b8f8e7ec706f23ea583fda1634897ea0734db4606fb3f45"], + ["02000000041e24a515673692378e2a0c34c19959015184472ca5816b7b083a9b8c3fda2d6c0300000009ac6a65535163acab6affffffffc9dad37bc94b3a06fdc261d719da16c61e9cf981a44bd570961182205ccd900203000000007b6f73a001b86e76847cc0a6a0cdfb72e854d0e5f6b66caec161e82102a95bcbba902c9b03000000010074b56b1fc7d499c6a68954ce1b75985c6985461add2d914f7435810274bdcfac3d02bd030200000000189826c804317644040000000003536363d27e2b0400000000046a65006526b353020000000008656a5363006565000270a7000000000008ac636365ac51655300000000", "00515300", 3, 4527977, -1535316883, "0f470c7fdada4fe823fa29ad136bfeaf8d1fd142150bdeb3e2aac634b06c6b25"], + ["020000000363011b248a9a0eec55cc9b0382f97d0e5d2af9f9232239df79066bd7acbe293b0100000000ffffffffcdbfa9e2bb1527d33728a18e21c31f213f2d53a79f07363faace4efee59a32360000000005525365636affffffff3a4b6f3c409a0aa39a88366af5859bc004ee1537873d27802dcf43559f34c5e001000000025353ffffffff01d2033e000000000004530051abe38879e3", "53656363ac5265", 1, 5202488, -489114263, "90fb750d10e9220a9d6d3f693ee7bd244cea74dcffbc2488f8367ec61725cb54"], + ["01000000019e5e58d4cb97935b359e75c2341054496e62f716ab6693c68201ca32ada0a7520000000003005265ffffffff01fbe045000000000007ac65635165530000000000", "000052ab6a", 0, 1345676, 385684844, "0a18d52ac824a78963c4bf0e4ccc13e1bf316668b4ac699762c8218adef668d3"], + ["010000000473610186b6a3e6faa61bf9bf928ce51656a23780082f215b7a0602b95b650dce020000000865515163526a00ab555d1a970bee5ad24fef75e7831c4cfa04ab286ddaa29375ef42aaa246bd70a8c015db5e00000000056551ab5365ffffffff5b75d4e39ecde2e738530624fd61256d5f4920b7f150a83a77302b824762bf6000000000003d0967d56270e332437428af9817b690bd0a72dc62937bad3b9cf87fcfafd10d8e45e01d0000000004ab63656affffffff0432eb3c02000000000300ac6a1b64d70100000000095165536a00ac63ac6531484b0300000000086a526a5352526365531947040000000007650000abab005163d4e0b9", "", 0, 9948036, -213686829, "89a94513a2fd7627aa37faa53d78e21800bf9fe4ae183e208ae5e789abc59be9"], + ["020000000301e4da214bf1c051356ae7b8955d77fe0770d9f3bb51a4f4c6c7e22a27984687020000000700ab6351656a6a6401090feb183e51d9501d9219ef9e3697e2bbdd426357b8c8961fbe667b99053910473802000000025152ffffffff8f19a30923e9d9a7ec8aa9e4a5e2fe75ad4106ff7f5d1cd2e1581bbb6eb6bdba030000000852535253516a52ac2f5f021a02b8dd2d00000000000800516563abababac13288203000000000852536a00005152ac00000000", "51536aab", 2, 989836, 607588801, "63c7ef900687af0cab85a89ae3057c0525eb1f8ddbe492bc71bf0196b8487238"], + ["0200000002b7bb4072c702f4e7a5b0c3e9a82d4f24bd16ac6a4a21d9673ac84323a0313fd50300000001acffffffff1ebe51336e59f062451ca7cb2d33adeec017ae291d4ed155c2dc42a46b2707830000000008ab51656a63000051081a69be0266bd100400000000085165656351636a53e69635000000000008ab51656a526aac5250b21eb4", "6351ab0063ac5352", 0, 3183217, -1433138999, "dcd8a36dc8ee99cfa1ffd722c5b525329f16357c043c850e516b0d197a0729db"], + ["0100000004425538e425afca58c091a81428453472b39a2f6b45c7da34d17caf078b67f8ee020000000165654f3cbf10dd26c7c616d39a6d3d21c075c2573cfde8be621f3fb1f3fb8eb1f3c1a04ac20100000009abab53636551526a52aace9c763fc7948af61f1baebdb3133586cd8209d982901c66220720ae44fdd0d16ba1f30200000009ab650051515100acabffffffffc0957778aaf1abfa433998454400a262a762ffacf6e748cdee6fe98c1acc5e5902000000045265acabffffffff046efe40020000000008635253abab535353343e360300000000046351516590e588030000000006535200ac53ac47a9d60100000000066351515253655717b1bd", "ac656a", 2, 5225358, -1626150178, "02f2a56cd16e791cc2e59e729181ac704ebbce0879f5c4776a099de649466fc0"], + ["0100000002f9c9ddf4934f4c2509f074fa3edd7e8d332d1b2f3bb4c36cefa907b3780de7b3010000000565635251636e862e9bef43f34c5d7c5fb204a3b9a889dc14ad0425b6f8c5c0bc66da465adcff61ced901000000001112bec601df6c53020000000008526a655351abab6300000000", "", 0, 7236683, 1728423904, "0054cccb0c388b772b800dae7b59c146e3853ecb9a886a1bfebf5d2fc9ae5d0b"], + ["0200000001ed3d9cbc299b9461e46ca26bace15bda9d21f369a0d6d2926da1f4b867b129b80200000009ab6365ac5365ab5200ffffffff03304ad90100000000066565ab6363528111bd0100000000045163ab63d4c36403000000000351ac5100000000", "53ac5252526552", 0, 389044, -1608501535, "f6765df1f25cbcb7f86245ff8666d3372b0adfc0cc31321029978478da247d4e"], + ["010000000488616b12cf2a63fed646cb144f08624d4f414135246462ae75a83199c26af5c50100000006005353005365ffffffffc5de8465ca6e6edec65c0b541f133508ac7d06f92767be39d1feedc2210f64a4000000000765006a6a5352acfe742a31f8aef1d2c09e1b691cea019e9463d1c017222bab7ee2ad843008037e48423c6701000000096563ab5163ac51ab53cba5e7e9d6aca33a460916d610503a2d2720030f9082dd0dbeb1518a4fc6a5dd56d4d71903000000036a6a51ffffffff0200b5180200000000086a6a63526aac6a52f099e10300000000075351ac006351ac3626aa00", "63", 0, 6841948, 161352951, "e884ddf72b1f7c35893f69346f9d7fec585cc20876aeda033f490d44e27ad8fe"], + ["02000000027d838b05b4fe245a25775c2a9243786a062abd57d88f5e0fc1e882c81dc040130200000008635100ac6a6352acbdbb4c5556a036140495f6292bf842b9e1df03316506f686f706bed7d2d49882e8b366e00300000004535251ac417aeb12015b8738030000000006636a6a5363ac8f14762c", "636a00", 0, 2811405, -175424901, "ea324932aaaa19a56720b90751ebb7a8c3ef09e44619bd864ef270bc2be04ec6"], + ["0100000004c419c3656373d4018c5834ac10f171c368311a5ec76d008e25c4039cc0e5c0360000000001ab78afe4cdea988603ca520ab94d7d442f24038f3312e80a958dd5ea01023955f75d7216120300000000ffffffff50dea10c18444fec62a879dd31ef3eb91b8820c4f6926c096a569d22f5ea4147000000000751acab51536565e56c5266136d158e49c7b3086e09907867b537a465b57bc399dfebbe4fe519f8677f338b02000000096565516a5263630051ffffffff02f47f570300000000003737e3020000000006abab5352ac6500000000", "525153acab65ab", 3, 5109454, 1681038174, "ae5e0bf05aa8131f35d2b8e0d36e41325162a12e1babc9b98ad52cbd6f6aff73"], + ["010000000359265539ff4db4d6dc2c7f8fcdae1000dcafb1508ac461fa5ba176c585d8638e0200000009acac63656351655152ffffffffaee5caf0ed44d26f9d830060e071efbc6dc628068ce27b8e27937069b841ed7700000000070052ac655252ab9b194e75c8485b1126725afb2809963162fc0622160ffb91db6d6226a7f8b3f8e6d8e68d0200000000196e75b102fc5bd7010000000009535352ab6300ab5151fa2511030000000004ab00ab53df9e4402", "6551ac520051510000", 2, 1883684, 415881087, "be96232be0991b3d6bca6abffd3343a8ae623b0bb318f3a54bdf4dfe800f5f36"], + ["0100000002074307c8e8ae4929f21be0e38d38b8e1efc9cd11b02b780d03f799bb6470bc0300000000066a53ab00516ae0fe51a4beeac32f4729bd1e7d8f91cc33043d2266655ecc48ddefe3fe72de31dee4ec870100000008ac51656300ac52524e19fef604b140c40200000000056551ac51515cb4dd030000000001514b9522040000000008ab5253ac6a52536a5e48660400000000015300000000", "0065abacabab6a6a65", 1, 1311838, -645015852, "6fabf574bda37e67aec51126db532e1444a96e03d1dc9ce306d6b495e0649e14"], + ["0200000002b95388aabc736cda80b2241604c1a86f8d7e37b9b6a679c255bbd9eca11ec7010200000009ac65ac63ac5100ac6a0f88d2cbce8f5c6498a8f01947cdb7c56e30dad720654ff43e8e686076a1095e6268dd62000000000253ac58061b7f022d61fa00000000000263639f7b5f02000000000251ac00000000", "52526a6a6352", 1, 6705562, -1279719720, "9035212667d65f353b6c781c653513a2e14a013642a998d5d7bc9e0390f78b89"], + ["01000000024fc6a50285420b215bd27811ce3bfaa0d150064afc0e59d91bfad34822b663930100000005ab6a6a6365ffffffffaec00b286db17e60bc8db390b61aba3939cb85b049f1d2595ef06356fed936ea03000000020052a52bc2270468a2a9010000000005ac63516a5239481b010000000000973bc3050000000000f2808002000000000200ac00000000", "", 1, 9752746, -956733962, "90b4ca2f31d85fb334ed32340c4eefb396ed3b9b7e724e296c011a6306849b1a"], + ["02000000041df3bee271c929eaeb38a7f14674f0a16a38b8c6c865f1fdaa22bb0d0c84346d000000000153f47b70b35ebc30ac2c280786e4af030ae4f5a844a90eea5fa10d1751d92401bb4a110bc10200000004ab65636affffffffb9477a6c69ed69bb12ce8a9edac7d8e49f21e50605da70d1e81b380d9ba4857703000000055152526aac06094a697cb5314865094f39226ced1248c2402c3b83eb2a5dc49264294d11e4c745604103000000020051db3342af021308a30500000000025165039df701000000000453525300ecd73f5f", "535363ab00", 1, 2986756, -933692844, "9f65f441e71bdcd79e0b6bd5fc8a407d2cd8d299bb6d5e726f30165c57d7572c"], + ["01000000034405af528aa00ea8eaf3db60cbf2d011d4f2a8fe632d955486cfbf538dfe09ad01000000095165abac525252ac53ffffffff9b771fceddc5b14cf67f49afedb5c73c36d8e8d935e02b72d4fc14dfea77565303000000056a51510053ffffffff17a3e448ebcbd72fc8477411fde7a62b519cb859f69789039f6c4cd4286a294800000000086565536500520063ffffffff04ede2e904000000000600abab5253524da91802000000000165cf5481010000000008acab52630051526af611900300000000076500ab635152ab00000000", "53636363515365", 2, 4578070, 1044353383, "38f2ce17e78e86e35c15b7dae4bbf51cf63a983a414ecb3c9495a44917037c2f"], + ["020000000471ed2c1e2736f998caf8b558c275400e35e18b949b986308ae8c2094b1796e32000000000751516351515351dd0c322535859b162189cfc053cbfe84db78019171c2f755dba3fb22ec37291d6088e9170000000009ac5165ab6552526a63ffffffffcab3ecdc08feaa8651ff43cda8dc6022711b92e569c0e3602e47f6f3a5ebf1ce01000000026aacffffffff8a8c9b759169b3cae27f8ad8fe2e92f02be8c3a7199a9fa28a336327f25abb6600000000007e1c9eec04589bc40500000000056a000053004e8af500000000000653acacab515390ed6e0400000000076aab536300acabaf8fe20300000000085300ab526a65516500000000", "ab51656a5165", 3, 770949, 1344376298, "83899aa079287e90d299d0dc09593c1590fdf9df47019982a31520eef534a3d5"], + ["010000000474191fb95881c8656efccb6fd2029b4ba454810dd2aace85a03e7e07dc05fa3b010000000252ac53b66e3a07734fd1919a6dbc7ca90027ef9cce584d66bfc7a24f07bdd23b2ba96da3d66f0100000000139644c59538c4ce3824e10926f4aa2e3babe5a79f86570eda997e2d2185825c0dd5161c0300000006ac5300ac6a52f1d44e72b8904e3bf008115e9624af1774e3f2b6c8c80187dfc8260ed85132b4176a17070300000003ac5365ffffffff02a878cf02000000000651656500656552bbcf0100000000015257d5b131", "53", 1, 5400373, -1795872315, "dae44ddc74330faff92c47fd261eb0e0dfee96a5656a40af087806f01281fdcc"], + ["0200000002f703046bf64302d473c767f8beb0ecc6192221f92b9e90b6618e972be8a8dc630100000000d943c2f4ea00db2f577d55e08527e40b41088716fed7535db851b7062d49591206c6b892020000000751ac635200656a88753d3603a9442c050000000004525251ab6fa4bd000000000005acab5100acba0dfe03000000000453655151c2a6bb5a", "52ac51", 0, 4709242, -1027636110, "44c304efc4502062477252b1afe3319df46ead2999f1c134a10498738e5e1356"], + ["02000000010d7b7de0a3d1b2f48c818cf284f0c028ab20aadcff202ab1dc72f5971747f71f010000000453005152ffffffff018985120000000000045365ab00833b8570", "65", 0, 4226965, 1297042152, "3f3d880edbb783b59e1a0021afec684a7529931adf0e54a0b2bd312f0ce96d47"], + ["0200000004dfa91bedd1223a14182aeef4ab98dcaaff2428fd2151cbc20fa087695328237802000000086a65ab63006a51ac7e7440c69342d0b8e203c087f2a6921e16c09b055964a28d81a0e97828da70859c256d8401000000045365ab6affffffffe707889cedaf6e7ba91cca39d8fbb1a54d3f5203831517a8425f8a0e9e21f24e0300000007ac6a636563006affffffffddcb0b33d881910b6778d07e6bfd7c29a8e2913302576e50c3adbb7f80fe2d130300000001006be3599402b3f693050000000004005351ac812d900500000000036353636d0fb605", "63ac63005263ac", 1, 9909801, -1538902934, "c760b6c9c131ff35e5b86d115a82032168fa7b67b67b97f54b23f30071815c48"], + ["01000000033bf2a66a9049dff4bf5658b4a703aef6ebc9998d32a481930c5de2439cb0c8c80300000004ab525151ffffffff4a5582aa6f15a50ee350668c52239f7e78400374133fd967b3fdaadda0d7bc5f0300000008ababac5353ab00abfffffffff3e9e3035111f6b5d36bcc85ddc89b75a6370771e6dcb1f66f4ee9964de5fdde03000000026a53e646333e01064857020000000000a271cc23", "005265510053", 2, 6368718, 1039551567, "6a54e14bae7ead471adc71686327636209101b3ba5f2408e22f769aaf6d0d62a"], + ["0200000004fb34df65eb6a6522ae72091de6fc88d8de3ea94d740ddcbe2db746db8c1359cc02000000055253656553ffffffffbfeea412647b270997db9729d6df707715d5118c107f56be980f2d4f3f7dccc6000000000453656300ffffffff7f5672f3dc5ed03ef60f61863c7a2819a2a94583646530dac619d27eae034aef03000000085100abab52636551ffffffff1e7f15ec33b786dba1db6084e0aa1b35bfa3983bc80ad0408a3255b607373906020000000753ab6552ac00657e04294901cca1f4000000000003ab516a00000000", "006a536aac", 2, 8482165, -371588533, "2274c730e42d0a4e6f1f5e574e5f075ef867f4752c7c84556c683d53de86e05b"], + ["0100000003037552370969c07c558dc2665bdc3cd30486b3fd8d4c86d365aef06f7ef3b29100000000015227c753475ee3f680ef243ea1b59fbddd05074b1ddaefb06488b88c8051bba82da8c7ee560200000009656a51ab5353635151ffffffff1915dfb0c337ce3bcf40a886ab3af17c0e20b5337bb3b50373658e5ad6747e680300000003ab6a5186245fa903b7a3440000000000026353607c8d040000000004ac526a007d14ec0500000000036500ac00000000", "", 1, 9626277, 1558786045, "1403e017d301be22f8005fbed44e5a052770094644a6da83e026cc0934c2ec13"], + ["0200000004e9f908115020300a714af9f2c92733c001b3486d29470b6108630215b8e6801b0200000000ffffffff995872460d4dbf845787a615968327a18ac4dcc9a2dd06473f21056ce6b563d903000000076352abac63656aa82d10afc923e0b117b04451b427e9fa65350db3813b69739d6782f38bb90c0fa6535c6b0000000002ac00ffffffff6cc6d06ebca08fa51de85225158ae64ea9af80ef1f9556bc783918ecae6e1c740200000009656aac0053ac65ac51ce376f2d0115c3fd010000000005ab65656552f2672b1d", "abac6aacac", 3, 5541999, -1817695137, "0c722b64ef813b47eff30786e7bc4e4180288a6707716b1a4d61bebef85e555b"], + ["010000000254edbbd7b795923158d7078ef9550fd1d52a7967f6e0f69d0b65a03505dfb6f402000000075365ab5265ac00ffffffff4a52d1b88fe056129b2e3f2b100bbab6c9efbe7029bab3cae3fd91bc9cd5b32f030000000553ab6a6353ca82174a026c13db05000000000553ab6a6365a7539a020000000002535264692ce2", "ab51", 0, 7387847, -403442866, "e02083f7c6204baf75fbf4beaa4bbc7934f135823e473195504376191b849304"], + ["01000000049a8fa7eb86b3a8191853a5f8edde0a4ff3e8ba7cc698b14cd0bc5f698973fe01000000000453ab6a633ec9c220826a309cdbc54fdddbe4d07ca9e47517050e6debe7454c9061c26bc95ab8cb09020000000551636aac00ffffffffa0cb1abddc9db5fd8da874edd5f07f430b30684ae5090e5867b32002c392dc6803000000065300ab6a63abffffffff08bf9ce8130517a455af45ccf90538640ca5534ddf21258d8de2162b611b689600000000096aab5363ab520052511112132004eb75f00300000000075163acabac6aab00b9d600000000000853ab0065006a656520ab08040000000004536552517151e2050000000006526a0051636300000000", "52ab53ab5151ab00", 0, 7678012, -618144685, "15701301cc908721ecf6787e7011eef654e32b7681c23f8784aef76e92563c7d"], + ["02000000016114fcb4be0dcb02a0f19abf22b631387a8e60a15134e05db9a8eee5cc1d3197010000000853acab630051536affffffff03c5477a000000000009ac52acab53ab52ab51a0cbf902000000000852acac6a536a6a51e7090a0500000000046a65abab00000000", "52006aab53535363", 0, 9415316, 1723247301, "0c2b6e61455f5d16f70f7b8995cff08c5720463d0969a71a6115b6a97584f0f1"], + ["0100000001984e962e2919e929947182a3187e21af106850683786306a8060f31174894f240300000003530052ffffffff03cea0d8020000000001633f3c9c030000000008510065abab5100ab1dc19f05000000000000000000", "51535100", 0, 2185449, 1177720434, "ac544dd5d05d6ec7046deaa7bc5e7f664c20affbf6137e7b4d448c2cb35282c7"], + ["02000000029ca84edbdb1ab5226cddeb41d6f7051dacc43a8386d86e6597353bd8d938aa50020000000152ffffffff79516697568d6724f6244445572ba88f4da0117ad9b3bb3d0a8ddfabc9aa93be01000000060052525100ab268ca68c016222f2040000000002515284b6e265", "5163acab00510053", 0, 7777648, 12810073, "1410e152d3c8cbdcf4a14ff8a3118ad93c038e14959cebe5d60cc9f341a5dbbc"], + ["0100000002181d417e41939aa3f833ce94ab8dd31b13121cc94dec78f5dd5af795423891370200000001630ddf665c4319d3cc90e2a5cae323e2fca6ce75186ba93442ccf4afe1ab0320f6dd7077820100000007abac6aab005363ffffffff028c338400000000000351656a9fd30403000000000165cdff2639", "656a516a635253", 0, 8897881, 1599964406, "bfe49b403dd5f65e2ddb1f690ef71264adf07f3f238b716e537f1a1b6806f7f0"], + ["0200000004c045e0ba2a974f086ce753a7958c06d9424fb6803dfcd3d39e23228b35fb81350300000000ffffffff5ce5c824574a6288faa0e1ed16fe0f7ea0176c64124de63b8da82b11fc6170eb000000000253634e79119902147c096400a914698c1ebda65527b7559c85eebcf23a26f28a4c5175319734000000000300ac51ffffffff56d4d62833b034b2e91a3056f422ca7961c37bfd8d7156f74bfd76d54ce904280200000007abac52515363acffffffff044d4d65010000000002ab6a7c57fc02000000000665ab52ac6aacde250d0300000000016af6a757010000000005000052656500000000", "ab6565", 0, 116194, 1755594076, "712ca7bbc50c94bc697c69d70d80effc4f4213357c90e96722e12ced89ecb5aa"], + ["0100000002ebf26f39502c286ca932939e72e9a4844469ed04f31bcfd289b6dbfb1466cbed02000000016afdb497aedcfc14471ce52637dea783be57d69cace9441961def1337c6abbb75427be15f30200000004ab51acacf2a32714044ef174000000000009636300515253acab52377ead03000000000252ac793fac0000000000080063ac00ab51005237c3e4020000000008530000ac6363656346a2c5f1", "655252516a65", 0, 4919737, -1909964198, "1453b03912e5c5d381334aee194844abd2e62116201d57a04e3684bb488756c3"], + ["010000000161b30a7b695d6fc0dd435344a7fbc924262ae70478ae56dd3ec76aab82b97b5b0100000006acac6363ac63ffffffff03aa82140300000000076a52acab5300527b19b201000000000363516548efc60500000000066aabab63656a00000000", "535300ac526a5251", 0, 5646653, 1580819054, "d7b7d722856aa9a4477124fceff8a5a01debb90528e88845dac7446d3ed0b858"], + ["0200000003a25bd5be0b47f4bb89910aca0ee7ae417c4ba0660ed1b56d4ad69503b149a7d80100000005ab65ab5353ffffffff44d27fee5bbaa67bb3e0f2a08373e810dc9527e8a56eb174c53dc68943126eab03000000085263acac5353ac650f57785feb4a503c6b8acc9861f3722cbc8a68e802c1bc9e0f3bd1a3bbce75f85c4c7c9c020000000363ab002698a651032113b901000000000300ac63e112ce0200000000036300acbf22e90000000000076a6aab5252635100000000", "5300ab6a", 0, 6015673, -1687643051, "e30a1f9cae244a8ad1a91f1fa2867e87533ee5d4803f211889a935bf2a781b9a"], + ["020000000167e0f2ec31d71bbbf9705316f9763ea70b2409802dfb05be30d8ce28c8fabede010000000152aba65b4b036366c9050000000006ab6aacab5253274c9d020000000007acacacac536a632276e605000000000865acab00ab63516a93fe6fc7", "0000ac6a63", 0, 2869444, 840288710, "d194e72ccea7247bc97a455aa5e97344038277675064e42ada19d16e05e8f182"], + ["0200000001ada3271d1ce06d75cc7a39117d4f295573deab6b734dcfa548fe3e77424949d1030000000153831bd416044b85fb04000000000951526553516a535300477c98040000000003656551c889c2000000000009655165536a536a52ab234a60030000000003ab515300000000", "5300", 0, 1030700, -386012302, "fe068afc9f18bb2b7fda0aff21cce4c1de89e65b698575c620484f92b1a8accd"], + ["010000000388162fdb5235fe97d108c21e046f78b07d150e5af25f6903d0379d5cb51c8e1100000000025265fffffffff8f7911f35dfd3b13ef563584dede69783611c444173083c580ef0428bba9262020000000951ab6551ac52510065ffffffff06b1b261aacf2293ce951c5c8192706dc227d6833ab0c8ba4b0f9b4a21e75c5003000000096aab6aab526553ab51cb5d8d64037919a8030000000005526a63abac4779b90500000000096a65ababac0053ac6ae86ee1040000000003535263271fc013", "6a53005151516563", 2, 3411311, -127197884, "cfe6c16ef34b8d68734350873012f1d9aadaa0242965d70e1c70127cbb5251a0"], + ["0100000001abf8cff62cb332aba1f2ef60e4b189aac476acbf6e5cf88ae640971b0d3fb71c010000000852536aab63ac0051ffffffff0155ad2b050000000007536a6551005252f9c78609", "ab6552abab51526a53", 0, 3281161, -1648484130, "a0ed3a264776fbc4f29443366528ddf47129a8b22e39fc7e53dcb95ba7eaa322"], + ["01000000028fbdf755d3385e009553cf7c0aeeac97598a9d87de33440f4e099567182c4a390100000009525151515251635200af4c36d00750f900284dbf2b7ba0061bcee556d43c274947452cf66697d59ffd1cbbedae010000000163ffffffff02889e5b0300000000086a0052ac5251535159387a040000000008006352536553abab00000000", "006500ac00ac63", 1, 7684826, 1218586436, "2ce04ce376990635b2916175bbc56382d08e4702f0e9a39440a0f0b8814be9dc"], + ["0200000003bdb614f83b13cf9b8857eb0038d132a5261809d90e511764c60c28b3fa50f19700000000015154e572637ae3e5911e2afa633577388843c486127444bc4019d0f6a2a3532b197c82a179000000000963ac65acac5351acabc0eaf0601566186498b3819a0149f1ba767f6a37ab7af87628a9421234356b51615765de0100000008ac51526a53ab6363ffffffff03f8628a050000000003ab6551ee42410000000000076a536aac63abac256893000000000006656a52ac635100000000", "", 1, 1908314, 154440002, "d74e06503584cb140706527b9090ed798931995bfcee1aa59cec6a9c9809608d"], + ["01000000043c6ef7c785592879cf96fa82d6b2a5ba4aaae415195e3c3a82e06dbbf3693602020000000552530000acbc4595768d52e11c79fdca50f91f8cd09737f01751e3260efdf6c5bc849c7e8162fc111703000000075365526a530053e90ecf62f9fe8945d087d4f347e4e070f9998ca7eb216e08d98b5479eb56b94b47b8e4f601000000066a6363510065ffffffff62aa30f9c4091a8510e28cfc9f366472870d6a920fe30cea42f97ac9ced6e44000000000020052ffffffff04770b48050000000002ab51cc6cc100000000000163f58d1e0300000000086300acab52520063d0b8aa020000000003ab5365026e4fa0", "6553656a6a", 3, 9887440, 90402290, "234e22330d05162d25efffa39825c0e8577cd8fccc89b40ab0eb39c7b0805f7b"], + ["0100000001ffc6dbc2862443f10b342a46b02f33f8ee8ee12289f5c368d47ea0a8e08fabed0000000009ab53abac53005300005005dafc021221ab04000000000400656aac591697030000000002535100000000", "ac51", 0, 687666, -1997216421, "7a476bc7e67a8fb52adaa9c28440c5f41e32515ad942470a159a5c500d2534df"], + ["010000000428c47b3d6a818f84453022ecf7b5f0929aecb05048a4e2085b2ec284f79fdb04000000000463516565ffffffff42f2d7268ba314b098110fb622d7ef2a27b62537bc7c986cad56471b48084ced00000000036a6353ffffffff60296dc7bdc07b37b0f61a90f7035f2a6b59bd8c7ce6a555908baf0b6765ee0f0200000007535153ac005163a7c48dad6479eb3005524a32002a7c1ff9c19a6567d990ffe397d5d2bf8e641d5a8683b70000000000ffffffff02e156a404000000000351ac6a6078fc03000000000751ac52656a636a00000000", "", 0, 1065730, 1729806680, "ab4f0018891353368a7a2b6aaf250b4baa60c280ac124925f5c038eaf0c504b6"], + ["010000000373bed8ec9eb774a06e117454fb593cf2560ccbae096f0547ef2d506356a1c2bc0000000008ac6a6563535100abffffffff4ff34c77334b3ee07a1e3c312801fe548e1f193ea5d8af1104f6eb53a89462bb03000000095163ab53ab51ab52abcf14cf4f0e04a1049f1d35d2e3893ddbee3e0d629ef896c6196d6e0d0a31895b20d3d1440300000006516a65525300ffffffff044f02590100000000086a00516352515352e074a902000000000061b3860000000000016ae73f410300000000066a65ab6563ab00000000", "635152535200ab", 2, 2788214, 680111455, "cb960bf5f48a1d00af4b12fffa6a4a0a71962ffde4be702a1d8d3868d7be8032"], + ["02000000044bd7d2504a638cfb47814c56f9ae8df16b2c23a615b736bb900442c4fa06e3f90200000004ac63ab00a62fcd430e6750b9e8a7556ee1e8298854a4b5a1ca8eeaee8ee938971adcae6e98c613570300000004ac5263acffffffffa6d5f1ed35cc0bdc5eeebb2e68f46e08c961748b1871cd500b778ad36792c06401000000096a53536a00516a51acffffffffe4c0ef82c98b35ca0eabe140832386c20aa0da9314fd266ee9b1b68d4c5d3b82030000000152ffffffff01d0711f03000000000565ac0000ab00000000", "525151", 2, 5931921, -1185712950, "63ce386d86ee623bc32384fc11d2283ef48d8f809e0b159d229a9c16e952e8be"], + ["0100000003623ed9cf68eae7fdc3208c4508e7c22cb6d571f95ba851d93f8771a7202ea8220300000002ac514c7c47e871e62dc02113da6f7b15a363d217b35807346c1480ca021d9880516b23e5313a000000000163737e0012857e59d373829b5cd1a92c70efb47a0959e9b7a485caf6b3cc4d51fc52312a5c0100000006ab00530051acffffffff0413a5d70000000000045200ab51e13788030000000007ab635152656a5139e45a0100000000000fb93b0000000000095265650052650065ac6e6b1b7a", "6a51", 2, 2723897, 1894414842, "b4a4757e0886bb8f32b95a80b7e3083a2514dfb728a1ecc2de2fe5a3e52f2db7"], + ["020000000292fd42ba56b92a65faf781bae1c754a48463f24d66ba4072015dfa3dc9a8025f00000000060051ab536365ffffffffa6060eb61194c9656129ce49e7be1dc03282f87d32137dded3f566411fce18f3030000000653ab525363529f7fc47103a5212b02000000000900635165acac636365c7498f05000000000952ab005252655263633b7165050000000002525100000000", "6a005253ac", 1, 9319477, 1776524647, "cd32d0f518fb6b217972d50a4346cf6084e1a3857014872d0d0e9224a8071861"], + ["020000000314971bd10f589a8239e1c2d30b2da0e2a685b2aa9d54797d9685591d791279db00000000026552ffffffff8c20b63e1f8d1acea98ac6bbe0f7ad314f4cc5e76e8792bf4beba6562683fdb403000000016affffffff7979a9e665d3b533ac50c29faed1bd00be2b8307735fba8b2dc32fbde13c2b2102000000055165ab5300ffffffff0498152401000000000865656a536a6351aca37e0d04000000000753ab656aacab6a337ae205000000000900ac65ac51535100536afdb3030000000003ac6a6a00000000", "636563", 2, 7411767, -1460556474, "9a3211b66192c86eea78469396bb936a8a8d47ee381398700e0eeba78474ea06"] +] diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index 1ce4035e4557..27ee64cbf2f4 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -111,6 +112,61 @@ void static RandomTransaction(CMutableTransaction &tx, bool fSingle) { } } +static void TestSigHashFromData(SigVersion sigVersion) +{ + const bool isDip0143 = sigVersion == SigVersion::DIP0143; + UniValue tests; + if (isDip0143) { + tests = read_json(std::string(json_tests::sighash_dip0143, json_tests::sighash_dip0143 + sizeof(json_tests::sighash_dip0143))); + } else { + tests = read_json(std::string(json_tests::sighash, json_tests::sighash + sizeof(json_tests::sighash))); + } + for (unsigned int idx = 0; idx < tests.size(); idx++) { + UniValue test = tests[idx]; + std::string strTest = test.write(); + if (test.size() < 1) // Allow for extra stuff (useful for comments) + { + BOOST_ERROR("Bad test: " << strTest); + continue; + } + if (test.size() == 1) continue; // comment + + std::string raw_tx, raw_script, sigHashHex; + int nIn, nHashType; + CAmount amount; + uint256 sh; + CTransactionRef tx; + CScript scriptCode = CScript(); + + try { + // deserialize test data + raw_tx = test[0].get_str(); + raw_script = test[1].get_str(); + nIn = test[2].get_int(); + amount = isDip0143 ? test[3].get_int() : 0; + size_t offset = isDip0143 ? 1 : 0; + nHashType = test[3 + offset].get_int(); + sigHashHex = test[4 + offset].get_str(); + + CDataStream stream(ParseHex(raw_tx), SER_NETWORK, PROTOCOL_VERSION); + stream >> tx; + + TxValidationState state; + BOOST_CHECK_MESSAGE(CheckTransaction(*tx, state), strTest); + BOOST_CHECK(state.IsValid()); + + std::vector raw = ParseHex(raw_script); + scriptCode.insert(scriptCode.end(), raw.begin(), raw.end()); + } catch (...) { + BOOST_ERROR("Bad test, couldn't deserialize data: " << strTest); + continue; + } + + sh = SignatureHash(scriptCode, *tx, nIn, nHashType, amount, sigVersion); + BOOST_CHECK_MESSAGE(sh.GetHex() == sigHashHex, strTest); + } +} + BOOST_FIXTURE_TEST_SUITE(sighash_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(sighash_test) @@ -158,48 +214,8 @@ BOOST_AUTO_TEST_CASE(sighash_test) // Goal: check that SignatureHash generates correct hash BOOST_AUTO_TEST_CASE(sighash_from_data) { - UniValue tests = read_json(std::string(json_tests::sighash, json_tests::sighash + sizeof(json_tests::sighash))); - - for (unsigned int idx = 0; idx < tests.size(); idx++) { - UniValue test = tests[idx]; - std::string strTest = test.write(); - if (test.size() < 1) // Allow for extra stuff (useful for comments) - { - BOOST_ERROR("Bad test: " << strTest); - continue; - } - if (test.size() == 1) continue; // comment - - std::string raw_tx, raw_script, sigHashHex; - int nIn, nHashType; - uint256 sh; - CTransactionRef tx; - CScript scriptCode = CScript(); - - try { - // deserialize test data - raw_tx = test[0].get_str(); - raw_script = test[1].get_str(); - nIn = test[2].get_int(); - nHashType = test[3].get_int(); - sigHashHex = test[4].get_str(); - - CDataStream stream(ParseHex(raw_tx), SER_NETWORK, PROTOCOL_VERSION); - stream >> tx; - - TxValidationState state; - BOOST_CHECK_MESSAGE(CheckTransaction(*tx, state), strTest); - BOOST_CHECK(state.IsValid()); - - std::vector raw = ParseHex(raw_script); - scriptCode.insert(scriptCode.end(), raw.begin(), raw.end()); - } catch (...) { - BOOST_ERROR("Bad test, couldn't deserialize data: " << strTest); - continue; - } - - sh = SignatureHash(scriptCode, *tx, nIn, nHashType, 0, SigVersion::BASE); - BOOST_CHECK_MESSAGE(sh.GetHex() == sigHashHex, strTest); + for (const auto sigVersion : {SigVersion::BASE, SigVersion::DIP0143}) { + TestSigHashFromData(sigVersion); } } BOOST_AUTO_TEST_SUITE_END() From fc6fc900728b165bd194cd196ad3ddd72533ec90 Mon Sep 17 00:00:00 2001 From: Alessandro Rezzi Date: Sat, 24 Feb 2024 13:49:51 +0100 Subject: [PATCH 10/16] test: VerifyScript unit test coverage - Test that txs with SigVersion DIP0143 pass script verification only when the corresponding flag is set - Test that multi sig transactions can have their inputs signed with different SigVersion (one BASE, the other DIP0143) - Test that SigHashType DIP0143 cannot be used alone --- src/Makefile.test.include | 1 + src/test/dip0143_tests.cpp | 156 +++++++++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 src/test/dip0143_tests.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index edcad0d7775a..86aeb10d90b0 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -105,6 +105,7 @@ BITCOIN_TESTS =\ test/cuckoocache_tests.cpp \ test/denialofservice_tests.cpp \ test/dip0020opcodes_tests.cpp \ + test/dip0143_tests.cpp \ test/descriptor_tests.cpp \ test/dynamic_activation_thresholds_tests.cpp \ test/evo_assetlocks_tests.cpp \ diff --git a/src/test/dip0143_tests.cpp b/src/test/dip0143_tests.cpp new file mode 100644 index 000000000000..70e4639c7b6e --- /dev/null +++ b/src/test/dip0143_tests.cpp @@ -0,0 +1,156 @@ +// Copyright (c) 2024 The Dash Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include