/src/test/multisig_tests.cpp
https://github.com/superbitcoin/SuperBitcoin · C++ · 245 lines · 202 code · 37 blank · 6 comment · 27 complexity · 8c8d73b8faf61906e7f6926fbcb67bd5 MD5 · raw file
- // Copyright (c) 2011-2016 The Bitcoin Core developers
- // Distributed under the MIT software license, see the accompanying
- // file COPYING or http://www.opensource.org/licenses/mit-license.php.
- #include "wallet/key.h"
- #include "wallet/keystore.h"
- #include "sbtccore/transaction/policy.h"
- #include "script/script.h"
- #include "script/script_error.h"
- #include "script/interpreter.h"
- #include "script/sign.h"
- #include "script/ismine.h"
- #include "uint256.h"
- #include "test/test_bitcoin.h"
- #include <boost/test/unit_test.hpp>
- BOOST_FIXTURE_TEST_SUITE(multisig_tests, BasicTestingSetup)
- CScript
- sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transaction, int whichIn)
- {
- uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL, 0, SIGVERSION_BASE);
- CScript result;
- result << OP_0; // CHECKMULTISIG bug workaround
- for (const CKey &key : keys)
- {
- std::vector<unsigned char> vchSig;
- BOOST_CHECK(key.Sign(hash, vchSig));
- vchSig.push_back((unsigned char)SIGHASH_ALL);
- result << vchSig;
- }
- return result;
- }
- BOOST_AUTO_TEST_CASE(multisig_verify)
- {
- unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC;
- ScriptError err;
- CKey key[4];
- CAmount amount = 0;
- for (int i = 0; i < 4; i++)
- key[i].MakeNewKey(true);
- CScript a_and_b;
- a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2
- << OP_CHECKMULTISIG;
- CScript a_or_b;
- a_or_b << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2
- << OP_CHECKMULTISIG;
- CScript escrow;
- escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey())
- << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
- CMutableTransaction txFrom; // Funding transaction
- txFrom.vout.resize(3);
- txFrom.vout[0].scriptPubKey = a_and_b;
- txFrom.vout[1].scriptPubKey = a_or_b;
- txFrom.vout[2].scriptPubKey = escrow;
- CMutableTransaction txTo[3]; // Spending transaction
- for (int i = 0; i < 3; i++)
- {
- txTo[i].vin.resize(1);
- txTo[i].vout.resize(1);
- txTo[i].vin[0].prevout.n = i;
- txTo[i].vin[0].prevout.hash = txFrom.GetHash();
- txTo[i].vout[0].nValue = 1;
- }
- std::vector<CKey> keys;
- CScript s;
- // Test a AND b:
- keys.assign(1, key[0]);
- keys.push_back(key[1]);
- s = sign_multisig(a_and_b, keys, txTo[0], 0);
- BOOST_CHECK(VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount),
- &err));
- BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
- for (int i = 0; i < 4; i++)
- {
- keys.assign(1, key[i]);
- s = sign_multisig(a_and_b, keys, txTo[0], 0);
- BOOST_CHECK_MESSAGE(
- !VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount),
- &err), strprintf("a&b 1: %d", i));
- BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
- keys.assign(1, key[1]);
- keys.push_back(key[i]);
- s = sign_multisig(a_and_b, keys, txTo[0], 0);
- BOOST_CHECK_MESSAGE(
- !VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount),
- &err), strprintf("a&b 2: %d", i));
- BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
- }
- // Test a OR b:
- for (int i = 0; i < 4; i++)
- {
- keys.assign(1, key[i]);
- s = sign_multisig(a_or_b, keys, txTo[1], 0);
- if (i == 0 || i == 1)
- {
- BOOST_CHECK_MESSAGE(
- VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount),
- &err), strprintf("a|b: %d", i));
- BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
- } else
- {
- BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, nullptr, flags,
- MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err),
- strprintf("a|b: %d", i));
- BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
- }
- }
- s.clear();
- s << OP_0 << OP_1;
- BOOST_CHECK(!VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount),
- &err));
- BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err));
- for (int i = 0; i < 4; i++)
- for (int j = 0; j < 4; j++)
- {
- keys.assign(1, key[i]);
- keys.push_back(key[j]);
- s = sign_multisig(escrow, keys, txTo[2], 0);
- if (i < j && i < 3 && j < 3)
- {
- BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, nullptr, flags,
- MutableTransactionSignatureChecker(&txTo[2], 0, amount), &err),
- strprintf("escrow 1: %d %d", i, j));
- BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
- } else
- {
- BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, nullptr, flags,
- MutableTransactionSignatureChecker(&txTo[2], 0, amount), &err),
- strprintf("escrow 2: %d %d", i, j));
- BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
- }
- }
- }
- BOOST_AUTO_TEST_CASE(multisig_IsStandard)
- {
- CKey key[4];
- for (int i = 0; i < 4; i++)
- key[i].MakeNewKey(true);
- txnouttype whichType;
- CScript a_and_b;
- a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2
- << OP_CHECKMULTISIG;
- BOOST_CHECK(::IsStandard(a_and_b, whichType));
- CScript a_or_b;
- a_or_b << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2
- << OP_CHECKMULTISIG;
- BOOST_CHECK(::IsStandard(a_or_b, whichType));
- CScript escrow;
- escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey())
- << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
- BOOST_CHECK(::IsStandard(escrow, whichType));
- CScript one_of_four;
- one_of_four << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey())
- << ToByteVector(key[2].GetPubKey()) << ToByteVector(key[3].GetPubKey()) << OP_4 << OP_CHECKMULTISIG;
- BOOST_CHECK(!::IsStandard(one_of_four, whichType));
- CScript malformed[6];
- malformed[0] << OP_3 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2
- << OP_CHECKMULTISIG;
- malformed[1] << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_3
- << OP_CHECKMULTISIG;
- malformed[2] << OP_0 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2
- << OP_CHECKMULTISIG;
- malformed[3] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_0
- << OP_CHECKMULTISIG;
- malformed[4] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey())
- << OP_CHECKMULTISIG;
- malformed[5] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey());
- for (int i = 0; i < 6; i++)
- BOOST_CHECK(!::IsStandard(malformed[i], whichType));
- }
- BOOST_AUTO_TEST_CASE(multisig_Sign)
- {
- // Test SignSignature() (and therefore the version of Solver() that signs transactions)
- CBasicKeyStore keystore;
- CKey key[4];
- for (int i = 0; i < 4; i++)
- {
- key[i].MakeNewKey(true);
- keystore.AddKey(key[i]);
- }
- CScript a_and_b;
- a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2
- << OP_CHECKMULTISIG;
- CScript a_or_b;
- a_or_b << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2
- << OP_CHECKMULTISIG;
- CScript escrow;
- escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey())
- << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
- CMutableTransaction txFrom; // Funding transaction
- txFrom.vout.resize(3);
- txFrom.vout[0].scriptPubKey = a_and_b;
- txFrom.vout[1].scriptPubKey = a_or_b;
- txFrom.vout[2].scriptPubKey = escrow;
- CMutableTransaction txTo[3]; // Spending transaction
- for (int i = 0; i < 3; i++)
- {
- txTo[i].vin.resize(1);
- txTo[i].vout.resize(1);
- txTo[i].vin[0].prevout.n = i;
- txTo[i].vin[0].prevout.hash = txFrom.GetHash();
- txTo[i].vout[0].nValue = 1;
- }
- for (int i = 0; i < 3; i++)
- {
- BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0, SIGHASH_ALL | SIGHASH_SBTC_FORK),
- strprintf("SignSignature %d", i));
- }
- }
- BOOST_AUTO_TEST_SUITE_END()