Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2017-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#include <addresstype.h>6#include <key.h>7#include <key_io.h>8#include <script/script.h>9#include <script/signingprovider.h>10#include <script/solver.h>11#include <test/data/bip341_wallet_vectors.json.h>12#include <test/util/common.h>13#include <test/util/setup_common.h>14#include <univalue.h>15#include <util/check.h>16#include <util/strencodings.h>18#include <boost/test/unit_test.hpp>20using namespace util::hex_literals;22BOOST_FIXTURE_TEST_SUITE(script_standard_tests, BasicTestingSetup)24BOOST_AUTO_TEST_CASE(dest_default_is_no_dest)25{26CTxDestination dest;27BOOST_CHECK(!IsValidDestination(dest));28}30BOOST_AUTO_TEST_CASE(script_standard_Solver_success)31{32CKey keys[3];33CPubKey pubkeys[3];34for (int i = 0; i < 3; i++) {35keys[i].MakeNewKey(true);36pubkeys[i] = keys[i].GetPubKey();37}39CScript s;40std::vector<std::vector<unsigned char> > solutions;42// TxoutType::PUBKEY43s.clear();44s << ToByteVector(pubkeys[0]) << OP_CHECKSIG;45BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::PUBKEY);46BOOST_CHECK_EQUAL(solutions.size(), 1U);47BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0]));49// TxoutType::PUBKEYHASH50s.clear();51s << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;52BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::PUBKEYHASH);53BOOST_CHECK_EQUAL(solutions.size(), 1U);54BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0].GetID()));56// TxoutType::SCRIPTHASH57CScript redeemScript(s); // initialize with leftover P2PKH script58s.clear();59s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;60BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::SCRIPTHASH);61BOOST_CHECK_EQUAL(solutions.size(), 1U);62BOOST_CHECK(solutions[0] == ToByteVector(CScriptID(redeemScript)));64// TxoutType::MULTISIG65s.clear();66s << OP_1 <<67ToByteVector(pubkeys[0]) <<68ToByteVector(pubkeys[1]) <<69OP_2 << OP_CHECKMULTISIG;70BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::MULTISIG);71BOOST_CHECK_EQUAL(solutions.size(), 4U);72BOOST_CHECK(solutions[0] == std::vector<unsigned char>({1}));73BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0]));74BOOST_CHECK(solutions[2] == ToByteVector(pubkeys[1]));75BOOST_CHECK(solutions[3] == std::vector<unsigned char>({2}));77s.clear();78s << OP_2 <<79ToByteVector(pubkeys[0]) <<80ToByteVector(pubkeys[1]) <<81ToByteVector(pubkeys[2]) <<82OP_3 << OP_CHECKMULTISIG;83BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::MULTISIG);84BOOST_CHECK_EQUAL(solutions.size(), 5U);85BOOST_CHECK(solutions[0] == std::vector<unsigned char>({2}));86BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0]));87BOOST_CHECK(solutions[2] == ToByteVector(pubkeys[1]));88BOOST_CHECK(solutions[3] == ToByteVector(pubkeys[2]));89BOOST_CHECK(solutions[4] == std::vector<unsigned char>({3}));91// TxoutType::NULL_DATA92s.clear();93s << OP_RETURN <<94std::vector<unsigned char>({0}) <<95std::vector<unsigned char>({75}) <<96std::vector<unsigned char>({255});97BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NULL_DATA);98BOOST_CHECK_EQUAL(solutions.size(), 0U);100// TxoutType::WITNESS_V0_KEYHASH101s.clear();102s << OP_0 << ToByteVector(pubkeys[0].GetID());103BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::WITNESS_V0_KEYHASH);104BOOST_CHECK_EQUAL(solutions.size(), 1U);105BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0].GetID()));107// TxoutType::WITNESS_V0_SCRIPTHASH108uint256 scriptHash;109CSHA256().Write(redeemScript.data(), redeemScript.size())110.Finalize(scriptHash.begin());112s.clear();113s << OP_0 << ToByteVector(scriptHash);114BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::WITNESS_V0_SCRIPTHASH);115BOOST_CHECK_EQUAL(solutions.size(), 1U);116BOOST_CHECK(solutions[0] == ToByteVector(scriptHash));118// TxoutType::WITNESS_V1_TAPROOT119s.clear();120s << OP_1 << ToByteVector(uint256::ZERO);121BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::WITNESS_V1_TAPROOT);122BOOST_CHECK_EQUAL(solutions.size(), 1U);123BOOST_CHECK(solutions[0] == ToByteVector(uint256::ZERO));125// TxoutType::WITNESS_UNKNOWN126s.clear();127s << OP_16 << ToByteVector(uint256::ONE);128BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::WITNESS_UNKNOWN);129BOOST_CHECK_EQUAL(solutions.size(), 2U);130BOOST_CHECK(solutions[0] == std::vector<unsigned char>{16});131BOOST_CHECK(solutions[1] == ToByteVector(uint256::ONE));133// TxoutType::ANCHOR134s.clear();135s << OP_1 << ANCHOR_BYTES;136BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::ANCHOR);137BOOST_CHECK(solutions.empty());139// Sanity-check IsPayToAnchor140int version{-1};141std::vector<unsigned char> witness_program;142BOOST_CHECK(s.IsPayToAnchor());143BOOST_CHECK(s.IsWitnessProgram(version, witness_program));144BOOST_CHECK(CScript::IsPayToAnchor(version, witness_program));146// TxoutType::NONSTANDARD147s.clear();148s << OP_9 << OP_ADD << OP_11 << OP_EQUAL;149BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);150}152BOOST_AUTO_TEST_CASE(script_standard_Solver_failure)153{154CKey key = GenerateRandomKey();155CPubKey pubkey = key.GetPubKey();157CScript s;158std::vector<std::vector<unsigned char> > solutions;160// TxoutType::PUBKEY with incorrectly sized pubkey161s.clear();162s << std::vector<unsigned char>(30, 0x01) << OP_CHECKSIG;163BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);165// TxoutType::PUBKEYHASH with incorrectly sized key hash166s.clear();167s << OP_DUP << OP_HASH160 << ToByteVector(pubkey) << OP_EQUALVERIFY << OP_CHECKSIG;168BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);170// TxoutType::SCRIPTHASH with incorrectly sized script hash171s.clear();172s << OP_HASH160 << std::vector<unsigned char>(21, 0x01) << OP_EQUAL;173BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);175// TxoutType::MULTISIG 0/2176s.clear();177s << OP_0 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;178BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);180// TxoutType::MULTISIG 2/1181s.clear();182s << OP_2 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;183BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);185// TxoutType::MULTISIG n = 2 with 1 pubkey186s.clear();187s << OP_1 << ToByteVector(pubkey) << OP_2 << OP_CHECKMULTISIG;188BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);190// TxoutType::MULTISIG n = 1 with 0 pubkeys191s.clear();192s << OP_1 << OP_1 << OP_CHECKMULTISIG;193BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);195// TxoutType::NULL_DATA with other opcodes196s.clear();197s << OP_RETURN << std::vector<unsigned char>({75}) << OP_ADD;198BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);200// TxoutType::WITNESS_V0_{KEY,SCRIPT}HASH with incorrect program size (-> consensus-invalid, i.e. non-standard)201s.clear();202s << OP_0 << std::vector<unsigned char>(19, 0x01);203BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);205// TxoutType::WITNESS_V1_TAPROOT with incorrect program size (-> undefined, but still policy-valid)206s.clear();207s << OP_1 << std::vector<unsigned char>(31, 0x01);208BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::WITNESS_UNKNOWN);209s.clear();210s << OP_1 << std::vector<unsigned char>(33, 0x01);211BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::WITNESS_UNKNOWN);213// TxoutType::ANCHOR but wrong witness version214s.clear();215s << OP_2 << ANCHOR_BYTES;216BOOST_CHECK(!s.IsPayToAnchor());217BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::WITNESS_UNKNOWN);219// TxoutType::ANCHOR but wrong 2-byte data push220s.clear();221s << OP_1 << std::vector<unsigned char>{0xff, 0xff};222BOOST_CHECK(!s.IsPayToAnchor());223BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::WITNESS_UNKNOWN);224}226BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)227{228CKey key = GenerateRandomKey();229CPubKey pubkey = key.GetPubKey();231CScript s;232CTxDestination address;234// TxoutType::PUBKEY235s.clear();236s << ToByteVector(pubkey) << OP_CHECKSIG;237BOOST_CHECK(!ExtractDestination(s, address));238BOOST_CHECK(std::get<PubKeyDestination>(address) == PubKeyDestination(pubkey));240// TxoutType::PUBKEYHASH241s.clear();242s << OP_DUP << OP_HASH160 << ToByteVector(pubkey.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;243BOOST_CHECK(ExtractDestination(s, address));244BOOST_CHECK(std::get<PKHash>(address) == PKHash(pubkey));246// TxoutType::SCRIPTHASH247CScript redeemScript(s); // initialize with leftover P2PKH script248s.clear();249s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;250BOOST_CHECK(ExtractDestination(s, address));
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.