Browse Source

More work on using multiple shielded notes as inputs to a raw xtn

z_createrawtransaction
Jonathan "Duke" Leto 5 years ago
parent
commit
b337ad8d73
  1. 41
      src/wallet/rpcwallet.cpp

41
src/wallet/rpcwallet.cpp

@ -4550,6 +4550,7 @@ UniValue z_createrawtransaction(const UniValue& params, bool fHelp)
int nextBlockHeight = chainActive.Height() + 1;
TransactionBuilder builder = TransactionBuilder(Params().GetConsensus(), nextBlockHeight, pwalletMain);
builder.SetFee(minersFee);
// process inputs
for (const UniValue& input : inputs.getValues()) {
@ -4560,28 +4561,48 @@ UniValue z_createrawtransaction(const UniValue& params, bool fHelp)
const UniValue& amount = find_value(o, "amount");
int nOutindex = outindex.get_int();
int nAmount = amount.get_int();
int nOutput = vout_v.get_int();
if (!vout_v.isNum() && !outindex.isNum())
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid input, must provide either vout or outindex");
int nOutput = vout_v.get_int();
if (vout_v.isNum() && outindex.isNum())
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid input, cannot provide both vout and outindex");
// add input to transaction builder
if (nOutput) {
// transparent input
if (nOutput < 0)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
builder.AddTransparentInput(COutPoint(txid, nOutput), CScript(), nAmount);
} else {
} else if (nOutindex) {
// shielded input
if (nOutindex < 0)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, outindex must be positive");
// select sapling notes
// fetch anchor and witnesses
// Add Sapling spends
for (size_t i = 0; i < notes.size(); i++) {
if (!witnesses[i]) {
throw JSONRPCError(RPC_WALLET_ERROR, "Missing witness for Sapling note");
}
assert(builder.AddSaplingSpend(expsk, notes[i], anchor, witnesses[i].get()));
SaplingExpandedSpendingKey expsk;
uint256 ovk;
// TODO: look up fromAddress for (txid,outindex)
auto address = DecodePaymentAddress(fromAddress);
if (!boost::apply_visitor(HaveSpendingKeyForPaymentAddress(pwalletMain), address)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, no spending key found for zaddr");
}
spendingkey_ = boost::apply_visitor(GetSpendingKeyForPaymentAddress(pwalletMain), address).get();
auto sk = boost::get<libzcash::SaplingExtendedSpendingKey>(spendingkey_);
expsk = sk.expsk;
ovk = expsk.full_viewing_key().ovk;
// Fetch Sapling anchor and witnesses
uint256 anchor;
std::vector<boost::optional<SaplingWitness>> witnesses;
{
LOCK2(cs_main, pwalletMain->cs_wallet);
pwalletMain->GetSaplingNoteWitnesses(ops, witnesses, anchor);
}
assert(builder.AddSaplingSpend(expsk, notes[i], anchor, witnesses[i].get()));
}
}

Loading…
Cancel
Save