Changeset View
Changeset View
Standalone View
Standalone View
src/test/script_tests.cpp
Show First 20 Lines • Show All 307 Lines • ▼ Show 20 Lines | TestBuilder &Push(const CScript &_script) { | ||||
DoPush(std::vector<uint8_t>(_script.begin(), _script.end())); | DoPush(std::vector<uint8_t>(_script.begin(), _script.end())); | ||||
return *this; | return *this; | ||||
} | } | ||||
TestBuilder &PushSig(const CKey &key, | TestBuilder &PushSig(const CKey &key, | ||||
SigHashType sigHashType = SigHashType(), | SigHashType sigHashType = SigHashType(), | ||||
unsigned int lenR = 32, unsigned int lenS = 32, | unsigned int lenR = 32, unsigned int lenS = 32, | ||||
Amount amount = Amount(0)) { | Amount amount = Amount(0)) { | ||||
uint256 hash = SignatureHash(script, spendTx, 0, sigHashType, amount); | uint256 hash = SignatureHash(script, CTransaction(spendTx), 0, | ||||
sigHashType, amount); | |||||
std::vector<uint8_t> vchSig, r, s; | std::vector<uint8_t> vchSig, r, s; | ||||
uint32_t iter = 0; | uint32_t iter = 0; | ||||
do { | do { | ||||
key.Sign(hash, vchSig, iter++); | key.Sign(hash, vchSig, iter++); | ||||
if ((lenS == 33) != (vchSig[5 + vchSig[3]] == 33)) { | if ((lenS == 33) != (vchSig[5 + vchSig[3]] == 33)) { | ||||
NegateSignatureS(vchSig); | NegateSignatureS(vchSig); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 866 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12) { | ||||
scriptPubKey12 << OP_1 << ToByteVector(key1.GetPubKey()) | scriptPubKey12 << OP_1 << ToByteVector(key1.GetPubKey()) | ||||
<< ToByteVector(key2.GetPubKey()) << OP_2 | << ToByteVector(key2.GetPubKey()) << OP_2 | ||||
<< OP_CHECKMULTISIG; | << OP_CHECKMULTISIG; | ||||
CMutableTransaction txFrom12 = | CMutableTransaction txFrom12 = | ||||
BuildCreditingTransaction(scriptPubKey12, Amount(0)); | BuildCreditingTransaction(scriptPubKey12, Amount(0)); | ||||
CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), txFrom12); | CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), txFrom12); | ||||
CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12); | CScript goodsig1 = | ||||
sign_multisig(scriptPubKey12, key1, CTransaction(txTo12)); | |||||
BOOST_CHECK(VerifyScript( | BOOST_CHECK(VerifyScript( | ||||
goodsig1, scriptPubKey12, flags, | goodsig1, scriptPubKey12, flags, | ||||
MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), | MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), | ||||
&err)); | &err)); | ||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); | BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); | ||||
txTo12.vout[0].nValue = Amount(2); | txTo12.vout[0].nValue = Amount(2); | ||||
BOOST_CHECK(!VerifyScript( | BOOST_CHECK(!VerifyScript( | ||||
goodsig1, scriptPubKey12, flags, | goodsig1, scriptPubKey12, flags, | ||||
MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), | MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), | ||||
&err)); | &err)); | ||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); | BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); | ||||
CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12); | CScript goodsig2 = | ||||
sign_multisig(scriptPubKey12, key2, CTransaction(txTo12)); | |||||
BOOST_CHECK(VerifyScript( | BOOST_CHECK(VerifyScript( | ||||
goodsig2, scriptPubKey12, flags, | goodsig2, scriptPubKey12, flags, | ||||
MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), | MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), | ||||
&err)); | &err)); | ||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); | BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); | ||||
CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12); | CScript badsig1 = sign_multisig(scriptPubKey12, key3, CTransaction(txTo12)); | ||||
BOOST_CHECK(!VerifyScript( | BOOST_CHECK(!VerifyScript( | ||||
badsig1, scriptPubKey12, flags, | badsig1, scriptPubKey12, flags, | ||||
MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), | MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), | ||||
&err)); | &err)); | ||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); | BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) { | BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) { | ||||
ScriptError err; | ScriptError err; | ||||
CKey key1, key2, key3, key4; | CKey key1, key2, key3, key4; | ||||
key1.MakeNewKey(true); | key1.MakeNewKey(true); | ||||
key2.MakeNewKey(false); | key2.MakeNewKey(false); | ||||
key3.MakeNewKey(true); | key3.MakeNewKey(true); | ||||
key4.MakeNewKey(false); | key4.MakeNewKey(false); | ||||
CScript scriptPubKey23; | CScript scriptPubKey23; | ||||
scriptPubKey23 << OP_2 << ToByteVector(key1.GetPubKey()) | scriptPubKey23 << OP_2 << ToByteVector(key1.GetPubKey()) | ||||
<< ToByteVector(key2.GetPubKey()) | << ToByteVector(key2.GetPubKey()) | ||||
<< ToByteVector(key3.GetPubKey()) << OP_3 | << ToByteVector(key3.GetPubKey()) << OP_3 | ||||
<< OP_CHECKMULTISIG; | << OP_CHECKMULTISIG; | ||||
CMutableTransaction txFrom23 = | CMutableTransaction txFrom23 = | ||||
BuildCreditingTransaction(scriptPubKey23, Amount(0)); | BuildCreditingTransaction(scriptPubKey23, Amount(0)); | ||||
CMutableTransaction txTo23 = BuildSpendingTransaction(CScript(), txFrom23); | CMutableTransaction mutableTxTo23 = | ||||
BuildSpendingTransaction(CScript(), txFrom23); | |||||
// after it has been set up, mutableTxTo23 does not change in this test, | |||||
// so we can convert it to readonly transaction and use | |||||
// TransactionSignatureChecker | |||||
// instead of MutableTransactionSignatureChecker | |||||
const CTransaction txTo23(mutableTxTo23); | |||||
std::vector<CKey> keys; | std::vector<CKey> keys; | ||||
keys.push_back(key1); | keys.push_back(key1); | ||||
keys.push_back(key2); | keys.push_back(key2); | ||||
CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23); | CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23); | ||||
BOOST_CHECK(VerifyScript( | BOOST_CHECK(VerifyScript( | ||||
goodsig1, scriptPubKey23, flags, | goodsig1, scriptPubKey23, flags, | ||||
MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), | TransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), | ||||
&err)); | &err)); | ||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); | BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); | ||||
keys.clear(); | keys.clear(); | ||||
keys.push_back(key1); | keys.push_back(key1); | ||||
keys.push_back(key3); | keys.push_back(key3); | ||||
CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23); | CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23); | ||||
BOOST_CHECK(VerifyScript( | BOOST_CHECK(VerifyScript( | ||||
goodsig2, scriptPubKey23, flags, | goodsig2, scriptPubKey23, flags, | ||||
MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), | TransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), | ||||
&err)); | &err)); | ||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); | BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); | ||||
keys.clear(); | keys.clear(); | ||||
keys.push_back(key2); | keys.push_back(key2); | ||||
keys.push_back(key3); | keys.push_back(key3); | ||||
CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23); | CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23); | ||||
BOOST_CHECK(VerifyScript( | BOOST_CHECK(VerifyScript( | ||||
goodsig3, scriptPubKey23, flags, | goodsig3, scriptPubKey23, flags, | ||||
MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), | TransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), | ||||
&err)); | &err)); | ||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); | BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); | ||||
keys.clear(); | keys.clear(); | ||||
keys.push_back(key2); | keys.push_back(key2); | ||||
keys.push_back(key2); // Can't re-use sig | keys.push_back(key2); // Can't re-use sig | ||||
CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23); | CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23); | ||||
BOOST_CHECK(!VerifyScript( | BOOST_CHECK(!VerifyScript( | ||||
badsig1, scriptPubKey23, flags, | badsig1, scriptPubKey23, flags, | ||||
MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), | TransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), | ||||
&err)); | &err)); | ||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); | BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); | ||||
keys.clear(); | keys.clear(); | ||||
keys.push_back(key2); | keys.push_back(key2); | ||||
keys.push_back(key1); // sigs must be in correct order | keys.push_back(key1); // sigs must be in correct order | ||||
CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23); | CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23); | ||||
BOOST_CHECK(!VerifyScript( | BOOST_CHECK(!VerifyScript( | ||||
badsig2, scriptPubKey23, flags, | badsig2, scriptPubKey23, flags, | ||||
MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), | TransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), | ||||
&err)); | &err)); | ||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); | BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); | ||||
keys.clear(); | keys.clear(); | ||||
keys.push_back(key3); | keys.push_back(key3); | ||||
keys.push_back(key2); // sigs must be in correct order | keys.push_back(key2); // sigs must be in correct order | ||||
CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23); | CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23); | ||||
BOOST_CHECK(!VerifyScript( | BOOST_CHECK(!VerifyScript( | ||||
badsig3, scriptPubKey23, flags, | badsig3, scriptPubKey23, flags, | ||||
MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), | TransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), | ||||
&err)); | &err)); | ||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); | BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); | ||||
keys.clear(); | keys.clear(); | ||||
keys.push_back(key4); | keys.push_back(key4); | ||||
keys.push_back(key2); // sigs must match pubkeys | keys.push_back(key2); // sigs must match pubkeys | ||||
CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23); | CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23); | ||||
BOOST_CHECK(!VerifyScript( | BOOST_CHECK(!VerifyScript( | ||||
badsig4, scriptPubKey23, flags, | badsig4, scriptPubKey23, flags, | ||||
MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), | TransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), | ||||
&err)); | &err)); | ||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); | BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); | ||||
keys.clear(); | keys.clear(); | ||||
keys.push_back(key1); | keys.push_back(key1); | ||||
keys.push_back(key4); // sigs must match pubkeys | keys.push_back(key4); // sigs must match pubkeys | ||||
CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23); | CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23); | ||||
BOOST_CHECK(!VerifyScript( | BOOST_CHECK(!VerifyScript( | ||||
badsig5, scriptPubKey23, flags, | badsig5, scriptPubKey23, flags, | ||||
MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), | TransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), | ||||
&err)); | &err)); | ||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); | BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); | ||||
keys.clear(); // Must have signatures | keys.clear(); // Must have signatures | ||||
CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23); | CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23); | ||||
BOOST_CHECK(!VerifyScript( | BOOST_CHECK(!VerifyScript( | ||||
badsig6, scriptPubKey23, flags, | badsig6, scriptPubKey23, flags, | ||||
MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), | TransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), | ||||
&err)); | &err)); | ||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, | BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, | ||||
ScriptErrorString(err)); | ScriptErrorString(err)); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(script_combineSigs) { | BOOST_AUTO_TEST_CASE(script_combineSigs) { | ||||
// Test the CombineSignatures function | // Test the CombineSignatures function | ||||
Amount amount(0); | Amount amount(0); | ||||
Show All 9 Lines | BOOST_AUTO_TEST_CASE(script_combineSigs) { | ||||
} | } | ||||
CMutableTransaction txFrom = BuildCreditingTransaction( | CMutableTransaction txFrom = BuildCreditingTransaction( | ||||
GetScriptForDestination(keys[0].GetPubKey().GetID()), Amount(0)); | GetScriptForDestination(keys[0].GetPubKey().GetID()), Amount(0)); | ||||
CMutableTransaction txTo = BuildSpendingTransaction(CScript(), txFrom); | CMutableTransaction txTo = BuildSpendingTransaction(CScript(), txFrom); | ||||
CScript &scriptPubKey = txFrom.vout[0].scriptPubKey; | CScript &scriptPubKey = txFrom.vout[0].scriptPubKey; | ||||
CScript &scriptSig = txTo.vin[0].scriptSig; | CScript &scriptSig = txTo.vin[0].scriptSig; | ||||
// Although it looks like CMutableTransaction is not modified after it’s | |||||
// been set up (it is not passed as parameter to any non-const function), | |||||
// it is actually modified when new value is assigned to scriptPubKey, | |||||
// which points to mutableTxFrom.vout[0].scriptPubKey. Therefore we can | |||||
// not use single instance of CTransaction in this test. | |||||
// CTransaction creates a copy of CMutableTransaction and is not modified | |||||
// when scriptPubKey is assigned to. | |||||
SignatureData empty; | SignatureData empty; | ||||
SignatureData combined = CombineSignatures( | SignatureData combined = CombineSignatures( | ||||
scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | ||||
empty, empty); | empty, empty); | ||||
BOOST_CHECK(combined.scriptSig.empty()); | BOOST_CHECK(combined.scriptSig.empty()); | ||||
// Single signature case: | // Single signature case: | ||||
SignSignature(keystore, txFrom, txTo, 0, | SignSignature(keystore, CTransaction(txFrom), txTo, 0, | ||||
SigHashType()); // changes scriptSig | SigHashType()); // changes scriptSig | ||||
combined = CombineSignatures( | combined = CombineSignatures( | ||||
scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | ||||
SignatureData(scriptSig), empty); | SignatureData(scriptSig), empty); | ||||
BOOST_CHECK(combined.scriptSig == scriptSig); | BOOST_CHECK(combined.scriptSig == scriptSig); | ||||
combined = CombineSignatures( | combined = CombineSignatures( | ||||
scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | ||||
empty, SignatureData(scriptSig)); | empty, SignatureData(scriptSig)); | ||||
BOOST_CHECK(combined.scriptSig == scriptSig); | BOOST_CHECK(combined.scriptSig == scriptSig); | ||||
CScript scriptSigCopy = scriptSig; | CScript scriptSigCopy = scriptSig; | ||||
// Signing again will give a different, valid signature: | // Signing again will give a different, valid signature: | ||||
SignSignature(keystore, txFrom, txTo, 0, SigHashType()); | SignSignature(keystore, CTransaction(txFrom), txTo, 0, SigHashType()); | ||||
combined = CombineSignatures( | combined = CombineSignatures( | ||||
scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | ||||
SignatureData(scriptSigCopy), SignatureData(scriptSig)); | SignatureData(scriptSigCopy), SignatureData(scriptSig)); | ||||
BOOST_CHECK(combined.scriptSig == scriptSigCopy || | BOOST_CHECK(combined.scriptSig == scriptSigCopy || | ||||
combined.scriptSig == scriptSig); | combined.scriptSig == scriptSig); | ||||
// P2SH, single-signature case: | // P2SH, single-signature case: | ||||
CScript pkSingle; | CScript pkSingle; | ||||
pkSingle << ToByteVector(keys[0].GetPubKey()) << OP_CHECKSIG; | pkSingle << ToByteVector(keys[0].GetPubKey()) << OP_CHECKSIG; | ||||
keystore.AddCScript(pkSingle); | keystore.AddCScript(pkSingle); | ||||
scriptPubKey = GetScriptForDestination(CScriptID(pkSingle)); | scriptPubKey = GetScriptForDestination(CScriptID(pkSingle)); | ||||
SignSignature(keystore, txFrom, txTo, 0, SigHashType()); | SignSignature(keystore, CTransaction(txFrom), txTo, 0, SigHashType()); | ||||
combined = CombineSignatures( | combined = CombineSignatures( | ||||
scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | ||||
SignatureData(scriptSig), empty); | SignatureData(scriptSig), empty); | ||||
BOOST_CHECK(combined.scriptSig == scriptSig); | BOOST_CHECK(combined.scriptSig == scriptSig); | ||||
combined = CombineSignatures( | combined = CombineSignatures( | ||||
scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | ||||
empty, SignatureData(scriptSig)); | empty, SignatureData(scriptSig)); | ||||
BOOST_CHECK(combined.scriptSig == scriptSig); | BOOST_CHECK(combined.scriptSig == scriptSig); | ||||
scriptSigCopy = scriptSig; | scriptSigCopy = scriptSig; | ||||
SignSignature(keystore, txFrom, txTo, 0, SigHashType()); | SignSignature(keystore, CTransaction(txFrom), txTo, 0, SigHashType()); | ||||
combined = CombineSignatures( | combined = CombineSignatures( | ||||
scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | ||||
SignatureData(scriptSigCopy), SignatureData(scriptSig)); | SignatureData(scriptSigCopy), SignatureData(scriptSig)); | ||||
BOOST_CHECK(combined.scriptSig == scriptSigCopy || | BOOST_CHECK(combined.scriptSig == scriptSigCopy || | ||||
combined.scriptSig == scriptSig); | combined.scriptSig == scriptSig); | ||||
// dummy scriptSigCopy with placeholder, should always choose | // dummy scriptSigCopy with placeholder, should always choose | ||||
// non-placeholder: | // non-placeholder: | ||||
scriptSigCopy = CScript() << OP_0 << std::vector<uint8_t>(pkSingle.begin(), | scriptSigCopy = CScript() << OP_0 << std::vector<uint8_t>(pkSingle.begin(), | ||||
pkSingle.end()); | pkSingle.end()); | ||||
combined = CombineSignatures( | combined = CombineSignatures( | ||||
scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | ||||
SignatureData(scriptSigCopy), SignatureData(scriptSig)); | SignatureData(scriptSigCopy), SignatureData(scriptSig)); | ||||
BOOST_CHECK(combined.scriptSig == scriptSig); | BOOST_CHECK(combined.scriptSig == scriptSig); | ||||
combined = CombineSignatures( | combined = CombineSignatures( | ||||
scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | ||||
SignatureData(scriptSig), SignatureData(scriptSigCopy)); | SignatureData(scriptSig), SignatureData(scriptSigCopy)); | ||||
BOOST_CHECK(combined.scriptSig == scriptSig); | BOOST_CHECK(combined.scriptSig == scriptSig); | ||||
// Hardest case: Multisig 2-of-3 | // Hardest case: Multisig 2-of-3 | ||||
scriptPubKey = GetScriptForMultisig(2, pubkeys); | scriptPubKey = GetScriptForMultisig(2, pubkeys); | ||||
keystore.AddCScript(scriptPubKey); | keystore.AddCScript(scriptPubKey); | ||||
SignSignature(keystore, txFrom, txTo, 0, SigHashType()); | SignSignature(keystore, CTransaction(txFrom), txTo, 0, SigHashType()); | ||||
combined = CombineSignatures( | combined = CombineSignatures( | ||||
scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | ||||
SignatureData(scriptSig), empty); | SignatureData(scriptSig), empty); | ||||
BOOST_CHECK(combined.scriptSig == scriptSig); | BOOST_CHECK(combined.scriptSig == scriptSig); | ||||
combined = CombineSignatures( | combined = CombineSignatures( | ||||
scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), | ||||
empty, SignatureData(scriptSig)); | empty, SignatureData(scriptSig)); | ||||
BOOST_CHECK(combined.scriptSig == scriptSig); | BOOST_CHECK(combined.scriptSig == scriptSig); | ||||
// A couple of partially-signed versions: | // A couple of partially-signed versions: | ||||
std::vector<uint8_t> sig1; | std::vector<uint8_t> sig1; | ||||
uint256 hash1 = | uint256 hash1 = SignatureHash(scriptPubKey, CTransaction(txTo), 0, | ||||
SignatureHash(scriptPubKey, txTo, 0, SigHashType(), Amount(0)); | SigHashType(), Amount(0)); | ||||
BOOST_CHECK(keys[0].Sign(hash1, sig1)); | BOOST_CHECK(keys[0].Sign(hash1, sig1)); | ||||
sig1.push_back(SIGHASH_ALL); | sig1.push_back(SIGHASH_ALL); | ||||
std::vector<uint8_t> sig2; | std::vector<uint8_t> sig2; | ||||
uint256 hash2 = SignatureHash( | uint256 hash2 = SignatureHash( | ||||
scriptPubKey, txTo, 0, | scriptPubKey, CTransaction(txTo), 0, | ||||
SigHashType().withBaseSigHash(BaseSigHashType::NONE), Amount(0)); | SigHashType().withBaseSigHash(BaseSigHashType::NONE), Amount(0)); | ||||
BOOST_CHECK(keys[1].Sign(hash2, sig2)); | BOOST_CHECK(keys[1].Sign(hash2, sig2)); | ||||
sig2.push_back(SIGHASH_NONE); | sig2.push_back(SIGHASH_NONE); | ||||
std::vector<uint8_t> sig3; | std::vector<uint8_t> sig3; | ||||
uint256 hash3 = SignatureHash( | uint256 hash3 = SignatureHash( | ||||
scriptPubKey, txTo, 0, | scriptPubKey, CTransaction(txTo), 0, | ||||
SigHashType().withBaseSigHash(BaseSigHashType::SINGLE), Amount(0)); | SigHashType().withBaseSigHash(BaseSigHashType::SINGLE), Amount(0)); | ||||
BOOST_CHECK(keys[2].Sign(hash3, sig3)); | BOOST_CHECK(keys[2].Sign(hash3, sig3)); | ||||
sig3.push_back(SIGHASH_SINGLE); | sig3.push_back(SIGHASH_SINGLE); | ||||
// Not fussy about order (or even existence) of placeholders or signatures: | // Not fussy about order (or even existence) of placeholders or signatures: | ||||
CScript partial1a = CScript() << OP_0 << sig1 << OP_0; | CScript partial1a = CScript() << OP_0 << sig1 << OP_0; | ||||
CScript partial1b = CScript() << OP_0 << OP_0 << sig1; | CScript partial1b = CScript() << OP_0 << OP_0 << sig1; | ||||
CScript partial2a = CScript() << OP_0 << sig2; | CScript partial2a = CScript() << OP_0 << sig2; | ||||
▲ Show 20 Lines • Show All 326 Lines • Show Last 20 Lines |