Skip to content

Commit 314784a

Browse files
committed
Make listunspent and signrawtransaction RPCs support witnessScript
1 parent 0d1160e commit 314784a

File tree

2 files changed

+42
-7
lines changed

2 files changed

+42
-7
lines changed

src/rpc/rawtransaction.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -856,15 +856,25 @@ UniValue SignTransaction(interfaces::Chain& chain, CMutableTransaction& mtx, con
856856
RPCTypeCheckObj(prevOut,
857857
{
858858
{"redeemScript", UniValueType(UniValue::VSTR)},
859-
});
860-
UniValue v = find_value(prevOut, "redeemScript");
861-
if (!v.isNull()) {
862-
std::vector<unsigned char> rsData(ParseHexV(v, "redeemScript"));
859+
{"witnessScript", UniValueType(UniValue::VSTR)},
860+
}, true);
861+
UniValue rs = find_value(prevOut, "redeemScript");
862+
if (!rs.isNull()) {
863+
std::vector<unsigned char> rsData(ParseHexV(rs, "redeemScript"));
863864
CScript redeemScript(rsData.begin(), rsData.end());
864865
keystore->AddCScript(redeemScript);
865866
// Automatically also add the P2WSH wrapped version of the script (to deal with P2SH-P2WSH).
867+
// This is only for compatibility, it is encouraged to use the explicit witnessScript field instead.
866868
keystore->AddCScript(GetScriptForWitness(redeemScript));
867869
}
870+
UniValue ws = find_value(prevOut, "witnessScript");
871+
if (!ws.isNull()) {
872+
std::vector<unsigned char> wsData(ParseHexV(ws, "witnessScript"));
873+
CScript witnessScript(wsData.begin(), wsData.end());
874+
keystore->AddCScript(witnessScript);
875+
// Automatically also add the P2WSH wrapped version of the script (to deal with P2SH-P2WSH).
876+
keystore->AddCScript(GetScriptForWitness(witnessScript));
877+
}
868878
}
869879
}
870880
}
@@ -949,7 +959,8 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request)
949959
{"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
950960
{"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"},
951961
{"scriptPubKey", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "script key"},
952-
{"redeemScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2SH or P2WSH) redeem script"},
962+
{"redeemScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2SH) redeem script"},
963+
{"witnessScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2WSH or P2SH-P2WSH) witness script"},
953964
{"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "The amount spent"},
954965
},
955966
},

src/wallet/rpcwallet.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2768,7 +2768,8 @@ static UniValue listunspent(const JSONRPCRequest& request)
27682768
" \"scriptPubKey\" : \"key\", (string) the script key\n"
27692769
" \"amount\" : x.xxx, (numeric) the transaction output amount in " + CURRENCY_UNIT + "\n"
27702770
" \"confirmations\" : n, (numeric) The number of confirmations\n"
2771-
" \"redeemScript\" : n (string) The redeemScript if scriptPubKey is P2SH\n"
2771+
" \"redeemScript\" : \"script\" (string) The redeemScript if scriptPubKey is P2SH"
2772+
" \"witnessScript\" : \"script\" (string) witnessScript if the scriptPubKey is P2WSH or P2SH-P2WSH\n"
27722773
" \"spendable\" : xxx, (bool) Whether we have the private keys to spend this output\n"
27732774
" \"solvable\" : xxx, (bool) Whether we know how to spend this output, ignoring the lack of keys\n"
27742775
" \"desc\" : xxx, (string, only when solvable) A descriptor for spending this output\n"
@@ -2882,6 +2883,28 @@ static UniValue listunspent(const JSONRPCRequest& request)
28822883
CScript redeemScript;
28832884
if (pwallet->GetCScript(hash, redeemScript)) {
28842885
entry.pushKV("redeemScript", HexStr(redeemScript.begin(), redeemScript.end()));
2886+
// Now check if the redeemScript is actually a P2WSH script
2887+
CTxDestination witness_destination;
2888+
if (redeemScript.IsPayToWitnessScriptHash()) {
2889+
bool extracted = ExtractDestination(redeemScript, witness_destination);
2890+
assert(extracted);
2891+
// Also return the witness script
2892+
const WitnessV0ScriptHash& whash = boost::get<WitnessV0ScriptHash>(witness_destination);
2893+
CScriptID id;
2894+
CRIPEMD160().Write(whash.begin(), whash.size()).Finalize(id.begin());
2895+
CScript witnessScript;
2896+
if (pwallet->GetCScript(id, witnessScript)) {
2897+
entry.pushKV("witnessScript", HexStr(witnessScript.begin(), witnessScript.end()));
2898+
}
2899+
}
2900+
}
2901+
} else if (scriptPubKey.IsPayToWitnessScriptHash()) {
2902+
const WitnessV0ScriptHash& whash = boost::get<WitnessV0ScriptHash>(address);
2903+
CScriptID id;
2904+
CRIPEMD160().Write(whash.begin(), whash.size()).Finalize(id.begin());
2905+
CScript witnessScript;
2906+
if (pwallet->GetCScript(id, witnessScript)) {
2907+
entry.pushKV("witnessScript", HexStr(witnessScript.begin(), witnessScript.end()));
28852908
}
28862909
}
28872910
}
@@ -3137,7 +3160,8 @@ UniValue signrawtransactionwithwallet(const JSONRPCRequest& request)
31373160
{"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
31383161
{"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"},
31393162
{"scriptPubKey", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "script key"},
3140-
{"redeemScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2SH or P2WSH) redeem script"},
3163+
{"redeemScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2SH) redeem script"},
3164+
{"witnessScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2WSH or P2SH-P2WSH) witness script"},
31413165
{"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "The amount spent"},
31423166
},
31433167
},

0 commit comments

Comments
 (0)