11 #include "ui_blockexplorer.h"
17 #include <QMessageBox>
22 inline std::string
utostr(
unsigned int n)
27 static std::string makeHRef(
const std::string& Str)
29 return "<a href=\"" + Str +
"\">" + Str +
"</a>";
38 for (
unsigned int i = 0; i < tx.
vin.size(); i++)
43 static std::string ValueToString(
CAmount nValue,
bool AllowNegative =
false)
45 if (nValue < 0 && !AllowNegative)
46 return "<span>" +
_(
"unknown") +
"</span>";
49 if (AllowNegative && nValue > 0)
51 return std::string(
"<span>") + Str.toUtf8().data() +
"</span>";
54 static std::string ScriptToString(
const CScript& Script,
bool Long =
false,
bool Highlight =
false)
63 return "<span class=\"addr\">" + Address.
ToString() +
"</span>";
67 return Long ?
"<pre>" +
FormatScript(Script) +
"</pre>" :
_(
"Non-standard script");
70 static std::string TimeToString(uint64_t Time)
73 timestamp.setTime_t(Time);
74 return timestamp.toString(
"yyyy-MM-dd hh:mm:ss").toUtf8().data();
77 static std::string makeHTMLTableRow(
const std::string* pCells,
int n)
79 std::string Result =
"<tr>";
80 for (
int i = 0; i < n; i++) {
81 Result +=
"<td class=\"d" +
utostr(i) +
"\">";
89 static const char* table =
"<table>";
91 static std::string makeHTMLTable(
const std::string* pCells,
int nRows,
int nColumns)
93 std::string Table = table;
94 for (
int i = 0; i < nRows; i++)
95 Table += makeHTMLTableRow(pCells + i * nColumns, nColumns);
100 static std::string TxToRow(
const CTransaction& tx,
const CScript& Highlight =
CScript(),
const std::string& Prepend = std::string(), int64_t* pSum = NULL)
102 std::string InAmounts, InAddresses, OutAmounts, OutAddresses;
104 for (
unsigned int j = 0; j < tx.
vin.size(); j++) {
107 InAddresses +=
"coinbase";
110 InAmounts += ValueToString(PrevOut.
nValue);
115 if (j + 1 != tx.
vin.size()) {
116 InAmounts +=
"<br/>";
117 InAddresses +=
"<br/>";
120 for (
unsigned int j = 0; j < tx.
vout.size(); j++) {
122 OutAmounts += ValueToString(Out.
nValue);
126 if (j + 1 != tx.
vout.size()) {
127 OutAmounts +=
"<br/>";
128 OutAddresses +=
"<br/>";
132 std::string List[8] =
143 int n =
sizeof(List) /
sizeof(std::string) - 2;
145 if (!Highlight.empty()) {
146 List[n++] = std::string(
"<font color=\"") + ((Delta > 0) ?
"green" :
"red") +
"\">" + ValueToString(Delta,
true) +
"</font>";
148 List[n++] = ValueToString(*pSum);
149 return makeHTMLTableRow(List, n);
151 return makeHTMLTableRow(List + 1, n - 1);
159 return tx.
vout[out.
n];
176 std::string genesisblockhash =
"0000039a711dba61e12c29fb86542fa059e9616aafe9b4c61e065d393f31535e";
178 if ((Height < 0) || (Height > pindexBest->
nHeight)) {
179 return genesisblockhash;
184 while (pblockindex->
nHeight > Height)
185 pblockindex = pblockindex->
pprev;
201 std::string TxLabels[] = {
_(
"Hash"),
_(
"From"),
_(
"Amount"),
_(
"To"),
_(
"Amount")};
203 std::string TxContent = table + makeHTMLTableRow(TxLabels,
sizeof(TxLabels) /
sizeof(std::string));
204 for (
unsigned int i = 0; i < block.
vtx.size(); i++) {
206 TxContent += TxToRow(tx);
213 Fees = -MAX_MONEY_OUT;
219 TxContent +=
"</table>";
223 Generated = OutVolume;
227 std::string BlockContentCells[] =
231 _(
"Number of Transactions"),
itostr(block.
vtx.size()),
232 _(
"Value Out"), ValueToString(OutVolume),
233 _(
"Fees"), ValueToString(Fees),
234 _(
"Generated"), ValueToString(Generated),
235 _(
"Timestamp"), TimeToString(block.
nTime),
244 std::string BlockContent = makeHTMLTable(BlockContentCells,
sizeof(BlockContentCells) / (2 *
sizeof(std::string)), 2);
247 Content +=
"<h2><a class=\"nav\" href=";
249 Content +=
">◄ </a>";
250 Content +=
_(
"Block");
253 Content +=
"<a class=\"nav\" href=";
255 Content +=
"> ►</a></h2>";
256 Content += BlockContent;
258 Content +=
"<h2>" +
_(
"Transactions") +
"</h2>";
259 Content += TxContent;
269 std::string InputsContentCells[] = {
_(
"#"),
_(
"Taken from"),
_(
"Address"),
_(
"Amount")};
270 std::string InputsContent = makeHTMLTableRow(InputsContentCells,
sizeof(InputsContentCells) /
sizeof(std::string));
271 std::string OutputsContentCells[] = {
_(
"#"),
_(
"Redeemed in"),
_(
"Address"),
_(
"Amount")};
272 std::string OutputsContent = makeHTMLTableRow(OutputsContentCells,
sizeof(OutputsContentCells) /
sizeof(std::string));
275 std::string InputsContentCells[] =
280 ValueToString(Output)};
281 InputsContent += makeHTMLTableRow(InputsContentCells,
sizeof(InputsContentCells) /
sizeof(std::string));
283 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
287 Input = -MAX_MONEY_OUT;
290 std::string InputsContentCells[] =
295 ValueToString(PrevOut.
nValue)};
296 InputsContent += makeHTMLTableRow(InputsContentCells,
sizeof(InputsContentCells) /
sizeof(std::string));
300 for (
unsigned int i = 0; i < tx.
vout.size(); i++) {
303 unsigned int nNext = 0;
304 bool fAddrIndex =
false;
306 std::string OutputsContentCells[] =
309 (HashNext ==
uint256S(
"0")) ? (fAddrIndex ?
_(
"no") :
_(
"unknown")) :
"<span>" + makeHRef(HashNext.
GetHex()) +
":" +
itostr(nNext) +
"</span>",
311 ValueToString(Out.
nValue)};
312 OutputsContent += makeHTMLTableRow(OutputsContentCells,
sizeof(OutputsContentCells) /
sizeof(std::string));
315 InputsContent = table + InputsContent +
"</table>";
316 OutputsContent = table + OutputsContent +
"</table>";
320 std::string Labels[] =
324 _(
"Input"), tx.
IsCoinBase() ?
"-" : ValueToString(Input),
325 _(
"Output"), ValueToString(Output),
326 _(
"Fees"), tx.
IsCoinBase() ?
"-" : ValueToString(Input - Output),
328 _(
"Hash"),
"<pre>" +
Hash +
"</pre>",
336 Labels[5 * 2 + 1] = TimeToString(pIndex->
nTime);
340 Content +=
"<h2>" +
_(
"Transaction") +
" <span>" +
Hash +
"</span></h2>";
341 Content += makeHTMLTable(Labels,
sizeof(Labels) / (2 *
sizeof(std::string)), 2);
343 Content +=
"<h3>" +
_(
"Inputs") +
"</h3>";
344 Content += InputsContent;
346 Content +=
"<h3>" +
_(
"Outputs") +
"</h3>";
347 Content += OutputsContent;
354 std::string TxLabels[] =
364 std::string TxContent = table + makeHTMLTableRow(TxLabels,
sizeof(TxLabels) /
sizeof(std::string));
366 std::set<COutPoint> PrevOuts;
367 TxContent +=
"</table>";
370 Content +=
"<h1>" +
_(
"Transactions to/from") +
" <span>" + Address.
ToString() +
"</span></h1>";
371 Content += TxContent;
384 connect(
ui->pushSearch, SIGNAL(released()),
this, SLOT(
onSearch()));
385 connect(
ui->content, SIGNAL(linkActivated(
const QString&)),
this, SLOT(
goTo(
const QString&)));
386 connect(
ui->back, SIGNAL(released()),
this, SLOT(
back()));
387 connect(
ui->forward, SIGNAL(released()),
this, SLOT(
forward()));
397 switch ((Qt::Key)event->key()) {
404 return QMainWindow::keyPressEvent(event);
416 QString text = QString(
"%1").arg(pindexBest->
nHeight);
417 ui->searchBox->setText(text);
422 QString Warning = tr(
"Not all transactions will be shown. To view all transactions you need to set txindex=1 in the configuration file (prcycoin.conf).");
423 QMessageBox::warning(
this,
"PRCY Blockchain Explorer", Warning, QMessageBox::Ok);
431 int64_t AsInt = query.toInt(&IsOk);
462 Address.
SetString(query.toUtf8().constData());
477 ui->searchBox->setText(query);
488 goTo(
ui->searchBox->text());
498 QString CSS =
"body {font-size:12px; color:#f8f6f6; bgcolor:#5B4C7C;}\n a, span { font-family: monospace; }\n span.addr {color:#5B4C7C; font-weight: bold;}\n table tr td {padding: 3px; border: 1px solid black; background-color: #5B4C7C;}\n td.d0 {font-weight: bold; color:#f8f6f6;}\n h2, h3 { white-space:nowrap; color:#5B4C7C;}\n a { color:#88f6f6; text-decoration:none; }\n a.nav {color:#5B4C7C;}\n";
499 QString FullContent =
"<html><head><style type=\"text/css\">" + CSS +
"</style></head>" +
"<body>" + Content.c_str() +
"</body></html>";
501 ui->content->setText(FullContent);
507 if (0 <= NewIndex && NewIndex <
m_History.size()) {
518 if (0 <= NewIndex && NewIndex <
m_History.size()) {