bool CCoinsViewCache::HaveInputs(const CTransaction& tx) { if (!tx.IsCoinBase()) { // first check whether information about the prevout hash is available for (unsigned int i = 0; i < tx.vin.size(); i++) { const COutPoint &prevout = tx.vin[i].prevout; if (!HaveCoins(prevout.hash)) return false; } // then check whether the actual outputs are available for (unsigned int i = 0; i < tx.vin.size(); i++) { const COutPoint &prevout = tx.vin[i].prevout; const CCoins &coins = GetCoins(prevout.hash); if (!coins.IsAvailable(prevout.n)) return false; } } return true; }
Value rpc_TxToJSON(const CTransaction& tx) { Object entry; entry.push_back(Pair("txid", tx.GetHash().GetHex())); entry.push_back(Pair("version", tx.nVersion)); entry.push_back(Pair("locktime", (boost::int64_t)tx.nLockTime)); Array vin; BOOST_FOREACH(const CTxIn& txin, tx.vin) { Object in; 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", (boost::int64_t)txin.prevout.n)); Object o; o.push_back(Pair("asm", txin.scriptSig.ToString())); o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); in.push_back(Pair("scriptSig", o)); } in.push_back(Pair("sequence", (boost::int64_t)txin.nSequence)); vin.push_back(in); } entry.push_back(Pair("vin", vin)); Array vout; for (unsigned int i = 0; i < tx.vout.size(); i++) { const CTxOut& txout = tx.vout[i]; Object out; out.push_back(Pair("value", ValueFromAmount(txout.nValue))); out.push_back(Pair("n", (boost::int64_t)i)); Object o; rpc_ScriptPubKeyToJSON(txout.scriptPubKey, o); out.push_back(Pair("scriptPubKey", o)); vout.push_back(out); } entry.push_back(Pair("vout", vout)); return entry; }
extern "C" char* GetPeggyByBlock(CBlock *pblock, CBlockIndex *pindex) { cJSON *array, *arrayObj, *header, *peggybase, *peggypayments, *peggytx; header = cJSON_CreateObject(); peggybase = cJSON_CreateObject(); peggypayments = cJSON_CreateArray(); peggytx = cJSON_CreateArray(); array = cJSON_CreateArray(); arrayObj = cJSON_CreateObject(); //header jaddnum(header, "blocknum", pindex->nHeight); jaddnum(header, "blocktimestamp", pblock->nTime); jaddstr(header, "blockhash", (char*)pindex->GetBlockHash().ToString().c_str()); jadd(arrayObj, "header", header); if(pindex->nHeight >= nMinPeggyHeight){ if(!pblock->vtx[2].IsPeggyBase()) throw runtime_error( "Block Does not contain a peggybase transaction!\n" ); } else{ return "Not a peggy block\n"; } int index, vouts; //peggypayments char bits[4096]; char hex[4096]; bool fPeggy = false; uint64_t nPeggyPayments = 0; for(index=0; index<pblock->vtx.size(); index++){ fPeggy = false; const CTransaction tempTx = pblock->vtx[index]; if(tempTx.IsCoinBase() || tempTx.IsCoinStake()) continue; if(tempTx.IsPeggyBase()){ const CTxOut peggyOut = tempTx.vout[0]; const CScript priceFeed = peggyOut.scriptPubKey; char peggybits[4096]; strcpy(peggybits, (char*)HexStr(priceFeed.begin(), priceFeed.end(), false).c_str()+2); jaddstr(peggybase, "txid", (char*)tempTx.GetHash().ToString().c_str()); jaddstr(peggybase, "peggybase", peggybits); jaddnum(peggybase, "time", tempTx.nTime); jaddnum(peggybase, "txind", 2); jaddnum(peggybase, "voutind", 0); jaddstr(peggybase, "address", "peggypayments"); fPeggy = true; } for(vouts=0; vouts<tempTx.vout.size(); vouts++){ const CTxOut tempVout = tempTx.vout[vouts]; const CScript tempScriptPubKey = tempVout.scriptPubKey; CTxDestination destAddress; strcpy(hex, (char*)HexStr(tempScriptPubKey.begin(), tempScriptPubKey.end(), false).c_str()); sprintf(hex, "%s", hex); if(fPeggy && (vouts != 0)){ cJSON *peggyOut = cJSON_CreateObject(); jaddstr(peggyOut, "txid", (char*)tempTx.GetHash().ToString().c_str()); jaddnum(peggyOut, "time", tempTx.nTime); jaddnum(peggyOut, "txind", index); jaddnum(peggyOut, "amount", tempVout.nValue); jaddnum(peggyOut, "voutind", vouts); jaddstr(peggyOut, "scriptPubKey", hex); if(ExtractDestination(tempScriptPubKey, destAddress)){ jaddstr(peggyOut, "address", (char*)CBitcoinAddress(destAddress).ToString().c_str()); } else{ jaddstr(peggyOut, "address", "null"); } nPeggyPayments += (uint64_t)tempVout.nValue; jaddi(peggypayments, peggyOut); } else if(!fPeggy && (isOpReturn(hex) == 0)){ //peggy lock found cJSON *lockVout = cJSON_CreateObject(); jaddstr(lockVout, "txid", (char*)tempTx.GetHash().ToString().c_str()); jaddnum(lockVout, "time", tempTx.nTime); jaddnum(lockVout, "txind", index); jaddnum(lockVout, "voutind", vouts); jaddstr(lockVout, "scriptPubKey", hex); if(ExtractDestination(tempScriptPubKey, destAddress)){ jaddstr(lockVout, "address", (char*)CBitcoinAddress(destAddress).ToString().c_str()); } else{ jaddstr(lockVout, "address", "null"); } jaddnum(lockVout, "amount", (uint64_t)tempVout.nValue); jaddi(peggytx, lockVout); continue; //1 op_return per tx } } } jaddnum(peggybase, "amount", nPeggyPayments); jadd(arrayObj, "peggybase", peggybase); jadd(arrayObj, "peggypayments", peggypayments); jadd(arrayObj, "peggytx", peggytx); jaddi(array, arrayObj); return jprint(array,0); }
void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) { entry.push_back(Pair("txid", tx.GetHash().GetHex())); entry.push_back(Pair("hash", tx.GetWitnessHash().GetHex())); entry.push_back(Pair("size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION))); entry.push_back(Pair("vsize", (int)::GetVirtualTransactionSize(tx))); entry.push_back(Pair("version", tx.nVersion)); entry.push_back(Pair("locktime", (int64_t)tx.nLockTime)); 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.wit.IsNull()) { if (!tx.wit.vtxinwit[i].IsNull()) { UniValue txinwitness(UniValue::VARR); for (unsigned int j = 0; j < tx.wit.vtxinwit[i].scriptWitness.stack.size(); j++) { std::vector<unsigned char> item = tx.wit.vtxinwit[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()) { entry.push_back(Pair("blockhash", hashBlock.GetHex())); BlockMap::iterator mi = mapBlockIndex.find(hashBlock); if (mi != mapBlockIndex.end() && (*mi).second) { CBlockIndex* pindex = (*mi).second; if (chainActive.Contains(pindex)) { entry.push_back(Pair("confirmations", 1 + chainActive.Height() - pindex->nHeight)); entry.push_back(Pair("time", pindex->GetBlockTime())); entry.push_back(Pair("blocktime", pindex->GetBlockTime())); } else entry.push_back(Pair("confirmations", 0)); } } }
void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) { entry.push_back(Pair("txid", tx.GetHash().GetHex())); entry.push_back(Pair("version", tx.nVersion)); entry.push_back(Pair("time", (boost::int64_t)tx.nTime)); entry.push_back(Pair("locktime", (boost::int64_t)tx.nLockTime)); Array vin; BOOST_FOREACH(const CTxIn& txin, tx.vin) { Object in; 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", (boost::int64_t)txin.prevout.n)); CTransaction txoutspent; uint256 tempHash = 0; if(GetTransaction( txin.prevout.hash, txoutspent, tempHash)) { in.push_back(Pair("value", ValueFromAmount(txoutspent.vout[txin.prevout.n].nValue))); CTxDestination inputAddress; ExtractDestination(txoutspent.vout[txin.prevout.n].scriptPubKey, inputAddress); in.push_back(Pair("addressfrom", CBitcoinAddress(inputAddress).ToString())); } Object o; o.push_back(Pair("asm", txin.scriptSig.ToString())); o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); in.push_back(Pair("scriptSig", o)); } in.push_back(Pair("sequence", (boost::int64_t)txin.nSequence)); vin.push_back(in); } entry.push_back(Pair("vin", vin)); Array vout; for (unsigned int i = 0; i < tx.vout.size(); i++) { const CTxOut& txout = tx.vout[i]; Object out; out.push_back(Pair("value", ValueFromAmount(txout.nValue))); out.push_back(Pair("n", (boost::int64_t)i)); Object o; ScriptPubKeyToJSON(txout.scriptPubKey, o); out.push_back(Pair("scriptPubKey", o)); vout.push_back(out); } entry.push_back(Pair("vout", vout)); if (hashBlock != 0) { entry.push_back(Pair("blockhash", hashBlock.GetHex())); map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); if (mi != mapBlockIndex.end() && (*mi).second) { CBlockIndex* pindex = (*mi).second; if (pindex->IsInMainChain()) { entry.push_back(Pair("confirmations", 1 + nBestHeight - pindex->nHeight)); entry.push_back(Pair("time", (boost::int64_t)pindex->nTime)); entry.push_back(Pair("blocktime", (boost::int64_t)pindex->nTime)); } else entry.push_back(Pair("confirmations", 0)); } } }
void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) { entry.push_back(Pair("txid", tx.GetHash().GetHex())); entry.push_back(Pair("version", tx.nVersion)); entry.push_back(Pair("time", (int64_t)tx.nTime)); entry.push_back(Pair("locktime", (int64_t)tx.nLockTime)); if (tx.nVersion > CTransaction::LEGACY_VERSION_1) { entry.push_back(Pair("clam-speech", tx.strCLAMSpeech)); } Array vin; BOOST_FOREACH(const CTxIn& txin, tx.vin) { Object in; 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)); Object o; o.push_back(Pair("asm", txin.scriptSig.ToString())); o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); in.push_back(Pair("scriptSig", o)); } in.push_back(Pair("sequence", (int64_t)txin.nSequence)); vin.push_back(in); } entry.push_back(Pair("vin", vin)); Array vout; for (unsigned int i = 0; i < tx.vout.size(); i++) { const CTxOut& txout = tx.vout[i]; Object out; out.push_back(Pair("value", ValueFromAmount(txout.nValue))); out.push_back(Pair("n", (int64_t)i)); Object o; ScriptPubKeyToJSON(txout.scriptPubKey, o, false); out.push_back(Pair("scriptPubKey", o)); vout.push_back(out); } entry.push_back(Pair("vout", vout)); if (hashBlock != 0) { entry.push_back(Pair("blockhash", hashBlock.GetHex())); map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); if (mi != mapBlockIndex.end() && (*mi).second) { CBlockIndex* pindex = (*mi).second; if (pindex->IsInMainChain()) { entry.push_back(Pair("confirmations", 1 + nBestHeight - pindex->nHeight)); entry.push_back(Pair("time", (int64_t)pindex->nTime)); entry.push_back(Pair("blocktime", (int64_t)pindex->nTime)); } else entry.push_back(Pair("confirmations", 0)); } } }
bool CheckCertInputs(const CTransaction &tx, int op, const vector<vector<unsigned char> > &vvchArgs, const std::vector<unsigned char> &vvchAlias, bool fJustCheck, int nHeight, sorted_vector<std::vector<unsigned char> > &revertedCerts, string &errorMessage, bool bSanityCheck) { if (!pcertdb || !paliasdb) return false; if (tx.IsCoinBase() && !fJustCheck && !bSanityCheck) { LogPrintf("*Trying to add cert in coinbase transaction, skipping..."); return true; } if (fDebug && !bSanityCheck) LogPrintf("*** CERT %d %d %s %s\n", nHeight, chainActive.Tip()->nHeight, tx.GetHash().ToString().c_str(), fJustCheck ? "JUSTCHECK" : "BLOCK"); // unserialize cert from txn, check for valid CCert theCert; vector<unsigned char> vchData; vector<unsigned char> vchHash; int nDataOut; if(!GetSyscoinData(tx, vchData, vchHash, nDataOut) || !theCert.UnserializeFromData(vchData, vchHash)) { errorMessage = "SYSCOIN_CERTIFICATE_CONSENSUS_ERROR ERRCODE: 3002 - " + _("Cannot unserialize data inside of this transaction relating to a certificate"); return true; } if(fJustCheck) { if(vvchArgs.size() != 1) { errorMessage = "SYSCOIN_CERTIFICATE_CONSENSUS_ERROR: ERRCODE: 3003 - " + _("Certificate arguments incorrect size"); return error(errorMessage.c_str()); } if(vchHash != vvchArgs[0]) { errorMessage = "SYSCOIN_CERTIFICATE_CONSENSUS_ERROR: ERRCODE: 2003 - " + _("Hash provided doesn't match the calculated hash of the data"); return true; } } CAliasIndex alias; string retError = ""; if(fJustCheck) { if(theCert.sCategory.size() > MAX_NAME_LENGTH) { errorMessage = "SYSCOIN_CERTIFICATE_CONSENSUS_ERROR: ERRCODE: 3004 - " + _("Certificate category too big"); return error(errorMessage.c_str()); } if(theCert.vchPubData.size() > MAX_VALUE_LENGTH) { errorMessage = "SYSCOIN_CERTIFICATE_CONSENSUS_ERROR: ERRCODE: 3005 - " + _("Certificate public data too big"); return error(errorMessage.c_str()); } switch (op) { case OP_CERT_ACTIVATE: if (theCert.vchCert.size() > MAX_GUID_LENGTH) { errorMessage = "SYSCOIN_CERTIFICATE_CONSENSUS_ERROR: ERRCODE: 3006 - " + _("Certificate hex guid too long"); return error(errorMessage.c_str()); } if((theCert.vchTitle.size() > MAX_NAME_LENGTH || theCert.vchTitle.empty())) { errorMessage = "SYSCOIN_CERTIFICATE_CONSENSUS_ERROR: ERRCODE: 3007 - " + _("Certificate title too big or is empty"); return error(errorMessage.c_str()); } if(!boost::algorithm::starts_with(stringFromVch(theCert.sCategory), "certificates")) { errorMessage = "SYSCOIN_CERTIFICATE_CONSENSUS_ERROR: ERRCODE: 3008 - " + _("Must use a certificate category"); return true; } break; case OP_CERT_UPDATE: if(theCert.vchTitle.size() > MAX_NAME_LENGTH) { errorMessage = "SYSCOIN_CERTIFICATE_CONSENSUS_ERROR: ERRCODE: 3009 - " + _("Certificate title too big"); return error(errorMessage.c_str()); } if(theCert.sCategory.size() > 0 && !boost::algorithm::istarts_with(stringFromVch(theCert.sCategory), "certificates")) { errorMessage = "SYSCOIN_CERTIFICATE_CONSENSUS_ERROR: ERRCODE: 3010 - " + _("Must use a certificate category"); return true; } break; case OP_CERT_TRANSFER: if(theCert.sCategory.size() > 0 && !boost::algorithm::istarts_with(stringFromVch(theCert.sCategory), "certificates")) { errorMessage = "SYSCOIN_CERTIFICATE_CONSENSUS_ERROR: ERRCODE: 3011 - " + _("Must use a certificate category"); return true; } break; default: errorMessage = "SYSCOIN_CERTIFICATE_CONSENSUS_ERROR: ERRCODE: 3012 - " + _("Certificate transaction has unknown op"); return error(errorMessage.c_str()); } } if (!fJustCheck && !bSanityCheck) { if (!RevertCert(theCert.vchCert, op, tx.GetHash(), revertedCerts)) { errorMessage = "SYSCOIN_CERTIFICATE_CONSENSUS_ERROR: ERRCODE: 3013 - " + _("Failed to revert cert"); return error(errorMessage.c_str()); } } const string &user1 = stringFromVch(vvchAlias); string user2 = ""; string user3 = ""; if (op == OP_CERT_TRANSFER) { user2 = stringFromVch(theCert.vchAlias); } string strResponseEnglish = ""; string strResponseGUID = ""; CTransaction txTmp; GetSyscoinTransactionDescription(txTmp, op, strResponseEnglish, CERT, strResponseGUID); // if not an certnew, load the cert data from the DB CCert dbCert; if (!GetCert(theCert.vchCert, dbCert)) { if (op != OP_CERT_ACTIVATE) { errorMessage = "SYSCOIN_CERTIFICATE_CONSENSUS_ERROR: ERRCODE: 3014 - " + _("Failed to read from certificate DB"); return true; } } if(op != OP_CERT_ACTIVATE) { if (dbCert.vchAlias != vvchAlias) { errorMessage = "SYSCOIN_CERTIFICATE_CONSENSUS_ERROR: ERRCODE: 3015 - " + _("Cannot update this certificate. Certificate owner must sign off on this change."); return true; } if (theCert.vchAlias.empty()) theCert.vchAlias = dbCert.vchAlias; if(theCert.vchPubData.empty()) theCert.vchPubData = dbCert.vchPubData; if(theCert.vchTitle.empty()) theCert.vchTitle = dbCert.vchTitle; if(theCert.sCategory.empty()) theCert.sCategory = dbCert.sCategory; CCert firstCert; if (!GetFirstCert(dbCert.vchCert, firstCert)) { errorMessage = "SYSCOIN_CERTIFICATE_CONSENSUS_ERROR: ERRCODE: 3016 - " + _("Cannot read first cert from cert DB"); return true; } if(op == OP_CERT_TRANSFER) { // check toalias if(!GetAlias(theCert.vchAlias, alias)) { errorMessage = "SYSCOIN_CERTIFICATE_CONSENSUS_ERROR: ERRCODE: 3017 - " + _("Cannot find alias you are transferring to. It may be expired"); return true; } if(!(alias.nAcceptTransferFlags & ACCEPT_TRANSFER_CERTIFICATES)) { errorMessage = "SYSCOIN_CERTIFICATE_CONSENSUS_ERROR: ERRCODE: 3018 - " + _("The alias you are transferring to does not accept certificate transfers"); return true; } // the original owner can modify certificate regardless of access flags, new owners must adhere to access flags if(dbCert.nAccessFlags < 2 && dbCert.vchAlias != firstCert.vchAlias) { errorMessage = "SYSCOIN_CERTIFICATE_CONSENSUS_ERROR: ERRCODE: 3019 - " + _("Cannot transfer this certificate. Insufficient privileges."); return true; } } else if(op == OP_CERT_UPDATE) { if(dbCert.nAccessFlags < 1 && dbCert.vchAlias != firstCert.vchAlias) { errorMessage = "SYSCOIN_CERTIFICATE_CONSENSUS_ERROR: ERRCODE: 3020 - " + _("Cannot edit this certificate. It is view-only."); return true; } } if(theCert.nAccessFlags > dbCert.nAccessFlags && dbCert.vchAlias != firstCert.vchAlias) { errorMessage = "SYSCOIN_CERTIFICATE_CONSENSUS_ERROR: ERRCODE: 3021 - " + _("Cannot modify for more lenient access. Only tighter access level can be granted."); return true; } } else { if (fJustCheck && GetCert(theCert.vchCert, theCert)) { errorMessage = "SYSCOIN_CERTIFICATE_CONSENSUS_ERROR: ERRCODE: 3022 - " + _("Certificate already exists"); return true; } } if(!bSanityCheck) { if (strResponseEnglish != "") { paliasdb->WriteAliasIndexTxHistory(user1, user2, user3, tx.GetHash(), nHeight, strResponseEnglish, stringFromVch(theCert.vchCert)); } } // set the cert's txn-dependent values theCert.nHeight = nHeight; theCert.txHash = tx.GetHash(); // write cert if (!bSanityCheck) { int64_t ms = INT64_MAX; if (fJustCheck) { ms = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count(); } if (!pcertdb->WriteCert(theCert, op, ms, fJustCheck)) { errorMessage = "SYSCOIN_CERTIFICATE_CONSENSUS_ERROR: ERRCODE: 3023 - " + _("Failed to write to certifcate DB"); return error(errorMessage.c_str()); } // debug if (fDebug) LogPrintf("CONNECTED CERT: op=%s cert=%s hash=%s height=%d fJustCheck=%d\n", certFromOp(op).c_str(), stringFromVch(theCert.vchCert).c_str(), tx.GetHash().ToString().c_str(), nHeight, fJustCheck ? 1 : -1); } return true; }
std::string TxToString(uint256 BlockHash, const CTransaction& tx) { CAmount Input = 0; CAmount Output = tx.GetValueOut(); std::string InputsContentCells[] = {_("#"), _("Taken from"), _("Address"), _("Amount")}; std::string InputsContent = makeHTMLTableRow(InputsContentCells, sizeof(InputsContentCells) / sizeof(std::string)); std::string OutputsContentCells[] = {_("#"), _("Redeemed in"), _("Address"), _("Amount")}; std::string OutputsContent = makeHTMLTableRow(OutputsContentCells, sizeof(OutputsContentCells) / sizeof(std::string)); if (tx.IsCoinBase()) { std::string InputsContentCells[] = { "0", "coinbase", "-", ValueToString(Output)}; InputsContent += makeHTMLTableRow(InputsContentCells, sizeof(InputsContentCells) / sizeof(std::string)); } else for (unsigned int i = 0; i < tx.vin.size(); i++) { COutPoint Out = tx.vin[i].prevout; CTxOut PrevOut = getPrevOut(tx.vin[i].prevout); if (PrevOut.nValue < 0) Input = -Params().MaxMoneyOut(); else Input += PrevOut.nValue; std::string InputsContentCells[] = { itostr(i), "<span>" + makeHRef(Out.hash.GetHex()) + ":" + itostr(Out.n) + "</span>", ScriptToString(PrevOut.scriptPubKey, true), ValueToString(PrevOut.nValue)}; InputsContent += makeHTMLTableRow(InputsContentCells, sizeof(InputsContentCells) / sizeof(std::string)); } uint256 TxHash = tx.GetHash(); for (unsigned int i = 0; i < tx.vout.size(); i++) { const CTxOut& Out = tx.vout[i]; uint256 HashNext = uint256S("0"); unsigned int nNext = 0; bool fAddrIndex = false; getNextIn(COutPoint(TxHash, i), HashNext, nNext); std::string OutputsContentCells[] = { itostr(i), (HashNext == uint256S("0")) ? (fAddrIndex ? _("no") : _("unknown")) : "<span>" + makeHRef(HashNext.GetHex()) + ":" + itostr(nNext) + "</span>", ScriptToString(Out.scriptPubKey, true), ValueToString(Out.nValue)}; OutputsContent += makeHTMLTableRow(OutputsContentCells, sizeof(OutputsContentCells) / sizeof(std::string)); } InputsContent = table + InputsContent + "</table>"; OutputsContent = table + OutputsContent + "</table>"; std::string Hash = TxHash.GetHex(); std::string Labels[] = { _("In Block"), "", _("Size"), itostr(GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION)), _("Input"), tx.IsCoinBase() ? "-" : ValueToString(Input), _("Output"), ValueToString(Output), _("Fees"), tx.IsCoinBase() ? "-" : ValueToString(Input - Output), _("Timestamp"), "", _("Hash"), "<pre>" + Hash + "</pre>", }; // std::map<uint256, CBlockIndex*>::iterator iter = mapBlockIndex.find(BlockHash); BlockMap::iterator iter = mapBlockIndex.find(BlockHash); if (iter != mapBlockIndex.end()) { CBlockIndex* pIndex = iter->second; Labels[0 * 2 + 1] = makeHRef(itostr(pIndex->nHeight)); Labels[5 * 2 + 1] = TimeToString(pIndex->nTime); } std::string Content; Content += "<h2>" + _("Transaction") + " <span>" + Hash + "</span></h2>"; Content += makeHTMLTable(Labels, sizeof(Labels) / (2 * sizeof(std::string)), 2); Content += "</br>"; Content += "<h3>" + _("Inputs") + "</h3>"; Content += InputsContent; Content += "</br>"; Content += "<h3>" + _("Outputs") + "</h3>"; Content += OutputsContent; return Content; }
bool COeruShield::CheckMasterTx(const CTransaction tx, const int nHeight, const bool revert) const { if (tx.IsCoinBase()) return false; if (tx.vout.size() != 3) return false; CTxOut minerOut = tx.vout[0]; CTxOut masterOut = tx.vout[1]; CTxOut signatureOut = tx.vout[2]; CBitcoinAddress master; if (!GetDestinationAddress(masterOut, master)) return false; if (!IsMasterKey(master)) return false; CBitcoinAddress miner; if (!GetDestinationAddress(minerOut, miner)) return false; COeruTxOut masterOeruOut(&signatureOut); COeruMasterData masterData = masterOeruOut.GetOeruMasterData(); if (!masterData.IsValid()) { LogPrint("OeruShield", "%s: No valid master data found\n", __FUNCTION__); return false; } bool enable; if (!masterData.GetEnable(enable)) { LogPrint("OeruShield", "%s: Master TX failed getting enable status\n", __FUNCTION__); return false; } uint64_t masterHeight; if (!masterData.GetHeight(masterHeight)) { LogPrint("OeruShield", "%s: Master TX failed getting height\n", __FUNCTION__); return false; } if (masterHeight > nHeight + Params().OeruShieldMaxMasterHeightDifference()) { LogPrint("OeruShield", "%s: Master TX too old\n", __FUNCTION__); return false; } if (!masterData.HasValidSignature(master, miner)) { LogPrint("OeruShield", "%s: Master TX has no valid signature\n", __FUNCTION__); return false; } // If this is a 'revert check' (ie called from DisconnectTip) // we need to invert the action if (revert) enable = !enable; if (enable) oeruDB->AddCertifiedAddress(miner); else oeruDB->RemoveCertifiedAddress(miner); oeruDB->WriteFile(); return true; }
void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) { CTxDB txdb("r"); entry.push_back(Pair("txid", tx.GetHash().GetHex())); entry.push_back(Pair("version", tx.nVersion)); entry.push_back(Pair("time", (boost::int64_t)tx.nTime)); entry.push_back(Pair("locktime", (boost::int64_t)tx.nLockTime)); if (tx.nVersion > 1) { entry.push_back(Pair("tx-comment", tx.strTxComment)); entry.push_back(Pair("product-id", (boost::int64_t)tx.nProdTypeID)); } Array vin; BOOST_FOREACH(const CTxIn& txin, tx.vin) { Object in; 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", (boost::int64_t)txin.prevout.n)); Object o; o.push_back(Pair("asm", txin.scriptSig.ToString())); o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); in.push_back(Pair("scriptSig", o)); } in.push_back(Pair("sequence", (boost::int64_t)txin.nSequence)); // [TODO] Refactor this! See getturboredemption. CTransaction txPrev; CTxIndex txindex; if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex)) { if (fDebug) { printf("TxToJSON: could not read txin from disk\n"); } continue; // previous transaction not in main chain? } CTxOut prevtxout = txPrev.vout[txin.prevout.n]; int nRequired; txnouttype type; vector<CTxDestination> addresses; if (ExtractDestinations(prevtxout.scriptPubKey, type, addresses, nRequired)) { in.push_back(Pair("value", ValueFromAmount(prevtxout.nValue))); } else { in.push_back(Pair("type", GetTxnOutputType(TX_NONSTANDARD))); } Array a; BOOST_FOREACH(const CTxDestination& addr, addresses) { a.push_back(CBitcoinAddress(addr).ToString()); } in.push_back(Pair("addresses", a)); vin.push_back(in); }