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.
501{RPCResult::Type::STR, "p2sh-segwit", "address of the P2SH script wrapping this witness redeem script"},502}},503},504},505RPCExamples{506HelpExampleCli("decodescript", "\"hexstring\"")507+ HelpExampleRpc("decodescript", "\"hexstring\"")508},509[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue510{511UniValue r(UniValue::VOBJ);512CScript script;513if (request.params[0].get_str().size() > 0){514std::vector<unsigned char> scriptData(ParseHexV(request.params[0], "argument"));515script = CScript(scriptData.begin(), scriptData.end());516} else {517// Empty scripts are valid518}519ScriptToUniv(script, /*out=*/r, /*include_hex=*/false, /*include_address=*/true);521std::vector<std::vector<unsigned char>> solutions_data;522const TxoutType which_type{Solver(script, solutions_data)};524const bool can_wrap{[&] {525switch (which_type) {526case TxoutType::MULTISIG:527case TxoutType::NONSTANDARD:528case TxoutType::PUBKEY:529case TxoutType::PUBKEYHASH:530case TxoutType::WITNESS_V0_KEYHASH:531case TxoutType::WITNESS_V0_SCRIPTHASH:532// Can be wrapped if the checks below pass533break;534case TxoutType::NULL_DATA:535case TxoutType::SCRIPTHASH:536case TxoutType::WITNESS_UNKNOWN:537case TxoutType::WITNESS_V1_TAPROOT:538case TxoutType::ANCHOR:539// Should not be wrapped540return false;541} // no default case, so the compiler can warn about missing cases542if (!script.HasValidOps() || script.IsUnspendable()) {543return false;544}545for (CScript::const_iterator it{script.begin()}; it != script.end();) {546opcodetype op;547CHECK_NONFATAL(script.GetOp(it, op));548if (op == OP_CHECKSIGADD || IsOpSuccess(op)) {549return false;550}551}552return true;553}()};555if (can_wrap) {556r.pushKV("p2sh", EncodeDestination(ScriptHash(script)));557// P2SH and witness programs cannot be wrapped in P2WSH, if this script558// is a witness program, don't return addresses for a segwit programs.559const bool can_wrap_P2WSH{[&] {560switch (which_type) {561case TxoutType::MULTISIG:562case TxoutType::PUBKEY:563// Uncompressed pubkeys cannot be used with segwit checksigs.564// If the script contains an uncompressed pubkey, skip encoding of a segwit program.565for (const auto& solution : solutions_data) {566if ((solution.size() != 1) && !CPubKey(solution).IsCompressed()) {567return false;568}569}570return true;571case TxoutType::NONSTANDARD:572case TxoutType::PUBKEYHASH:573// Can be P2WSH wrapped574return true;575case TxoutType::NULL_DATA:576case TxoutType::SCRIPTHASH:577case TxoutType::WITNESS_UNKNOWN:578case TxoutType::WITNESS_V0_KEYHASH:579case TxoutType::WITNESS_V0_SCRIPTHASH:580case TxoutType::WITNESS_V1_TAPROOT:581case TxoutType::ANCHOR:582// Should not be wrapped583return false;584} // no default case, so the compiler can warn about missing cases585NONFATAL_UNREACHABLE();586}()};587if (can_wrap_P2WSH) {588UniValue sr(UniValue::VOBJ);589CScript segwitScr;590FlatSigningProvider provider;591if (which_type == TxoutType::PUBKEY) {592segwitScr = GetScriptForDestination(WitnessV0KeyHash(Hash160(solutions_data[0])));593} else if (which_type == TxoutType::PUBKEYHASH) {594segwitScr = GetScriptForDestination(WitnessV0KeyHash(uint160{solutions_data[0]}));595} else {596// Scripts that are not fit for P2WPKH are encoded as P2WSH.597provider.scripts[CScriptID(script)] = script;598segwitScr = GetScriptForDestination(WitnessV0ScriptHash(script));599}600ScriptToUniv(segwitScr, /*out=*/sr, /*include_hex=*/true, /*include_address=*/true, /*provider=*/&provider);601sr.pushKV("p2sh-segwit", EncodeDestination(ScriptHash(segwitScr)));602r.pushKV("segwit", std::move(sr));603}604}606return r;607},608};609}611static RPCMethod combinerawtransaction()612{613return RPCMethod{614"combinerawtransaction",615"Combine multiple partially signed transactions into one transaction.\n"616"The combined transaction may be another partially signed transaction or a \n"617"fully signed transaction.",618{619{"txs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The hex strings of partially signed transactions",620{621{"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "A hex-encoded raw transaction"},622},623},624},625RPCResult{626RPCResult::Type::STR, "", "The hex-encoded raw transaction with signature(s)"627},628RPCExamples{629HelpExampleCli("combinerawtransaction", R"('["myhex1", "myhex2", "myhex3"]')")630},631[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue632{634UniValue txs = request.params[0].get_array();636// Can't merge < 2 items637if (txs.size() < 2) {638throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transactions. At least two transactions required.");639}641std::vector<CMutableTransaction> txVariants(txs.size());643for (unsigned int idx = 0; idx < txs.size(); idx++) {644if (!DecodeHexTx(txVariants[idx], txs[idx].get_str())) {645throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed for tx %d. Make sure the tx has at least one input.", idx));646}647}649{ // Test Tx relation for mergeability. Strip scriptSigs and scriptWitnesses to facilitate txId comparison650std::vector<CMutableTransaction> tx_variants_copy(txVariants);651Txid first_txid{};652for (unsigned int k{0}; k < tx_variants_copy.size(); ++k) {653// Remove all scriptSigs and scriptWitnesses from inputs654for (CTxIn& input : tx_variants_copy[k].vin) {655input.scriptSig.clear();656input.scriptWitness.SetNull();657}658if (k == 0) {659first_txid = tx_variants_copy[k].GetHash();660} else if (first_txid != tx_variants_copy[k].GetHash()) {661throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Transaction number %d not compatible with first transaction", k+1));662}663}664}666// mergedTx will end up with all the signatures; it667// starts as a clone of the rawtx:668CMutableTransaction mergedTx(txVariants[0]);670// Fetch previous transactions (inputs):671CCoinsViewCache view{&CoinsViewEmpty::Get()};672{673NodeContext& node = EnsureAnyNodeContext(request.context);674const CTxMemPool& mempool = EnsureMemPool(node);675ChainstateManager& chainman = EnsureChainman(node);676LOCK2(cs_main, mempool.cs);677CCoinsViewCache &viewChain = chainman.ActiveChainstate().CoinsTip();678CCoinsViewMemPool viewMempool(&viewChain, mempool);679view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view681for (const CTxIn& txin : mergedTx.vin) {682view.AccessCoin(txin.prevout); // Load entries from viewChain into view; can fail.683}685view.SetBackend(CoinsViewEmpty::Get()); // switch back to avoid locking mempool for too long686}688// Use CTransaction for the constant parts of the689// transaction to avoid rehashing.690const CTransaction txConst(mergedTx);691// Sign what we can:692for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {693CTxIn& txin = mergedTx.vin[i];694const Coin& coin = view.AccessCoin(txin.prevout);695if (coin.IsSpent()) {696throw JSONRPCError(RPC_VERIFY_ERROR, "Input not found or already spent");697}698SignatureData sigdata;700// ... and merge in other signatures:701for (const CMutableTransaction& txv : txVariants) {702if (txv.vin.size() > i) {703sigdata.MergeSignatureData(DataFromTransaction(txv, i, coin.out));704}705}706ProduceSignature(DUMMY_SIGNING_PROVIDER, MutableTransactionSignatureCreator(mergedTx, i, coin.out.nValue, {.sighash_type = SIGHASH_ALL}), coin.out.scriptPubKey, sigdata);708UpdateInput(txin, sigdata);709}711return EncodeHexTx(CTransaction(mergedTx));712},713};714}716static RPCMethod signrawtransactionwithkey()717{718return RPCMethod{719"signrawtransactionwithkey",720"Sign inputs for raw transaction (serialized, hex-encoded).\n"721"The second argument is an array of base58-encoded private\n"722"keys that will be the only keys used to sign the transaction.\n"723"The third optional argument (may be null) is an array of previous transaction outputs that\n"724"this transaction depends on but may not yet be in the block chain.\n",725{726{"hexstring", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction hex string"},727{"privkeys", RPCArg::Type::ARR, RPCArg::Optional::NO, "The base58-encoded private keys for signing",728{729{"privatekey", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "private key in base58-encoding"},730},731},732{"prevtxs", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "The previous dependent transaction outputs",733{734{"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "",735{736{"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},737{"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"},738{"scriptPubKey", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "output script"},739{"redeemScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2SH) redeem script"},740{"witnessScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2WSH or P2SH-P2WSH) witness script"},741{"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::OMITTED, "(required for Segwit inputs) the amount spent"},742},743},744},745},746{"sighashtype", RPCArg::Type::STR, RPCArg::DefaultHint{"DEFAULT for Taproot, ALL otherwise"}, "The signature hash type. Must be one of:\n"747" \"DEFAULT\"\n"748" \"ALL\"\n"749" \"NONE\"\n"750" \"SINGLE\"\n"