added helper method, enabled signing
This commit is contained in:
parent
9149e371ed
commit
96fdb05689
3 changed files with 82 additions and 1 deletions
|
@ -80,6 +80,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
||||||
{ "scantxoutset", 1, "scanobjects" },
|
{ "scantxoutset", 1, "scanobjects" },
|
||||||
{ "addmultisigaddress", 0, "nrequired" },
|
{ "addmultisigaddress", 0, "nrequired" },
|
||||||
{ "addmultisigaddress", 1, "keys" },
|
{ "addmultisigaddress", 1, "keys" },
|
||||||
|
{ "addtimelockedaddress", 0, "timelock" },
|
||||||
{ "createmultisig", 0, "nrequired" },
|
{ "createmultisig", 0, "nrequired" },
|
||||||
{ "createmultisig", 1, "keys" },
|
{ "createmultisig", 1, "keys" },
|
||||||
{ "listunspent", 0, "minconf" },
|
{ "listunspent", 0, "minconf" },
|
||||||
|
|
|
@ -87,6 +87,21 @@ static bool CreateSig(const BaseSignatureCreator& creator, SignatureData& sigdat
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CScript StripTimelockPrefix(const CScript& script) {
|
||||||
|
auto it = script.begin();
|
||||||
|
opcodetype op;
|
||||||
|
if (!script.GetOp(it, op))
|
||||||
|
return script;
|
||||||
|
|
||||||
|
if (!script.GetOp(it, op) || (op != OP_CHECKLOCKTIMEVERIFY && op != OP_CHECKSEQUENCEVERIFY))
|
||||||
|
return script;
|
||||||
|
|
||||||
|
if (!script.GetOp(it, op) || op != OP_DROP)
|
||||||
|
return script;
|
||||||
|
|
||||||
|
return CScript(it, script.end());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sign scriptPubKey using signature made with creator.
|
* Sign scriptPubKey using signature made with creator.
|
||||||
* Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed),
|
* Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed),
|
||||||
|
@ -102,7 +117,9 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
|
||||||
std::vector<unsigned char> sig;
|
std::vector<unsigned char> sig;
|
||||||
|
|
||||||
std::vector<valtype> vSolutions;
|
std::vector<valtype> vSolutions;
|
||||||
if (!Solver(StripClaimScriptPrefix(scriptPubKey), whichTypeRet, vSolutions))
|
auto stripped = StripClaimScriptPrefix(scriptPubKey);
|
||||||
|
stripped = StripTimelockPrefix(stripped);
|
||||||
|
if (!Solver(stripped, whichTypeRet, vSolutions))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch (whichTypeRet)
|
switch (whichTypeRet)
|
||||||
|
|
|
@ -1914,6 +1914,68 @@ static UniValue addmultisigaddress(const JSONRPCRequest& request)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UniValue addtimelockedaddress(const JSONRPCRequest& request)
|
||||||
|
{
|
||||||
|
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
|
||||||
|
CWallet* const pwallet = wallet.get();
|
||||||
|
|
||||||
|
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
|
||||||
|
return NullUniValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.fHelp || request.params.size() < 2 || request.params.size() > 4) {
|
||||||
|
std::string msg = "addtimelockedaddress timelock address ( \"label\" \"address_type\" )\n"
|
||||||
|
"\nAdd an address that can't be redeemed until timelock. Requires a new wallet backup.\n"
|
||||||
|
"See `importaddress` for watchonly p2sh address support.\n"
|
||||||
|
"If 'label' is specified, assign address to that label.\n"
|
||||||
|
|
||||||
|
"\nArguments:\n"
|
||||||
|
"1. timelock (numeric, required) Block height if < 500 million or unix timestamp if greater.\n"
|
||||||
|
"1. \"address\" (string, required) The destination wallet address.\n"
|
||||||
|
"2. \"label\" (string, optional) A label to assign the addresses to.\n"
|
||||||
|
"3. \"address_type\" (string, optional) The address type to use. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\". Default is set by -addresstype.\n"
|
||||||
|
|
||||||
|
"\nResult:\n"
|
||||||
|
"{\n"
|
||||||
|
" \"address\":\"address\", (string) The value of the new P2SH address.\n"
|
||||||
|
" \"redeemScript\":\"script\" (string) The string value of the hex-encoded redemption script.\n"
|
||||||
|
"}\n"
|
||||||
|
;
|
||||||
|
throw std::runtime_error(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto timelock = request.params[0].get_int();
|
||||||
|
std::string label;
|
||||||
|
if (!request.params[2].isNull())
|
||||||
|
label = LabelFromValue(request.params[2]);
|
||||||
|
|
||||||
|
LOCK2(cs_main, pwallet->cs_wallet);
|
||||||
|
|
||||||
|
auto address = request.params[1].get_str();
|
||||||
|
CTxDestination destination = DecodeDestination(address);
|
||||||
|
if (!IsValidDestination(destination)) {
|
||||||
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid LBRY address: ") + address);
|
||||||
|
}
|
||||||
|
auto destinationScript = GetScriptForDestination(destination);
|
||||||
|
|
||||||
|
OutputType output_type = pwallet->m_default_address_type;
|
||||||
|
if (!request.params[3].isNull()) {
|
||||||
|
if (!ParseOutputType(request.params[3].get_str(), output_type)) {
|
||||||
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[3].get_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct using pay-to-script-hash:
|
||||||
|
CScript inner = (CScript() << CScriptNum(timelock) << OP_CHECKLOCKTIMEVERIFY << OP_DROP) + destinationScript;
|
||||||
|
CTxDestination dest = AddAndGetDestinationForScript(*pwallet, inner, output_type);
|
||||||
|
pwallet->SetAddressBook(dest, label, "timelock");
|
||||||
|
|
||||||
|
UniValue result(UniValue::VOBJ);
|
||||||
|
result.pushKV("address", EncodeDestination(dest));
|
||||||
|
result.pushKV("redeemScript", HexStr(inner.begin(), inner.end()));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
class Witnessifier : public boost::static_visitor<bool>
|
class Witnessifier : public boost::static_visitor<bool>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -5305,6 +5367,7 @@ static const CRPCCommand commands[] =
|
||||||
{ "wallet", "abandontransaction", &abandontransaction, {"txid"} },
|
{ "wallet", "abandontransaction", &abandontransaction, {"txid"} },
|
||||||
{ "wallet", "abortrescan", &abortrescan, {} },
|
{ "wallet", "abortrescan", &abortrescan, {} },
|
||||||
{ "wallet", "addmultisigaddress", &addmultisigaddress, {"nrequired","keys","label|account","address_type"} },
|
{ "wallet", "addmultisigaddress", &addmultisigaddress, {"nrequired","keys","label|account","address_type"} },
|
||||||
|
{ "wallet", "addtimelockedaddress", &addtimelockedaddress, {"timelock", "address", "label|account","address_type"} },
|
||||||
{ "hidden", "addwitnessaddress", &addwitnessaddress, {"address","p2sh"} },
|
{ "hidden", "addwitnessaddress", &addwitnessaddress, {"address","p2sh"} },
|
||||||
{ "wallet", "backupwallet", &backupwallet, {"destination"} },
|
{ "wallet", "backupwallet", &backupwallet, {"destination"} },
|
||||||
{ "wallet", "bumpfee", &bumpfee, {"txid", "options"} },
|
{ "wallet", "bumpfee", &bumpfee, {"txid", "options"} },
|
||||||
|
|
Loading…
Reference in a new issue