Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/core_io.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright (c) 2009-2019 The Bitcoin Core developers
// Copyright (c) 2019 The Veil developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand Down Expand Up @@ -36,6 +37,7 @@ std::string EncodeHexTx(const CTransaction& tx, const int serializeFlags = 0);
std::string SighashToStr(unsigned char sighash_type);
void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
void ScriptToUniv(const CScript& script, UniValue& out, bool include_address);
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, const std::vector<std::vector<COutPoint>>& vTxRingCtInputs, UniValue& entry, bool include_hex = true, int serialize_flags = 0);
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex = true, int serialize_flags = 0);
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, const std::vector<std::vector<std::pair<int64_t, COutPoint>>>& vTxRingCTInputs, bool include_hex = true, int serialize_flags = 0);

#endif // BITCOIN_CORE_IO_H
121 changes: 111 additions & 10 deletions src/core_write.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright (c) 2009-2019 The Bitcoin Core developers
// Copyright (c) 2019 The Veil developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand Down Expand Up @@ -189,11 +190,11 @@ void OutputToJSON(uint256 &txid, int i,
{
CTxOutCT *s = (CTxOutCT*) baseOut;
entry.pushKV("type", "blind");
entry.pushKV("valueCommitment", HexStr(&s->commitment.data[0], &s->commitment.data[0]+33));
entry.pushKV("ephemeral_pubkey", HexStr(s->vData.begin(), s->vData.end()));
UniValue o(UniValue::VOBJ);
ScriptPubKeyToUniv(s->scriptPubKey, o, true);
entry.pushKV("scriptPubKey", o);
entry.pushKV("data_hex", HexStr(s->vData.begin(), s->vData.end()));
entry.pushKV("valueCommitment", HexStr(&s->commitment.data[0], &s->commitment.data[0]+33));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will want to make 33 at const as some point?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a const for 33 is added as part of #696


AddRangeproof(s->vRangeproof, entry);
}
Expand All @@ -202,9 +203,9 @@ void OutputToJSON(uint256 &txid, int i,
{
CTxOutRingCT *s = (CTxOutRingCT*) baseOut;
entry.pushKV("type", "ringct");
entry.pushKV("ephemeral_pubkey", HexStr(s->vData.begin(), s->vData.end()));
entry.pushKV("pubkey", HexStr(s->pk.begin(), s->pk.end()));
entry.pushKV("valueCommitment", HexStr(&s->commitment.data[0], &s->commitment.data[0]+33));
entry.pushKV("data_hex", HexStr(s->vData.begin(), s->vData.end()));

AddRangeproof(s->vRangeproof, entry);
}
Expand Down Expand Up @@ -257,7 +258,9 @@ void ScriptPubKeyToUniv(const CScript& scriptPubKey,
out.pushKV("addresses", a);
}

void TxToUniv(const CTransaction& tx, const uint256& hashBlock, const std::vector<std::vector<COutPoint>>& vTxRingCtInputs, UniValue& entry, bool include_hex, int serialize_flags)
// TODO: Fix duplicate code. This was done as such to prevent veil-tx and some tests from failing to build.
// One requires core lib, the other doesn't.
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex, int serialize_flags)
{
entry.pushKV("txid", tx.GetHash().GetHex());
entry.pushKV("hash", tx.GetWitnessHash().GetHex());
Expand All @@ -275,19 +278,117 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, const std::vecto
in.pushKV("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
if (txin.IsAnonInput()) {
in.pushKV("type", "anon");
uint32_t nSigInputs, nSigRingSize;
txin.GetAnonInfo(nSigInputs, nSigRingSize);
in.pushKV("num_inputs", (int) nSigInputs);
in.pushKV("ring_size", (int) nSigRingSize);
in.pushKV("ringct_inputs", "To see the RingCT inputs, you must run the core library!");

const std::vector<uint8_t> vKeyImages = txin.scriptData.stack[0];
UniValue arrKeyImage(UniValue::VARR);
for (unsigned int k = 0; k < nSigInputs; k++) {
arrKeyImage.push_back(HexStr(&vKeyImages[k*33], &vKeyImages[(k*33)+33]));
}
in.pushKV("key_images", arrKeyImage);
} else {
in.pushKV("txid", txin.prevout.hash.GetHex());
if (txin.IsZerocoinSpend()) {
in.pushKV("type", "zerocoinspend");
in.pushKV("denomination", FormatMoney(txin.GetZerocoinSpent()));
std::vector<char, zero_after_free_allocator<char> > dataTxIn;
dataTxIn.insert(dataTxIn.end(), txin.scriptSig.begin() + 4, txin.scriptSig.end());
CDataStream serializedCoinSpend(dataTxIn, SER_NETWORK, PROTOCOL_VERSION);
libzerocoin::CoinSpend spend(Params().Zerocoin_Params(), serializedCoinSpend);
in.pushKV("serial", spend.getCoinSerialNumber().GetHex());
if (spend.getVersion() >= 4) {
in.pushKV("pubcoin", spend.getPubcoinValue().GetHex());
}
}
in.pushKV("vout", (int64_t)txin.prevout.n);
UniValue o(UniValue::VOBJ);
o.pushKV("asm", ScriptToAsmStr(txin.scriptSig, true));
o.pushKV("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
in.pushKV("scriptSig", o);
if (!tx.vin[i].scriptWitness.IsNull()) {
UniValue txinwitness(UniValue::VARR);
for (const auto& item : tx.vin[i].scriptWitness.stack) {
txinwitness.push_back(HexStr(item.begin(), item.end()));
}
in.pushKV("txinwitness", txinwitness);
}
}
in.pushKV("sequence", (int64_t)txin.nSequence);
vin.push_back(in);
}
entry.pushKV("vin", vin);

UniValue vout(UniValue::VARR);
auto txid = tx.GetHash();
for (unsigned int i = 0; i < tx.vpout.size(); i++) {
const auto& pout = tx.vpout[i];
UniValue out(UniValue::VOBJ);
OutputToJSON(txid, i, pout.get(), out, tx.IsCoinBase());
vout.push_back(out);
}

entry.pushKV("vout", vout);

if (!hashBlock.IsNull())
entry.pushKV("blockhash", hashBlock.GetHex());

if (include_hex) {
entry.pushKV("hex", EncodeHexTx(tx, serialize_flags)); // The hex-encoded transaction. Used the name "hex" to be consistent with the verbose output of "getrawtransaction".
}
}

void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, const std::vector<std::vector<std::pair<int64_t, COutPoint>>>& vTxRingCTInputs, bool include_hex, int serialize_flags) {
entry.pushKV("txid", tx.GetHash().GetHex());
entry.pushKV("hash", tx.GetWitnessHash().GetHex());
entry.pushKV("version", tx.nVersion);
entry.pushKV("size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION));
entry.pushKV("vsize", (GetTransactionWeight(tx) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR);
entry.pushKV("weight", GetTransactionWeight(tx));
entry.pushKV("locktime", (int64_t)tx.nLockTime);

// For tracking position in RingCT transactions. Its possible to have more than 1 RingCT inputs in a tx.
unsigned int j = 0;
unsigned int k = 0;
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.pushKV("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
if (txin.IsAnonInput()) {
in.pushKV("type", "ringct"); // FIXME: Should match the type from enum?

uint32_t nSigInputs, nSigRingSize;
txin.GetAnonInfo(nSigInputs, nSigRingSize);
in.pushKV("num_inputs", (int) nSigInputs);
in.pushKV("ring_size", (int) nSigRingSize);

//Add ring ct inputs
if (vTxRingCtInputs.size() > i) {
std::vector<COutPoint> vRingCtInputs = vTxRingCtInputs[i];
const std::vector<uint8_t> vCommitments = txin.scriptWitness.stack[1];
in.pushKV("commitment_sig", HexStr(&vCommitments[j], &vCommitments[j + 32]));

if (vTxRingCTInputs.size() > i) {
UniValue arrRing(UniValue::VARR);
for (const COutPoint& outpoint : vRingCtInputs) {
const std::vector<uint8_t> vKeyImages = txin.scriptData.stack[0];
for (k; k < nSigInputs; k++) {
UniValue obj(UniValue::VOBJ);
obj.pushKV("txid", outpoint.hash.GetHex());
obj.pushKV("vout.n", (uint64_t) outpoint.n);
obj.pushKV("key_image", HexStr(&vKeyImages[k*33], &vKeyImages[(k*33)+33]));

std::vector<std::pair<int64_t, COutPoint>> vRingCtInputs = vTxRingCTInputs[i];
obj.pushKV("txid", vRingCtInputs[k].second.hash.GetHex());
obj.pushKV("vout.n", (uint64_t) vRingCtInputs[k].second.n);
obj.pushKV("index", vRingCtInputs[k].first);

UniValue arrCommitment(UniValue::VARR);
for (unsigned int m = 0; m < (nSigRingSize); m++) {
j += 1;
arrCommitment.push_back(HexStr(&vCommitments[j*32], &vCommitments[(j*32)+32]));
}
obj.pushKV("commitments", arrCommitment);

arrRing.push_back(obj);
}
in.pushKV("ringct_inputs", arrRing);
Expand Down
3 changes: 2 additions & 1 deletion src/rest.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2019 The Bitcoin Core developers
// Copyright (c) 2019 The Veil developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand Down Expand Up @@ -380,7 +381,7 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart)

case RetFormat::JSON: {
UniValue objTx(UniValue::VOBJ);
TxToUniv(*tx, hashBlock, {{}}, objTx);
TxToUniv(*tx, hashBlock, objTx);
std::string strJSON = objTx.write() + "\n";
req->WriteHeader("Content-Type", "application/json");
req->WriteReply(HTTP_OK, strJSON);
Expand Down
6 changes: 3 additions & 3 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,9 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx
if(txDetails)
{
UniValue objTx(UniValue::VOBJ);
std::vector<std::vector<COutPoint> > vInputs;
GetRingCtInputs(tx->vin[0], vInputs);
TxToUniv(*tx, uint256(), vInputs, objTx, true, RPCSerializationFlags());
std::vector<std::vector<std::pair<int64_t, COutPoint>>> vTxRingCTInputs;
GetRingCtInputs(tx->vin[0], vTxRingCTInputs);
TxToUniv(*tx, uint256(), objTx, vTxRingCTInputs, true, RPCSerializationFlags());
txs.push_back(objTx);
}
else
Expand Down
17 changes: 10 additions & 7 deletions src/rpc/rawtransaction.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2019 The Bitcoin Core developers
// Copyright (c) 2019 The Veil developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand Down Expand Up @@ -40,14 +41,15 @@
#include <univalue.h>


static void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry, const std::vector<std::vector<COutPoint>>& vTxRingCtInputs)
static void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
{
// Call into TxToUniv() in bitcoin-common to decode the transaction hex.
//
// Blockchain contextual information (confirmations and blocktime) is not
// available to code in bitcoin-common, so we query them here and push the
// data into the returned UniValue.
TxToUniv(tx, uint256(), vTxRingCtInputs, entry, true, RPCSerializationFlags());
const std::vector<std::vector<std::pair<int64_t, COutPoint>>> &vTxRingCtInputs = GetTxRingCtInputs(tx);
TxToUniv(tx, uint256(), entry, vTxRingCtInputs, true, RPCSerializationFlags());

if (!hashBlock.IsNull()) {
LOCK(cs_main);
Expand Down Expand Up @@ -201,10 +203,9 @@ static UniValue getrawtransaction(const JSONRPCRequest& request)
}

//Get ringct inputs
std::vector<std::vector<COutPoint> > vTxRingCtInputs = GetTxRingCtInputs(tx);
UniValue result(UniValue::VOBJ);
if (blockindex) result.pushKV("in_active_chain", in_active_chain);
TxToJSON(*tx, hash_block, result, vTxRingCtInputs);
TxToJSON(*tx, hash_block, result);
return result;
}

Expand Down Expand Up @@ -581,7 +582,9 @@ static UniValue decoderawtransaction(const JSONRPCRequest& request)
}

UniValue result(UniValue::VOBJ);
TxToUniv(CTransaction(std::move(mtx)), uint256(), {{}}, result, false);
CTransaction tx = std::move(mtx);
std::vector<std::vector<std::pair<int64_t, COutPoint>>> vTxRingCtInputs = GetTxRingCtInputs(tx);
TxToUniv(tx, uint256(), result, vTxRingCtInputs, false);

return result;
}
Expand Down Expand Up @@ -1425,7 +1428,7 @@ UniValue decodepsbt(const JSONRPCRequest& request)

// Add the decoded tx
UniValue tx_univ(UniValue::VOBJ);
TxToUniv(CTransaction(*psbtx.tx), uint256(), {{}}, tx_univ, false);
TxToUniv(CTransaction(*psbtx.tx), uint256(), tx_univ, false);
result.pushKV("tx", tx_univ);

// Unknown data
Expand Down Expand Up @@ -1457,7 +1460,7 @@ UniValue decodepsbt(const JSONRPCRequest& request)
in.pushKV("witness_utxo", out);
} else if (input.non_witness_utxo) {
UniValue non_wit(UniValue::VOBJ);
TxToUniv(*input.non_witness_utxo, uint256(), {{}}, non_wit, false);
TxToUniv(*input.non_witness_utxo, uint256(), non_wit, false);
in.pushKV("non_witness_utxo", non_wit);
total_in += input.non_witness_utxo->vpout[psbtx.tx->vin[i].prevout.n]->GetValue();
} else {
Expand Down
3 changes: 2 additions & 1 deletion src/veil-tx.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright (c) 2009-2019 The Bitcoin Core developers
// Copyright (c) 2019 The Veil developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand Down Expand Up @@ -719,7 +720,7 @@ static void MutateTx(CMutableTransaction& tx, const std::string& command,
static void OutputTxJSON(const CTransaction& tx)
{
UniValue entry(UniValue::VOBJ);
TxToUniv(tx, uint256(), {{}}, entry);
TxToUniv(tx, uint256(), entry);

std::string jsonOutput = entry.write(4);
fprintf(stdout, "%s\n", jsonOutput.c_str());
Expand Down
Loading