QString Document::documentRevision() { std::string result; std::string filtered; QString txasm; QString bcguid; QString bcfilehash; QString bcattrhash; QString revOk = "

" + tr("Revision successful") + "

"; QString revHint = "

" + tr("Revision with notes") + "

"; QString revNoConf= "

" + tr("Revision is not possible yet") + "

"; QString revError = "

" + tr("Revision failed") + "

"; if (txid.isEmpty()) return revError + "

" + tr("No Transaction stored.") + "

"; if (filehash != getFileHash(filename)) return revError + "

" + tr("The current file does not match the locally saved hash. This file has been modified.") + "

"; try { // 1. get transaction // RPC: Post('{"jsonrpc": "1.0", "id":"DMSExposed", "method": "getrawtransaction", "params": ["%1",true] }', RPCConsole::RPCExecuteCommandLine(result, "getrawtransaction " + txid.toStdString() + " true", &filtered); QJsonDocument jdoc = QJsonDocument::fromJson(QByteArray::fromStdString(result)); QJsonObject jobj = jdoc.object(); int confirmations = jobj.value("confirmations").toInt(); QDateTime time = QDateTime::fromTime_t(jobj.value("time").toInt()); QDateTime blocktime = QDateTime::fromTime_t(jobj.value("blocktime").toInt()); int height = jobj.value("height").toInt(); QString blockhash = jobj.value("blockhash").toString(); bool found = false; QJsonArray jary = jobj.value("vout").toArray(); BOOST_FOREACH (const QJsonValue & jarval, jary) { QJsonObject jvout = jarval.toObject(); // {"value": 0.00000000,"valueSat": 0,"n": 1,"scriptPubKey": {"asm": "OP_RETURN 48616c6c6f2057656c74","hex": "6a0a48616c6c6f2057656c74","type": "nulldata"}} jvout = jvout.value("scriptPubKey").toObject(); if (jvout.value("type").toString() == "nulldata") { txasm = jvout.value("asm").toString(); if (txasm.toUpper().startsWith("OP_RETURN 444D2400010002")) { txasm.remove(0, 10); bcguid = txasm.mid(14, 32).toUpper(); bcfilehash = txasm.mid(46, 32).toUpper(); bcattrhash = txasm.mid(78, 32).toUpper(); found = true; break; } } } if (!found) return revError + "

" + tr("Transaction not found.") + "

"; // compare document with data from blockchain QString revlog = ""; QString deviation = tr("current value \"%1\" differs from value \"%2\" stored in blockchain."); QString accordance = tr("matches the blockchain value."); if (confirmations < minConfirms) { revlog.append(revNoConf); revlog.append("

" + tr("There are not enough blockchain confirmations available for revision. Please wait a while.") + "

"); } else if (compressGuid(guid) == bcguid && attrhash == bcattrhash && filehash == bcfilehash) revlog.append(revOk); else if (filehash == bcfilehash) revlog.append(revHint); else revlog.append(revError); revlog.append("

"); if (compressGuid(guid) == bcguid) revlog.append(QString("%1: %2
").arg(trGUID, accordance)); else revlog.append(QString("%1: %2
") .arg(trGUID, deviation.arg(compressGuid(guid), bcguid))); if (attrhash == bcattrhash) revlog.append(QString("%1: %2
").arg(trAttrHash, accordance)); else revlog.append(QString("%1: %2
") .arg(trAttrHash, deviation.arg(compressGuid(guid), bcguid))); if (filehash == bcfilehash) { revlog.append(QString("%1: %2").arg(trFileHash, accordance)); if (confirmations >= minConfirms) revlog.append("

" + tr("The blockchain confirms that %1this document file%2 exists at least since %3 and has not been modified.") .arg("", "", GUIUtil::dateTimeStr(blocktime))); } else revlog.append(QString("%1: %2") .arg(trFileHash, deviation.arg(compressGuid(guid), bcguid))); revlog.append("

" + tr("Blockchain confirmations") + ": " + QString::number(confirmations) + ((confirmations < minConfirms) ? ("/" + QString::number(minConfirms)) : "") + "

"); return revlog; } catch (const std::exception& e) { return revError + "

" + QString::fromStdString(e.what()) + "

"; } catch (...) { return revError + "

" + tr("Unknown error.") + "

"; } }