CPubKey CKey::GetPubKey() const { int nSize = i2o_ECPublicKey(pkey, NULL); if (!nSize) throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed"); std::vector<unsigned char> vchPubKey(nSize, 0); unsigned char* pbegin = &vchPubKey[0]; if (i2o_ECPublicKey(pkey, &pbegin) != nSize) throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size"); return CPubKey(vchPubKey); }
unsigned int HaveKeys(const std::vector<valtype>& pubkeys, const CKeyStore& keystore) { unsigned int nResult = 0; for (const valtype& pubkey : pubkeys) { CKeyID keyID = CPubKey(pubkey).GetID(); if (keystore.HaveKey(keyID)) ++nResult; } return nResult; }
CMasternode::CMasternode() { LOCK(cs); vin = CTxIn(); addr = CService(); pubkey = CPubKey(); pubkey2 = CPubKey(); sig = std::vector<unsigned char>(); activeState = MASTERNODE_ENABLED; sigTime = GetAdjustedTime(); lastPing = CMasternodePing(); cacheInputAge = 0; cacheInputAgeBlock = 0; unitTest = false; allowFreeTx = true; protocolVersion = PROTOCOL_VERSION; nLastDsq = 0; nScanningErrorCount = 0; nLastScanningErrorBlockHeight = 0; lastTimeChecked = 0; }
static bool SignN(const std::vector<valtype>& multisigdata, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector<valtype>& ret, SigVersion sigversion) { int nSigned = 0; int nRequired = multisigdata.front()[0]; for (unsigned int i = 1; i < multisigdata.size()-1 && nSigned < nRequired; i++) { const valtype& pubkey = multisigdata[i]; CKeyID keyID = CPubKey(pubkey).GetID(); if (Sign1(keyID, creator, scriptCode, ret, sigversion)) ++nSigned; } return nSigned==nRequired; }
static bool ExtractPubKey(const CScript &dest, CPubKey& pubKeyOut) { //TODO: Use Solver to extract this? CScript::const_iterator pc = dest.begin(); opcodetype opcode; std::vector<unsigned char> vch; if (!dest.GetOp(pc, opcode, vch) || vch.size() < 33 || vch.size() > 65) return false; pubKeyOut = CPubKey(vch); if (!pubKeyOut.IsFullyValid()) return false; if (!dest.GetOp(pc, opcode, vch) || opcode != OP_CHECKSIG || dest.GetOp(pc, opcode, vch)) return false; return true; }
CMasternode::CMasternode() { LOCK(cs); vin = CTxIn(); addr = CService(); pubKeyCollateralAddress = CPubKey(); pubKeyMasternode = CPubKey(); sig = std::vector<unsigned char>(); activeState = MASTERNODE_ENABLED; sigTime = GetAdjustedTime(); lastPing = CMasternodePing(); cacheInputAge = 0; cacheInputAgeBlock = 0; unitTest = false; allowFreeTx = true; nActiveState = MASTERNODE_ENABLED, protocolVersion = PROTOCOL_VERSION; nLastDsq = 0; nScanningErrorCount = 0; nLastScanningErrorBlockHeight = 0; lastTimeChecked = 0; nLastDsee = 0; // temporary, do not save. Remove after migration to v12 nLastDseep = 0; // temporary, do not save. Remove after migration to v12 }
CMasternode::CollateralStatus CMasternode::CheckCollateral(const COutPoint& outpoint, const CPubKey& pubkey, int& nHeightRet) { AssertLockHeld(cs_main); Coin coin; if (!GetUTXOCoin(outpoint, coin)) { return COLLATERAL_UTXO_NOT_FOUND; } if (coin.out.nValue != 25000 * COIN) { return COLLATERAL_INVALID_AMOUNT; } if (pubkey == CPubKey() || coin.out.scriptPubKey != GetScriptForDestination(CScriptID(GetScriptForDestination(WitnessV0KeyHash(pubkey.GetID()))))) { return COLLATERAL_INVALID_PUBKEY; } nHeightRet = coin.nHeight; return COLLATERAL_OK; }
/** * Sign scriptPubKey using signature made with creator. * Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed), * unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script. * Returns false if scriptPubKey could not be completely satisfied. */ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey, std::vector<valtype>& ret, txnouttype& whichTypeRet, SigVersion sigversion, SignatureData& sigdata) { CScript scriptRet; uint160 h160; ret.clear(); std::vector<unsigned char> sig; std::vector<valtype> vSolutions; if (!Solver(scriptPubKey, whichTypeRet, vSolutions)) return false; switch (whichTypeRet) { case TX_NONSTANDARD: case TX_NULL_DATA: case TX_WITNESS_UNKNOWN: return false; case TX_PUBKEY: if (!CreateSig(creator, sigdata, provider, sig, CPubKey(vSolutions[0]), scriptPubKey, sigversion)) return false; ret.push_back(std::move(sig)); return true; case TX_PUBKEYHASH: { CKeyID keyID = CKeyID(uint160(vSolutions[0])); CPubKey pubkey; GetPubKey(provider, sigdata, keyID, pubkey); if (!CreateSig(creator, sigdata, provider, sig, pubkey, scriptPubKey, sigversion)) return false; ret.push_back(std::move(sig)); ret.push_back(ToByteVector(pubkey)); return true; } case TX_SCRIPTHASH: if (GetCScript(provider, sigdata, uint160(vSolutions[0]), scriptRet)) { ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end())); return true; } return false; case TX_MULTISIG: { size_t required = vSolutions.front()[0]; ret.push_back(valtype()); // workaround CHECKMULTISIG bug for (size_t i = 1; i < vSolutions.size() - 1; ++i) { CPubKey pubkey = CPubKey(vSolutions[i]); if (ret.size() < required + 1 && CreateSig(creator, sigdata, provider, sig, pubkey, scriptPubKey, sigversion)) { ret.push_back(std::move(sig)); } } bool ok = ret.size() == required + 1; for (size_t i = 0; i + ret.size() < required + 1; ++i) { ret.push_back(valtype()); } return ok; } case TX_WITNESS_V0_KEYHASH: ret.push_back(vSolutions[0]); return true; case TX_WITNESS_V0_SCRIPTHASH: CRIPEMD160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(h160.begin()); if (GetCScript(provider, sigdata, h160, scriptRet)) { ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end())); return true; } return false; default: return false; } }
void CAccount::SetNull() { vchPubKey = CPubKey(); }
// Extracts signatures and scripts from incomplete scriptSigs. Please do not extend this, use PSBT instead SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nIn, const CTxOut& txout) { SignatureData data; assert(tx.vin.size() > nIn); data.scriptSig = tx.vin[nIn].scriptSig; data.scriptWitness = tx.vin[nIn].scriptWitness; Stacks stack(data); // Get signatures MutableTransactionSignatureChecker tx_checker(&tx, nIn, txout.nValue); SignatureExtractorChecker extractor_checker(data, tx_checker); if (VerifyScript(data.scriptSig, txout.scriptPubKey, &data.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, extractor_checker)) { data.complete = true; return data; } // Get scripts txnouttype script_type; std::vector<std::vector<unsigned char>> solutions; Solver(txout.scriptPubKey, script_type, solutions); SigVersion sigversion = SigVersion::BASE; CScript next_script = txout.scriptPubKey; if (script_type == TX_SCRIPTHASH && !stack.script.empty() && !stack.script.back().empty()) { // Get the redeemScript CScript redeem_script(stack.script.back().begin(), stack.script.back().end()); data.redeem_script = redeem_script; next_script = std::move(redeem_script); // Get redeemScript type Solver(next_script, script_type, solutions); stack.script.pop_back(); } if (script_type == TX_WITNESS_V0_SCRIPTHASH && !stack.witness.empty() && !stack.witness.back().empty()) { // Get the witnessScript CScript witness_script(stack.witness.back().begin(), stack.witness.back().end()); data.witness_script = witness_script; next_script = std::move(witness_script); // Get witnessScript type Solver(next_script, script_type, solutions); stack.witness.pop_back(); stack.script = std::move(stack.witness); stack.witness.clear(); sigversion = SigVersion::WITNESS_V0; } if (script_type == TX_MULTISIG && !stack.script.empty()) { // Build a map of pubkey -> signature by matching sigs to pubkeys: assert(solutions.size() > 1); unsigned int num_pubkeys = solutions.size()-2; unsigned int last_success_key = 0; for (const valtype& sig : stack.script) { for (unsigned int i = last_success_key; i < num_pubkeys; ++i) { const valtype& pubkey = solutions[i+1]; // We either have a signature for this pubkey, or we have found a signature and it is valid if (data.signatures.count(CPubKey(pubkey).GetID()) || extractor_checker.CheckSig(sig, pubkey, next_script, sigversion)) { last_success_key = i + 1; break; } } } } return data; }
CMessage::CMessage() : m_header( (int)CPayloadKind::Uninitiated, std::vector<unsigned char>(), 0, CPubKey(), uint256(), uint256() ) { }
isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey, bool& isInvalid, SigVersion sigversion) { std::vector<valtype> vSolutions; txnouttype whichType; if (!Solver(scriptPubKey, whichType, vSolutions)) { if (keystore.HaveWatchOnly(scriptPubKey)) return ISMINE_WATCH_UNSOLVABLE; return ISMINE_NO; } CKeyID keyID; switch (whichType) { case TX_NONSTANDARD: case TX_NULL_DATA: break; case TX_PUBKEY: keyID = CPubKey(vSolutions[0]).GetID(); if (sigversion != SIGVERSION_BASE && vSolutions[0].size() != 33) { isInvalid = true; return ISMINE_NO; } if (keystore.HaveKey(keyID)) return ISMINE_SPENDABLE; break; case TX_WITNESS_V0_KEYHASH: { if (!keystore.HaveCScript(CScriptID(CScript() << OP_0 << vSolutions[0]))) { // We do not support bare witness outputs unless the P2SH version of it would be // acceptable as well. This protects against matching before segwit activates. // This also applies to the P2WSH case. break; } isminetype ret = ::IsMine(keystore, GetScriptForDestination(CKeyID(uint160(vSolutions[0]))), isInvalid, SIGVERSION_WITNESS_V0); if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid)) return ret; break; } case TX_PUBKEYHASH: keyID = CKeyID(uint160(vSolutions[0])); if (sigversion != SIGVERSION_BASE) { CPubKey pubkey; if (keystore.GetPubKey(keyID, pubkey) && !pubkey.IsCompressed()) { isInvalid = true; return ISMINE_NO; } } if (keystore.HaveKey(keyID)) return ISMINE_SPENDABLE; break; case TX_SCRIPTHASH: { CScriptID scriptID = CScriptID(uint160(vSolutions[0])); CScript subscript; if (keystore.GetCScript(scriptID, subscript)) { isminetype ret = IsMine(keystore, subscript, isInvalid); if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid)) return ret; } break; } case TX_WITNESS_V0_SCRIPTHASH: { if (!keystore.HaveCScript(CScriptID(CScript() << OP_0 << vSolutions[0]))) { break; } uint160 hash; CRIPEMD160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(hash.begin()); CScriptID scriptID = CScriptID(hash); CScript subscript; if (keystore.GetCScript(scriptID, subscript)) { isminetype ret = IsMine(keystore, subscript, isInvalid, SIGVERSION_WITNESS_V0); if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid)) return ret; } break; } case TX_MULTISIG: { // Only consider transactions "mine" if we own ALL the // keys involved. Multi-signature transactions that are // partially owned (somebody else has a key that can spend // them) enable spend-out-from-under-you attacks, especially // in shared-wallet situations. std::vector<valtype> keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1); if (sigversion != SIGVERSION_BASE) { for (size_t i = 0; i < keys.size(); i++) { if (keys[i].size() != 33) { isInvalid = true; return ISMINE_NO; } } } if (HaveKeys(keys, keystore) == keys.size()) return ISMINE_SPENDABLE; break; } } if (keystore.HaveWatchOnly(scriptPubKey)) { // TODO: This could be optimized some by doing some work after the above solver SignatureData sigs; return ProduceSignature(DummySignatureCreator(&keystore), scriptPubKey, sigs) ? ISMINE_WATCH_SOLVABLE : ISMINE_WATCH_UNSOLVABLE; } return ISMINE_NO; }
QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx) { QString strHTML; QString explorer(fTestNet ? "http://explorer.butterflycoin.info/" : "http://explorer.butterflycoin.info/"); LOCK2(cs_main, wallet->cs_wallet); strHTML.reserve(4000); strHTML += "<html><font face='verdana, arial, helvetica, sans-serif'>"; int64_t nTime = wtx.GetTxTime(); int64_t nCredit = wtx.GetCredit(); int64_t nDebit = wtx.GetDebit(); int64_t nNet = nCredit - nDebit; strHTML += "<b>" + tr("Status") + ":</b> " + FormatTxStatus(wtx); int nRequests = wtx.GetRequestCount(); if (nRequests != -1) { if (nRequests == 0) strHTML += tr(", has not been successfully broadcast yet"); else if (nRequests > 0) strHTML += tr(", broadcast through %n node(s)", "", nRequests); }; strHTML += "<br>"; strHTML += "<b>" + tr("Date") + ":</b> " + (nTime ? GUIUtil::dateTimeStr(nTime) : "") + "<br>"; // // From // if (wtx.IsCoinBase() || wtx.IsCoinStake()) { strHTML += "<b>" + tr("Source") + ":</b> " + tr("Generated") + "<br>"; } else if (wtx.mapValue.count("from") && !wtx.mapValue["from"].empty()) { // Online transaction strHTML += "<b>" + tr("From") + ":</b> " + GUIUtil::HtmlEscape(wtx.mapValue["from"]) + "<br>"; } else { // Offline transaction if (nNet > 0) { // Credit BOOST_FOREACH(const CTxOut& txout, wtx.vout) { if (wtx.nVersion == ANON_TXN_VERSION && txout.IsAnonOutput()) { const CScript &s = txout.scriptPubKey; CKeyID ckidD = CPubKey(&s[2+1], 33).GetID(); std::string sAnonPrefix("ao "); if (wallet->HaveKey(ckidD) && (wallet->mapAddressBook[ckidD].empty() || !wallet->mapAddressBook[ckidD].compare(0, sAnonPrefix.length(), sAnonPrefix) == 0)) { strHTML += "<b>" + tr("From") + ":</b> " + tr("unknown") + "<br>"; strHTML += "<b>" + tr("To") + ":</b> <a href='"+explorer+"address.asp?address="; strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(ckidD).ToString())+"' target='_blank'>"; strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(ckidD).ToString()); if (!wallet->mapAddressBook[ckidD].empty()) strHTML += " (" + tr("own address") + ", " + tr("label") + ": " + GUIUtil::HtmlEscape(wallet->mapAddressBook[ckidD]) + ")"; else strHTML += " (" + tr("own address") + ")"; strHTML += "</a><br>"; }; continue; } if (wallet->IsMine(txout)) { CTxDestination address; if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address)) { if (wallet->mapAddressBook.count(address)) { strHTML += "<b>" + tr("From") + ":</b> " + tr("unknown") + "<br>"; strHTML += "<b>" + tr("To") + ":</b> <a href='"+explorer+"address.asp?address="; strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString())+"' target='_blank'>"; strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString()); if (!wallet->mapAddressBook[address].empty()) strHTML += " (" + tr("own address") + ", " + tr("label") + ": " + GUIUtil::HtmlEscape(wallet->mapAddressBook[address]) + ")"; else strHTML += " (" + tr("own address") + ")"; strHTML += "</a><br>"; }; }; break; }; }; }; };
/* * Decompose CWallet transaction to model transaction records. */ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx) { QList<TransactionRecord> parts; int64_t nTime = wtx.GetTxTime(); int64_t nCredMOIN, nCredMoinX; wtx.GetCredit(nCredMOIN, nCredMoinX, true); int64_t nCredit = nCredMOIN + nCredMoinX; int64_t nDebit = wtx.GetDebit(); int64_t nNet = nCredit - nDebit; uint256 hash = wtx.GetHash(), hashPrev = 0; std::map<std::string, std::string> mapValue = wtx.mapValue; char cbuf[256]; if (wtx.nVersion == ANON_TXN_VERSION) { if (nNet > 0 && nCredMoinX > 0) { // -- credit TransactionRecord sub(hash, nTime, TransactionRecord::RecvMoinX, "", "", nNet, 0); for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++) { // display 1st transaction snprintf(cbuf, sizeof(cbuf), "n_%u", nOut); mapValue_t::const_iterator mi = wtx.mapValue.find(cbuf); if (mi != wtx.mapValue.end() && !mi->second.empty()) { sub.narration = mi->second; break; }; }; parts.append(sub); return parts; } else if (nNet <= 0) { // -- debit TransactionRecord sub(hash, nTime, TransactionRecord::SendMoinX, "", "", nNet, 0); for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++) { // display 1st transaction snprintf(cbuf, sizeof(cbuf), "n_%u", nOut); mapValue_t::const_iterator mi = wtx.mapValue.find(cbuf); if (mi != wtx.mapValue.end() && !mi->second.empty()) { sub.narration = mi->second; break; } }; parts.append(sub); return parts; }; // continue on }; if (nNet > 0 || wtx.IsCoinBase() || wtx.IsCoinStake()) { // // Credit // for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++) { const CTxOut& txout = wtx.vout[nOut]; if (wtx.nVersion == ANON_TXN_VERSION && txout.IsAnonOutput()) { const CScript &s = txout.scriptPubKey; CKeyID ckidD = CPubKey(&s[2+1], 33).GetID(); if (wallet->HaveKey(ckidD)) { TransactionRecord sub(hash, nTime); sub.idx = parts.size(); // sequence number sub.credit = txout.nValue; sub.type = TransactionRecord::RecvMoinX; sub.address = CBitcoinAddress(ckidD).ToString(); //sub.address = wallet->mapAddressBook[ckidD] snprintf(cbuf, sizeof(cbuf), "n_%u", nOut); mapValue_t::const_iterator mi = wtx.mapValue.find(cbuf); if (mi != wtx.mapValue.end() && !mi->second.empty()) sub.narration = mi->second; parts.append(sub); }; }; if (wallet->IsMine(txout)) { TransactionRecord sub(hash, nTime); sub.idx = parts.size(); // sequence number CTxDestination address; sub.credit = txout.nValue; if (ExtractDestination(txout.scriptPubKey, address) && IsDestMine(*wallet, address)) { // Received by Bitcoin Address sub.type = TransactionRecord::RecvWithAddress; sub.address = CBitcoinAddress(address).ToString(); } else { // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction sub.type = TransactionRecord::RecvFromOther; sub.address = mapValue["from"]; } snprintf(cbuf, sizeof(cbuf), "n_%u", nOut); mapValue_t::const_iterator mi = wtx.mapValue.find(cbuf); if (mi != wtx.mapValue.end() && !mi->second.empty()) sub.narration = mi->second; if (wtx.IsCoinBase()) { // Generated (proof-of-work) sub.type = TransactionRecord::Generated; }; if (wtx.IsCoinStake()) { // Generated (proof-of-stake) if (hashPrev == hash) continue; // last coinstake output sub.type = TransactionRecord::Generated; sub.credit = nNet > 0 ? nNet : wtx.GetValueOut() - nDebit; hashPrev = hash; }; parts.append(sub); } } } else { bool fAllFromMe = true; BOOST_FOREACH(const CTxIn& txin, wtx.vin) { if (wtx.nVersion == ANON_TXN_VERSION && txin.IsAnonInput()) { std::vector<uint8_t> vchImage; txin.ExtractKeyImage(vchImage); CWalletDB walletdb(wallet->strWalletFile, "r"); COwnedAnonOutput oao; if (!walletdb.ReadOwnedAnonOutput(vchImage, oao)) { fAllFromMe = false; break; // display as send/recv moinx }; continue; }; if (wallet->IsMine(txin)) continue; fAllFromMe = false; break; }; bool fAllToMe = true; BOOST_FOREACH(const CTxOut& txout, wtx.vout) { if (wtx.nVersion == ANON_TXN_VERSION && txout.IsAnonOutput()) { fAllToMe = false; break; // display as send/recv moinx } opcodetype firstOpCode; CScript::const_iterator pc = txout.scriptPubKey.begin(); if (txout.scriptPubKey.GetOp(pc, firstOpCode) && firstOpCode == OP_RETURN) continue; if (wallet->IsMine(txout)) continue; fAllToMe = false; break; }; if (fAllFromMe && fAllToMe) { // Payment to self int64_t nChange = wtx.GetChange(); std::string narration(""); mapValue_t::const_iterator mi; for (mi = wtx.mapValue.begin(); mi != wtx.mapValue.end(); ++mi) { if (mi->first.compare(0, 2, "n_") != 0) continue; narration = mi->second; break; }; parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf, "", narration, -(nDebit - nChange), nCredit - nChange)); } else if (fAllFromMe) { // // Debit // int64_t nTxFee = nDebit - wtx.GetValueOut(); for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++) { const CTxOut& txout = wtx.vout[nOut]; TransactionRecord sub(hash, nTime); sub.idx = parts.size(); if (wtx.nVersion == ANON_TXN_VERSION && txout.IsAnonOutput()) { const CScript &s = txout.scriptPubKey; CKeyID ckidD = CPubKey(&s[2+1], 33).GetID(); CTxDestination address; sub.idx = parts.size(); // sequence number sub.credit = txout.nValue; sub.type = TransactionRecord::SendMoinX; sub.address = CBitcoinAddress(ckidD).ToString(); } else { opcodetype firstOpCode; CScript::const_iterator pc = txout.scriptPubKey.begin(); if (txout.scriptPubKey.GetOp(pc, firstOpCode) && firstOpCode == OP_RETURN) continue; if (wallet->IsMine(txout)) { // Ignore parts sent to self, as this is usually the change // from a transaction sent back to our own address. continue; } CTxDestination address; if (ExtractDestination(txout.scriptPubKey, address)) { // Sent to Bitcoin Address sub.type = TransactionRecord::SendToAddress; sub.address = CBitcoinAddress(address).ToString(); } else { // Sent to IP, or other non-address transaction like OP_EVAL sub.type = TransactionRecord::SendToOther; sub.address = mapValue["to"]; } }; snprintf(cbuf, sizeof(cbuf), "n_%u", nOut); mapValue_t::const_iterator mi = wtx.mapValue.find(cbuf); if (mi != wtx.mapValue.end() && !mi->second.empty()) sub.narration = mi->second; int64_t nValue = txout.nValue; /* Add fee to first output */ if (nTxFee > 0) { nValue += nTxFee; nTxFee = 0; } sub.debit = -nValue; parts.append(sub); } } else { // // Mixed debit transaction, can't break down payees // TransactionRecord sub(hash, nTime, TransactionRecord::Other, "", "", nNet, 0); /* for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++) { // display 1st transaction snprintf(cbuf, sizeof(cbuf), "n_%u", nOut); mapValue_t::const_iterator mi = wtx.mapValue.find(cbuf); if (mi != wtx.mapValue.end() && !mi->second.empty()) sub.narration = mi->second; break; }; */ parts.append(sub); } } return parts; }
CMessage::CMessage( CIdentifyMessage const & _identifyMessage, uint256 const & _actionKey, uint256 const & _id ) : m_header( (int)CPayloadKind::IntroductionReq, std::vector<unsigned char>(), GetTime(), CPubKey(), _actionKey, _id ) { createPayload( _identifyMessage, m_payload ); }
CMessage::CMessage( CAck const & _ack, uint256 const & _actionKey, uint256 const & _id ) : m_header( (int)CPayloadKind::Ack, std::vector<unsigned char>(), GetTime(), CPubKey(), _actionKey, _id ) { createPayload( _ack, m_payload ); }
CMessage::CMessage( int _messageKind, std::vector< unsigned char > const & _payload, uint256 const & _actionKey, uint256 const & _id ) : m_header( _messageKind, std::vector<unsigned char>(), GetTime(), CPubKey(), _actionKey, _id ) , m_payload(_payload) { common::CommunicationProtocol::signPayload( _payload, m_header.m_signedHash ); }