|
|
@ -34,77 +34,15 @@ |
|
|
|
|
|
|
|
|
|
|
|
#include <univalue.h> |
|
|
|
#include <univalue.h> |
|
|
|
|
|
|
|
|
|
|
|
void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
txnouttype type; |
|
|
|
|
|
|
|
std::vector<CTxDestination> addresses; |
|
|
|
|
|
|
|
int nRequired; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
out.push_back(Pair("asm", ScriptToAsmStr(scriptPubKey))); |
|
|
|
|
|
|
|
if (fIncludeHex) |
|
|
|
|
|
|
|
out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end()))); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) { |
|
|
|
|
|
|
|
out.push_back(Pair("type", GetTxnOutputType(type))); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
out.push_back(Pair("reqSigs", nRequired)); |
|
|
|
|
|
|
|
out.push_back(Pair("type", GetTxnOutputType(type))); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
UniValue a(UniValue::VARR); |
|
|
|
|
|
|
|
BOOST_FOREACH(const CTxDestination& addr, addresses) |
|
|
|
|
|
|
|
a.push_back(CBitcoinAddress(addr).ToString()); |
|
|
|
|
|
|
|
out.push_back(Pair("addresses", a)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) |
|
|
|
void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) |
|
|
|
{ |
|
|
|
{ |
|
|
|
entry.push_back(Pair("txid", tx.GetHash().GetHex())); |
|
|
|
// Call into TxToUniv() in bitcoin-common to decode the transaction hex.
|
|
|
|
entry.push_back(Pair("hash", tx.GetWitnessHash().GetHex())); |
|
|
|
//
|
|
|
|
entry.push_back(Pair("size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION))); |
|
|
|
// Blockchain contextual information (confirmations and blocktime) is not
|
|
|
|
entry.push_back(Pair("vsize", (int)::GetVirtualTransactionSize(tx))); |
|
|
|
// available to code in bitcoin-common, so we query them here and push the
|
|
|
|
entry.push_back(Pair("version", tx.nVersion)); |
|
|
|
// data into the returned UniValue.
|
|
|
|
entry.push_back(Pair("locktime", (int64_t)tx.nLockTime)); |
|
|
|
TxToUniv(tx, uint256(), entry); |
|
|
|
|
|
|
|
|
|
|
|
UniValue vin(UniValue::VARR); |
|
|
|
|
|
|
|
for (unsigned int i = 0; i < tx.vin.size(); i++) { |
|
|
|
|
|
|
|
const CTxIn& txin = tx.vin[i]; |
|
|
|
|
|
|
|
UniValue in(UniValue::VOBJ); |
|
|
|
|
|
|
|
if (tx.IsCoinBase()) |
|
|
|
|
|
|
|
in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
in.push_back(Pair("txid", txin.prevout.hash.GetHex())); |
|
|
|
|
|
|
|
in.push_back(Pair("vout", (int64_t)txin.prevout.n)); |
|
|
|
|
|
|
|
UniValue o(UniValue::VOBJ); |
|
|
|
|
|
|
|
o.push_back(Pair("asm", ScriptToAsmStr(txin.scriptSig, true))); |
|
|
|
|
|
|
|
o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); |
|
|
|
|
|
|
|
in.push_back(Pair("scriptSig", o)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (tx.HasWitness()) { |
|
|
|
|
|
|
|
UniValue txinwitness(UniValue::VARR); |
|
|
|
|
|
|
|
for (unsigned int j = 0; j < tx.vin[i].scriptWitness.stack.size(); j++) { |
|
|
|
|
|
|
|
std::vector<unsigned char> item = tx.vin[i].scriptWitness.stack[j]; |
|
|
|
|
|
|
|
txinwitness.push_back(HexStr(item.begin(), item.end())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
in.push_back(Pair("txinwitness", txinwitness)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
in.push_back(Pair("sequence", (int64_t)txin.nSequence)); |
|
|
|
|
|
|
|
vin.push_back(in); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
entry.push_back(Pair("vin", vin)); |
|
|
|
|
|
|
|
UniValue vout(UniValue::VARR); |
|
|
|
|
|
|
|
for (unsigned int i = 0; i < tx.vout.size(); i++) { |
|
|
|
|
|
|
|
const CTxOut& txout = tx.vout[i]; |
|
|
|
|
|
|
|
UniValue out(UniValue::VOBJ); |
|
|
|
|
|
|
|
out.push_back(Pair("value", ValueFromAmount(txout.nValue))); |
|
|
|
|
|
|
|
out.push_back(Pair("n", (int64_t)i)); |
|
|
|
|
|
|
|
UniValue o(UniValue::VOBJ); |
|
|
|
|
|
|
|
ScriptPubKeyToJSON(txout.scriptPubKey, o, true); |
|
|
|
|
|
|
|
out.push_back(Pair("scriptPubKey", o)); |
|
|
|
|
|
|
|
vout.push_back(out); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
entry.push_back(Pair("vout", vout)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!hashBlock.IsNull()) { |
|
|
|
if (!hashBlock.IsNull()) { |
|
|
|
entry.push_back(Pair("blockhash", hashBlock.GetHex())); |
|
|
|
entry.push_back(Pair("blockhash", hashBlock.GetHex())); |
|
|
@ -525,7 +463,7 @@ UniValue decoderawtransaction(const JSONRPCRequest& request) |
|
|
|
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); |
|
|
|
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); |
|
|
|
|
|
|
|
|
|
|
|
UniValue result(UniValue::VOBJ); |
|
|
|
UniValue result(UniValue::VOBJ); |
|
|
|
TxToJSON(CTransaction(std::move(mtx)), uint256(), result); |
|
|
|
TxToUniv(CTransaction(std::move(mtx)), uint256(), result); |
|
|
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
return result; |
|
|
|
} |
|
|
|
} |
|
|
@ -565,7 +503,7 @@ UniValue decodescript(const JSONRPCRequest& request) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// Empty scripts are valid
|
|
|
|
// Empty scripts are valid
|
|
|
|
} |
|
|
|
} |
|
|
|
ScriptPubKeyToJSON(script, r, false); |
|
|
|
ScriptPubKeyToUniv(script, r, false); |
|
|
|
|
|
|
|
|
|
|
|
UniValue type; |
|
|
|
UniValue type; |
|
|
|
type = find_value(r, "type"); |
|
|
|
type = find_value(r, "type"); |
|
|
|