Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ add_executable(test_tapyrus
sanity_tests.cpp
scheduler_tests.cpp
script_p2sh_tests.cpp
script_risky_combinations_tests.cpp
script_standard_tests.cpp
script_tests.cpp
scriptnum_tests.cpp
Expand Down
161 changes: 161 additions & 0 deletions src/test/chainstate_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -936,6 +936,167 @@ BOOST_AUTO_TEST_CASE(duplicate_nonreissuable_issuance_rejected)
}
}

/**
* Regression test: burning an NFT must not erase its colorId from
* g_colorid_state, so a later re-issuance attempt is still rejected.
*
* "Burn" means spending the sole live NFT UTXO to an uncolored output —
* VerifyTokenBalances allows colored input value with no matching colored
* output (the value is simply discarded). This does not touch
* g_colorid_state: CIssuedColorIds::Erase() is only ever called from
* DisconnectBlock (reorg), never from a normal spend/burn. So after a burn,
* total live supply of the colorId is zero, but g_colorid_state must still
* report it as issued forever.
*
* As in duplicate_nonreissuable_issuance_rejected, actually re-deriving the
* same colorId requires the exact defining TPC outpoint to look unspent
* again (a SHA-256 preimage collision in practice), so the re-issuance
* attempt is exercised directly against CheckColorIdentifierValidity with a
* synthetic CCoinsViewCache that presents the (long since spent) defining
* outpoint as unspent — simulating the same reorg-shaped bug the
* NON_REISSUABLE test guards against.
*/
BOOST_AUTO_TEST_CASE(duplicate_nft_issuance_after_burn_rejected)
{
CScript payTo = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;

CKey key;
// Arbitrary non-coinbase key; low byte 3 is not load-bearing, just chosen
// to avoid clashing with any of TestChainSetup's pre-defined keys.
const unsigned char vchKeyBytes[32] = {
3,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
};
key.Set(vchKeyBytes, vchKeyBytes + 32, true);
CPubKey pubkey = key.GetPubKey();
std::vector<unsigned char> vchPubKey(pubkey.begin(), pubkey.end());
std::vector<unsigned char> pubkeyHash(20);
CHash160().Write(pubkey.data(), pubkey.size()).Finalize(pubkeyHash.data());

// Block: spend coinbase[1] into a plain TPC P2PKH output that will define
// the NFT's color id below.
CMutableTransaction spendTx;
spendTx.nFeatures = 1;
spendTx.vin.resize(1);
spendTx.vout.resize(1);
spendTx.vin[0].prevout.hashMalFix = m_coinbase_txns[1]->GetHashMalFix();
spendTx.vin[0].prevout.n = 0;
spendTx.vout[0].nValue = 100 * CENT;
spendTx.vout[0].scriptPubKey = CScript() << OP_DUP << OP_HASH160
<< ToByteVector(pubkeyHash)
<< OP_EQUALVERIFY << OP_CHECKSIG;
{
std::vector<unsigned char> vchSig;
uint256 sigHash = SignatureHash(
m_coinbase_txns[1]->vout[0].scriptPubKey, spendTx, 0, SIGHASH_ALL, 0, SigVersion::BASE);
coinbaseKey.Sign_Schnorr(sigHash, vchSig);
vchSig.push_back(SIGHASH_ALL);
spendTx.vin[0].scriptSig = CScript() << vchSig;
}
CreateAndProcessBlock({spendTx}, payTo);

// Block: issue an NFT (nValue must be exactly 1) from the defining P2PKH UTXO.
COutPoint definingUtxo(spendTx.GetHashMalFix(), 0);
ColorIdentifier colorid(definingUtxo, TokenTypes::NFT);
CScript colorScript = CScript() << colorid.toVector() << OP_COLOR
<< OP_DUP << OP_HASH160
<< ToByteVector(pubkeyHash)
<< OP_EQUALVERIFY << OP_CHECKSIG;

CMutableTransaction issueTx;
issueTx.nFeatures = 1;
issueTx.vin.resize(1);
issueTx.vout.resize(1);
issueTx.vin[0].prevout = definingUtxo;
issueTx.vout[0].nValue = 1;
issueTx.vout[0].scriptPubKey = colorScript;
{
std::vector<unsigned char> vchSig;
uint256 sigHash = SignatureHash(
spendTx.vout[0].scriptPubKey, issueTx, 0, SIGHASH_ALL, 0, SigVersion::BASE);
key.Sign_Schnorr(sigHash, vchSig);
vchSig.push_back(SIGHASH_ALL);
issueTx.vin[0].scriptSig = CScript() << vchSig << vchPubKey;
}
CreateAndProcessBlock({issueTx}, payTo);

{
LOCK(cs_main);
BOOST_REQUIRE(g_colorid_state && g_colorid_state->IsIssued(colorid));
}

// Block: burn the NFT — spend issueTx:0 (the only live unit) plus a TPC
// coinbase input (for fee/tpcin>0) to a plain uncolored output. No output
// carries colorid, so its value is simply discarded (a genuine burn).
CMutableTransaction burnTx;
burnTx.nFeatures = 1;
burnTx.vin.resize(2);
burnTx.vout.resize(1);
burnTx.vin[0].prevout = COutPoint(issueTx.GetHashMalFix(), 0);
burnTx.vin[1].prevout.hashMalFix = m_coinbase_txns[2]->GetHashMalFix();
burnTx.vin[1].prevout.n = 0;
burnTx.vout[0].nValue = 1;
burnTx.vout[0].scriptPubKey = CScript() << OP_DUP << OP_HASH160
<< ToByteVector(pubkeyHash)
<< OP_EQUALVERIFY << OP_CHECKSIG;
{
std::vector<unsigned char> vchSig;
uint256 sigHash = SignatureHash(
issueTx.vout[0].scriptPubKey, burnTx, 0, SIGHASH_ALL, 0, SigVersion::BASE);
key.Sign_Schnorr(sigHash, vchSig);
vchSig.push_back(SIGHASH_ALL);
burnTx.vin[0].scriptSig = CScript() << vchSig << vchPubKey;
}
{
std::vector<unsigned char> vchSig;
uint256 sigHash = SignatureHash(
m_coinbase_txns[2]->vout[0].scriptPubKey, burnTx, 1, SIGHASH_ALL, 0, SigVersion::BASE);
coinbaseKey.Sign_Schnorr(sigHash, vchSig);
vchSig.push_back(SIGHASH_ALL);
burnTx.vin[1].scriptSig = CScript() << vchSig;
}
CreateAndProcessBlock({burnTx}, payTo);

// The burn destroyed the only live unit of colorid, but g_colorid_state
// must still remember it was issued -- Erase() is reorg-only.
{
LOCK(cs_main);
BOOST_REQUIRE(g_colorid_state && g_colorid_state->IsIssued(colorid));
}

// Build a synthetic CCoinsViewCache that presents definingUtxo as unspent
// again, simulating a reorg that restored the UTXO while g_colorid_state
// retained the record. CheckColorIdentifierValidity must still reject the
// re-issuance with "bad-txns-colorid-already-issued", even though the
// colorId's supply is currently zero.
{
LOCK(cs_main);

CCoinsView dummy;
CCoinsViewCache syntheticView(&dummy);
Coin tpcCoin;
tpcCoin.out.nValue = spendTx.vout[0].nValue;
tpcCoin.out.scriptPubKey = spendTx.vout[0].scriptPubKey;
tpcCoin.nHeight = 6;
tpcCoin.fCoinBase = false;
syntheticView.AddCoin(definingUtxo, std::move(tpcCoin), /*potential_overwrite=*/false);

CMutableTransaction reissueTx;
reissueTx.nFeatures = 1;
reissueTx.vin.resize(1);
reissueTx.vout.resize(1);
reissueTx.vin[0].prevout = definingUtxo;
reissueTx.vout[0].nValue = 1;
reissueTx.vout[0].scriptPubKey = colorScript;

CValidationState state;
bool valid = CheckColorIdentifierValidity(
CTransaction(reissueTx), state, syntheticView, chainActive.Tip()->nHeight);

BOOST_CHECK(!valid);
BOOST_CHECK_EQUAL(state.GetRejectReason(), "bad-txns-colorid-already-issued");
}
}

/**
* Regression test: VerifyTokenBalances must not use DoS=100 for tpcin<=0.
*
Expand Down
25 changes: 22 additions & 3 deletions src/test/data/script_tests.json
Original file line number Diff line number Diff line change
Expand Up @@ -3089,16 +3089,35 @@
[
"0x47 0x3044022073df1d1a15d0e6fd8a14f0c1ba4409239c97d4fbc3cb113095c0929582d8447e0220271ec24bc865852e239693b20f0efbbe584d1b4cc4777948f18473ce30dc976a01 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x19 0x76a9141018853670f9f3b0582c5b9ee8ce93764ac32b9388ac",
"0x21 0xc11863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262 COLOR HASH160 0x14 0xda8a647bba351bbae4cee0089d373c97ec240580 EQUAL",
"",
"CP2SH_COLORED",
"OK",
"CP2SH(P2PKH) ECDSA"
"CP2SH(P2PKH) ECDSA, redeem script genuinely satisfied (passes with the flag on)"
],
[
"0x41 0xbc4b27bef382c8159db61d673868137020c08e7cb25b9d9653c706a025b02eadba29657e2937fd58f1dcfdb582433cb63a06a15379de562fadba9877cc531d3101 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x19 0x76a9141018853670f9f3b0582c5b9ee8ce93764ac32b9388ac",
"0x21 0xc11863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262 COLOR HASH160 0x14 0xda8a647bba351bbae4cee0089d373c97ec240580 EQUAL",
"CP2SH_COLORED",
"OK",
"CP2SH(P2PKH) SCHNORR, redeem script genuinely satisfied (passes with the flag on)"
],

["The next two show what SCRIPT_VERIFY_CP2SH_COLORED actually changes: same"],
["scriptSig/scriptPubKey (redeem script HASH160 matches; the sig inside it does"],
["NOT correspond to the pubkey), flag off vs flag on."],

[
"0x47 0x304402202539b3b68e870d525765d24cc08fadd7502ffd8735564eb545a9a3057f85469d02207611be2fde48142a19497f6c4cb4146c71bb4cd6bc567dbae30bb7ecd46bc73801 0x21 0x026292d4b98eecee53d2b78bea0883bbf85bcb4fcdd4479369bfc7c3ee3b46ea49 0x19 0x76a914aba705eb3d02be6c4563d3f6874a3e81004ec83988ac",
"0x21 0xc1c6a2c97c58b8e8264ebc66ffa99a1536ec324c21263722368a00b3dfb025abec COLOR HASH160 0x14 0x45601212e04228745b047c1fc4e8d78d83a762b1 EQUAL",
"",
"OK",
"CP2SH(P2PKH) SCHNORR"
"CP2SH(P2PKH), broken inner signature, flag OFF -- only the HASH160 preimage is checked, so this passes"
],
[
"0x47 0x304402202539b3b68e870d525765d24cc08fadd7502ffd8735564eb545a9a3057f85469d02207611be2fde48142a19497f6c4cb4146c71bb4cd6bc567dbae30bb7ecd46bc73801 0x21 0x026292d4b98eecee53d2b78bea0883bbf85bcb4fcdd4479369bfc7c3ee3b46ea49 0x19 0x76a914aba705eb3d02be6c4563d3f6874a3e81004ec83988ac",
"0x21 0xc1c6a2c97c58b8e8264ebc66ffa99a1536ec324c21263722368a00b3dfb025abec COLOR HASH160 0x14 0x45601212e04228745b047c1fc4e8d78d83a762b1 EQUAL",
"CP2SH_COLORED",
"EVAL_FALSE",
"CP2SH(P2PKH), same script, flag ON -- the redeem script is now actually evaluated and its CHECKSIG fails"
],
["The End"]
]
43 changes: 43 additions & 0 deletions src/test/data/tx_invalid.json
Original file line number Diff line number Diff line change
Expand Up @@ -887,5 +887,48 @@
["0000000000000000000000000000000000000000000000000000000000000100", 11, "DUP HASH160 0x14 0x4c9c3dfac4207d5d8cb89df5722cb3d712385e3f EQUALVERIFY CHECKSIG", 1011]],
"010000000c00010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00010000000000000000000000000000000000000000000000000000000000000100000000ffffffff0001000000000000000000000000000000000000000000000000000000000000020000006a473044022026c2e65b33fcd03b2a3b0f25030f0244bd23cc45ae4dec0f48ae62255b1998a00220463aa3982b718d593a6b9e0044513fd67a5009c2fdccc59992cffc2b167889f4012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0001000000000000000000000000000000000000000000000000000000000000030000006a4730440220008bd8382911218dcb4c9f2e75bf5c5c3635f2f2df49b36994fde85b0be21a1a02205a539ef10fb4c778b522c1be852352ea06c67ab74200977c722b0bc68972575a012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0001000000000000000000000000000000000000000000000000000000000000040000006b483045022100d9436c32ff065127d71e1a20e319e4fe0a103ba0272743dbd8580be4659ab5d302203fd62571ee1fe790b182d078ecfd092a509eac112bea558d122974ef9cc012c7012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0001000000000000000000000000000000000000000000000000000000000000050000006a47304402200e2c149b114ec546015c13b2b464bbcb0cdc5872e6775787527af6cbc4830b6c02207e9396c6979fb15a9a2b96ca08a633866eaf20dc0ff3c03e512c1d5a1654f148012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0001000000000000000000000000000000000000000000000000000000000000060000006b483045022100b20e70d897dc15420bccb5e0d3e208d27bdd676af109abbd3f88dbdb7721e6d6022005836e663173fbdfe069f54cde3c2decd3d0ea84378092a5d9d85ec8642e8a41012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff00010000000000000000000000000000000000000000000000000000000000000700000000ffffffff00010000000000000000000000000000000000000000000000000000000000000800000000ffffffff00010000000000000000000000000000000000000000000000000000000000000900000000ffffffff00010000000000000000000000000000000000000000000000000000000000000a00000000ffffffff00010000000000000000000000000000000000000000000000000000000000000b0000006a47304402206639c6e05e3b9d2675a7f3876286bdf7584fe2bbd15e0ce52dd4e02c0092cdc60220757d60b0a61fc95ada79d23746744c72bac1545a75ff6c2c7cdb6ae04e7e9592012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ffffffff0ce8030000000000000151e9030000000000000151ea030000000000000151eb030000000000000151ec030000000000000151ed030000000000000151ee030000000000000151ef030000000000000151f0030000000000000151f1030000000000000151f2030000000000000151f30300000000000001510248304502210082219a54f61bf126bfc3fa068c6e33831222d1d7138c6faa9d33ca87fd4202d6022063f9902519624254d7c2c8ea7ba2d66ae975e4e229ae38043973ec707d5d4a83012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7102473044022017fb58502475848c1b09f162cb1688d0920ff7f142bed0ef904da2ccc88b168f02201798afa61850c65e77889cbcd648a5703b487895517c88f85cdd18b021ee246a012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7100000000000247304402202830b7926e488da75782c81a54cd281720890d1af064629ebf2e31bf9f5435f30220089afaa8b455bbeb7d9b9c3fe1ed37d07685ade8455c76472cda424d93e4074a012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7102473044022026326fcdae9207b596c2b05921dbac11d81040c4d40378513670f19d9f4af893022034ecd7a282c0163b89aaa62c22ec202cef4736c58cd251649bad0d8139bcbf55012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71024730440220214978daeb2f38cd426ee6e2f44131a33d6b191af1c216247f1dd7d74c16d84a02205fdc05529b0bc0c430b4d5987264d9d075351c4f4484c16e91662e90a72aab24012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710247304402204a6e9f199dc9672cf2ff8094aaa784363be1eb62b679f7ff2df361124f1dca3302205eeb11f70fab5355c9c8ad1a0700ea355d315e334822fa182227e9815308ee8f012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc710000000000", "WITNESS"],

["Colored coin spends (OP_COLOR): invalid CP2PKH / CP2SH(P2PKH) variants"],
["Note: these only exercise script-level (VerifyScript) rejections. The"],
["consensus-level 'OP_COLOR must be exactly CP2PKH or CP2SH, else"],
["bad-txns-nonstandard-opcolor' rule (CheckColorIdentifierValidity) is not"],
["reachable from this harness -- it is covered in txvalidation_tests.cpp."],

["CP2PKH invalid: signature from the wrong key (correct pubkey pushed)"],
[[["e814a0b9ffca0211cd0d607e43cae079d5ac1baac8994f15018d5c5651324d8e", 0, "0x21 0xc111bc115c0226329c9a35a7fee1d29c1f5248e0f7841d57829b50278263149113 COLOR DUP HASH160 0x14 0x5e9a45bba03b45737b421c38366b590a89be80fd EQUALVERIFY CHECKSIG"]],
"01000000018e4d3251565c8d01154f99c8aa1bacd579e0ca437e600dcd1102caffb9a014e8000000006a473044022058a1e91ce4978c8d235c61e6783094c9bb29a2d274590f1edcd920fcaa369c4502202c0dd847d5deab020ca5f02523974dd44d815715551c5295bdf97dd76f04443f012102fc4672572cb02c5ebb43623c3cc5b213d16bfcee45aab502aaa2d92afd2775b1ffffffff0100000000000000000000000000", ""],

["CP2PKH invalid: wrong pubkey pushed (does not match embedded hash)"],
[[["e814a0b9ffca0211cd0d607e43cae079d5ac1baac8994f15018d5c5651324d8e", 0, "0x21 0xc111bc115c0226329c9a35a7fee1d29c1f5248e0f7841d57829b50278263149113 COLOR DUP HASH160 0x14 0x5e9a45bba03b45737b421c38366b590a89be80fd EQUALVERIFY CHECKSIG"]],
"01000000018e4d3251565c8d01154f99c8aa1bacd579e0ca437e600dcd1102caffb9a014e8000000006a473044022058a1e91ce4978c8d235c61e6783094c9bb29a2d274590f1edcd920fcaa369c4502202c0dd847d5deab020ca5f02523974dd44d815715551c5295bdf97dd76f04443f01210233115655789d58c0b3d1660df65e44e652eb620fb5ee06939a9513249e4aa8e7ffffffff0100000000000000000000000000", ""],

["CP2PKH invalid: color identifier payload is all-zero (rejected by EvalScript itself, not just consensus)"],
[[["b51a255d9d383c17cb958726e520415b045e2fba73ac4194fd85f28a9c6b543f", 0, "0x21 0xc10000000000000000000000000000000000000000000000000000000000000000 COLOR DUP HASH160 0x14 0x5e9a45bba03b45737b421c38366b590a89be80fd EQUALVERIFY CHECKSIG"]],
"01000000013f546b9c8af285fd9441ac73ba2f5e045b4120e5268795cb173c389d5d251ab5000000006a4730440220231f650579cbc80e180959911b3acaa756c264f6abccfdce4ff864bcb8d01f5f02204b78cab66ab4948cd6be3f60047c0db17f9fdd2c2104d2742c12af7bf9be6241012102fc4672572cb02c5ebb43623c3cc5b213d16bfcee45aab502aaa2d92afd2775b1ffffffff0100000000000000000000000000", ""],

["CP2SH(P2PKH) invalid: redeem script does not hash to the embedded scripthash"],
[[["30be58e04d2818fabc4a7e8cffdf22e3d5ed8d421e63d64b20fa84458116972f", 0, "0x21 0xc111bc115c0226329c9a35a7fee1d29c1f5248e0f7841d57829b50278263149113 COLOR HASH160 0x14 0x21e7adb7d667d8bf4a2db3b1107fecf74269a96b EQUAL"]],
"01000000012f9716814584fa204bd6631e428dedd5e322dfff8c7e4abcfa18284de058be30000000008447304402205a07d3acd38e6f4151cbb4249e8116115fae3dd859812c94ad8edf9c1a8fa90e0220052f2620585a81c5e1954204abe0d21f646b492fdaea259d583994e69d9ff56101210233115655789d58c0b3d1660df65e44e652eb620fb5ee06939a9513249e4aa8e71976a91433b0afdd23a1c43c4337bfbaae34b3fe0db939e088acffffffff0100000000000000000000000000", ""],

["P2SH(CP2PKH) invalid: OP_COLOR is unexpected inside a plain (uncolored) P2SH redeem script"],
[[["d71550dad4de82aef0e3c4c594d8e066c532a7007899ff4c78ea930f9009f9fc", 0, "HASH160 0x14 0xf4eca5b0452c281be60d90d1c36c182f39551c66 EQUAL"]],
"0100000001fcf909900f93ea784cff997800a732c566e0d894c5c4e3f0ae82ded4da5015d700000000a6463043021f72838cc7bc2de3968bbdaf157c7a3da40a6585fb837469957d6218a58c8b160220673212a09c44d9bbb0c1b654ed968eebc4da72ff6be0bcdcd6d6ddae1892d7c7012102fc4672572cb02c5ebb43623c3cc5b213d16bfcee45aab502aaa2d92afd2775b13c21c111bc115c0226329c9a35a7fee1d29c1f5248e0f7841d57829b50278263149113bc76a9145e9a45bba03b45737b421c38366b590a89be80fd88acffffffff0100000000000000000000000000", ""],

["The following two scripts are proven ACCEPTED by the raw interpreter in"],
["script_risky_combinations_tests.cpp (risk_opcolor_stack_manipulation and"],
["risk_opcolor_with_timelock) and rejected only by CheckColorIdentifierValidity"],
["(consensus layer, see txvalidation_tests.cpp) -- a check this VerifyScript-only"],
["harness cannot reach. To still exercise these exact script shapes here, the"],
["signature is deliberately wrong, so the failure below is EVAL_FALSE (a"],
["cryptographic signature mismatch), NOT proof that OP_COLOR's template"],
["restriction is enforced at this layer -- it is not."],

["SWAP-derived OP_COLOR, wrong signature"],
[[["6b3fa0499cd96b34ae40da7343cef8ff2ea61e1d382b2557c748fcd1658502c7", 0, "0x21 0xc22d62163d58906df7daa4aa14bbd74ef624333c074f922faa437ddaa538869ef1 SWAP COLOR DROP DUP HASH160 0x14 0xbe803c9776fc0302352fcff912c3e6de07d8deee EQUALVERIFY CHECKSIG"]],
"0100000001c7028565d1fc48c757252b381d1ea62efff8ce4373da40ae346bd99c49a03f6b000000008c473044022015138b446d133d86bc05f5365e2895de59d73413334ac670c8e553cb1f5dcb480220276597f1cd19fb4e7c8c7ee4809e95b1f25ef2cf38da83d1239520ad8c937eaf012102e219573f570f3f61f8be3bbaeb1408b3691cfaedf489b5499177553419528b0921c1107242fc3c7a88276516ae8987cfe9d39e204179b15e826dc511799418ba2015ffffffff0100000000000000000000000000", ""],

["OP_COLOR + CHECKLOCKTIMEVERIFY, wrong signature (locktime itself is satisfied)"],
[[["decb42c916d02a34fdba9a8e9b295aacf0423c1deee3babc69613a5ff4acb679", 0, "0x21 0xc13101b19114d1456c945f627fc6ca90a87cd25ff557c8b23ce981492f7ef23037 COLOR 0x03 0x20a107 CHECKLOCKTIMEVERIFY DROP DUP HASH160 0x14 0xbe803c9776fc0302352fcff912c3e6de07d8deee EQUALVERIFY CHECKSIG"]],
"010000000179b6acf45f3a6169bcbae3ee1d3c42f0ac5a299b8e9abafd342ad016c942cbde000000006a473044022076f7020243dcc33793f95a9cd4b0c1aed30e393e7aad88f0928db2e32735225002201cfec9c67df0359229231085d62a0d3373ebf0e04fca833561543152f2ba1252012102e219573f570f3f61f8be3bbaeb1408b3691cfaedf489b5499177553419528b09000000000100000000000000000020a10700", ""],

["Make diffs cleaner by leaving a comment here without comma at the end"]
]
Loading
Loading