本文整理汇总了C++中uint256::IsNull方法的典型用法代码示例。如果您正苦于以下问题:C++ uint256::IsNull方法的具体用法?C++ uint256::IsNull怎么用?C++ uint256::IsNull使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类uint256
的用法示例。
在下文中一共展示了uint256::IsNull方法的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: TxToUniv
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry)
{
entry.pushKV("txid", tx.GetHash().GetHex());
entry.pushKV("version", tx.nVersion);
entry.pushKV("locktime", (int64_t)tx.nLockTime);
UniValue vin(UniValue::VARR);
BOOST_FOREACH(const CTxIn& txin, tx.vin) {
UniValue in(UniValue::VOBJ);
if (tx.IsCoinBase())
in.pushKV("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
else {
in.pushKV("txid", txin.prevout.hash.GetHex());
in.pushKV("vout", (int64_t)txin.prevout.n);
UniValue o(UniValue::VOBJ);
o.pushKV("asm", txin.scriptSig.ToString());
o.pushKV("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
in.pushKV("scriptSig", o);
}
in.pushKV("sequence", (int64_t)txin.nSequence);
vin.push_back(in);
}
entry.pushKV("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);
UniValue outValue(UniValue::VNUM, FormatMoney(txout.nValue));
out.pushKV("value", outValue);
out.pushKV("n", (int64_t)i);
UniValue o(UniValue::VOBJ);
ScriptPubKeyToUniv(txout.scriptPubKey, o, true);
out.pushKV("scriptPubKey", o);
vout.push_back(out);
}
entry.pushKV("vout", vout);
if (!hashBlock.IsNull())
entry.pushKV("blockhash", hashBlock.GetHex());
entry.pushKV("hex", EncodeHexTx(tx)); // the hex-encoded transaction. used the name "hex" to be consistent with the verbose output of "getrawtransaction".
}
示例2: BatchWrite
bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) {
CDBBatch batch(db);
size_t count = 0;
size_t changed = 0;
for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
if (it->second.flags & CCoinsCacheEntry::DIRTY) {
if (it->second.coins.IsPruned())
batch.Erase(std::make_pair(DB_COINS, it->first));
else
batch.Write(std::make_pair(DB_COINS, it->first), it->second.coins);
changed++;
}
count++;
CCoinsMap::iterator itOld = it++;
mapCoins.erase(itOld);
}
if (!hashBlock.IsNull())
batch.Write(DB_BEST_BLOCK, hashBlock);
LogPrint("coindb", "Committing %u changed transactions (out of %u) to coin database...\n", (unsigned int)changed, (unsigned int)count);
return db.WriteBatch(batch);
}
示例3: TxToJSON
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(), entry, true, RPCSerializationFlags());
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));
}
}
}
示例4: TxToJSON
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));
}
}
}
示例5: runtime_error
UniValue
name_pending (const UniValue& params, bool fHelp)
{
if (fHelp || params.size () > 1)
throw std::runtime_error (
"name_pending (\"name\")\n"
"\nList unconfirmed name operations in the mempool.\n"
"\nIf a name is given, only check for operations on this name.\n"
"\nArguments:\n"
"1. \"name\" (string, optional) only look for this name\n"
"\nResult:\n"
"[\n"
" {\n"
" \"op\": xxxx (string) the operation being performed\n"
" \"name\": xxxx (string) the name operated on\n"
" \"value\": xxxx (string) the name's new value\n"
" \"txid\": xxxx (string) the txid corresponding to the operation\n"
" \"ismine\": xxxx (boolean) whether the name is owned by the wallet\n"
" },\n"
" ...\n"
"]\n"
+ HelpExampleCli ("name_pending", "")
+ HelpExampleCli ("name_pending", "\"d/domob\"")
+ HelpExampleRpc ("name_pending", "")
);
#ifdef ENABLE_WALLET
LOCK2 (pwalletMain ? &pwalletMain->cs_wallet : NULL, mempool.cs);
#else
LOCK (mempool.cs);
#endif
std::vector<uint256> txHashes;
if (params.size () == 0)
mempool.queryHashes (txHashes);
else
{
const std::string name = params[0].get_str ();
const valtype vchName = ValtypeFromString (name);
const uint256 txid = mempool.getTxForName (vchName);
if (!txid.IsNull ())
txHashes.push_back (txid);
}
UniValue arr(UniValue::VARR);
for (std::vector<uint256>::const_iterator i = txHashes.begin ();
i != txHashes.end (); ++i)
{
std::shared_ptr<const CTransaction> tx = mempool.get (*i);
if (!tx || !tx->IsNamecoin ())
continue;
for (const auto& txOut : tx->vout)
{
const CNameScript op(txOut.scriptPubKey);
if (!op.isNameOp () || !op.isAnyUpdate ())
continue;
const valtype vchName = op.getOpName ();
const valtype vchValue = op.getOpValue ();
const std::string name = ValtypeToString (vchName);
const std::string value = ValtypeToString (vchValue);
std::string strOp;
switch (op.getNameOp ())
{
case OP_NAME_FIRSTUPDATE:
strOp = "name_firstupdate";
break;
case OP_NAME_UPDATE:
strOp = "name_update";
break;
default:
assert (false);
}
UniValue obj(UniValue::VOBJ);
obj.push_back (Pair ("op", strOp));
obj.push_back (Pair ("name", name));
obj.push_back (Pair ("value", value));
obj.push_back (Pair ("txid", tx->GetHash ().GetHex ()));
#ifdef ENABLE_WALLET
isminetype mine = ISMINE_NO;
if (pwalletMain)
mine = IsMine (*pwalletMain, op.getAddress ());
const bool isMine = (mine & ISMINE_SPENDABLE);
obj.push_back (Pair ("ismine", isMine));
#endif
arr.push_back (obj);
}
}
return arr;
}
示例6: ValidateNameDB
bool CCoinsViewDB::ValidateNameDB(CGameDB& gameDb) const
{
/* Skip for genesis block, since there is no game state available yet
(test would fail below). There's not really anything to verify
for the genesis block anyway. */
const uint256 blockHash = GetBestBlock();
if (blockHash.IsNull())
return true;
/* It seems that there are no "const iterators" for LevelDB. Since we
only need read operations on it, use a const-cast to get around
that restriction. */
boost::scoped_ptr<CDBIterator> pcursor(const_cast<CDBWrapper*>(&db)->NewIterator());
pcursor->SeekToFirst();
/* Loop over the total database and read interesting
things to memory. We later use that to check
everything against each other. */
std::set<valtype> namesTotal;
std::set<valtype> namesInDB;
std::set<valtype> namesWithHistory;
std::map<valtype, CAmount> namesInUTXO;
for (; pcursor->Valid(); pcursor->Next())
{
boost::this_thread::interruption_point();
char chType;
if (!pcursor->GetKey(chType))
continue;
switch (chType)
{
case DB_COINS:
{
CCoins coins;
if (!pcursor->GetValue(coins))
return error("%s : failed to read coins", __func__);
BOOST_FOREACH(const CTxOut& txout, coins.vout)
if (!txout.IsNull())
{
const CNameScript nameOp(txout.scriptPubKey);
if (nameOp.isNameOp() && nameOp.isAnyUpdate())
{
const valtype& name = nameOp.getOpName();
if (namesInUTXO.count(name) > 0)
return error("%s : name %s duplicated in UTXO set",
__func__, ValtypeToString(name).c_str());
namesInUTXO.insert(std::make_pair(nameOp.getOpName(),
txout.nValue));
}
}
break;
}
case DB_NAME:
{
std::pair<char, valtype> key;
if (!pcursor->GetKey(key) || key.first != DB_NAME)
return error("%s : failed to read DB_NAME key", __func__);
const valtype& name = key.second;
CNameData data;
if (!pcursor->GetValue(data))
return error("%s : failed to read name value", __func__);
if (namesTotal.count(name) > 0)
return error("%s : name %s duplicated in name index",
__func__, ValtypeToString(name).c_str());
namesTotal.insert(name);
assert(namesInDB.count(name) == 0);
if (!data.isDead ())
namesInDB.insert(name);
break;
}
case DB_NAME_HISTORY:
{
std::pair<char, valtype> key;
if (!pcursor->GetKey(key) || key.first != DB_NAME_HISTORY)
return error("%s : failed to read DB_NAME_HISTORY key",
__func__);
const valtype& name = key.second;
if (namesWithHistory.count(name) > 0)
return error("%s : name %s has duplicate history",
__func__, ValtypeToString(name).c_str());
namesWithHistory.insert(name);
break;
}
default:
break;
}
}
std::map<valtype, CAmount> namesInGame;
GameState state(Params().GetConsensus());
//.........这里部分代码省略.........
示例7: populateRPCTransactionObject
int populateRPCTransactionObject(const CTransaction& tx, const uint256& blockHash, UniValue& txobj, std::string filterAddress, bool extendedDetails, std::string extendedDetailsFilter, int blockHeight)
{
int confirmations = 0;
int64_t blockTime = 0;
int positionInBlock = 0;
if (blockHeight == 0) {
blockHeight = GetHeight();
}
if (!blockHash.IsNull()) {
CBlockIndex* pBlockIndex = GetBlockIndex(blockHash);
if (NULL != pBlockIndex) {
confirmations = 1 + blockHeight - pBlockIndex->nHeight;
blockTime = pBlockIndex->nTime;
blockHeight = pBlockIndex->nHeight;
}
}
// attempt to parse the transaction
CMPTransaction mp_obj;
int parseRC = ParseTransaction(tx, blockHeight, 0, mp_obj, blockTime);
if (parseRC < 0) return MP_TX_IS_NOT_MASTER_PROTOCOL;
const uint256& txid = tx.GetHash();
// DEx BTC payment needs special handling since it's not actually an Omni message - handle and return
if (parseRC > 0) {
if (confirmations <= 0) {
// only confirmed DEx payments are currently supported
return MP_TX_UNCONFIRMED;
}
std::string tmpBuyer, tmpSeller;
uint64_t tmpVout, tmpNValue, tmpPropertyId;
{
LOCK(cs_tally);
p_txlistdb->getPurchaseDetails(txid, 1, &tmpBuyer, &tmpSeller, &tmpVout, &tmpPropertyId, &tmpNValue);
}
UniValue purchases(UniValue::VARR);
if (populateRPCDExPurchases(tx, purchases, filterAddress) <= 0) return -1;
txobj.push_back(Pair("txid", txid.GetHex()));
txobj.push_back(Pair("type", "DEx Purchase"));
txobj.push_back(Pair("sendingaddress", tmpBuyer));
txobj.push_back(Pair("purchases", purchases));
txobj.push_back(Pair("blockhash", blockHash.GetHex()));
txobj.push_back(Pair("blocktime", blockTime));
txobj.push_back(Pair("block", blockHeight));
txobj.push_back(Pair("confirmations", confirmations));
return 0;
}
// check if we're filtering from listtransactions_MP, and if so whether we have a non-match we want to skip
if (!filterAddress.empty() && mp_obj.getSender() != filterAddress && mp_obj.getReceiver() != filterAddress) return -1;
// parse packet and populate mp_obj
if (!mp_obj.interpret_Transaction()) return MP_TX_IS_NOT_MASTER_PROTOCOL;
// obtain validity - only confirmed transactions can be valid
bool valid = false;
if (confirmations > 0) {
LOCK(cs_tally);
valid = getValidMPTX(txid);
positionInBlock = p_OmniTXDB->FetchTransactionPosition(txid);
}
// populate some initial info for the transaction
bool fMine = false;
if (IsMyAddress(mp_obj.getSender()) || IsMyAddress(mp_obj.getReceiver())) fMine = true;
txobj.push_back(Pair("txid", txid.GetHex()));
txobj.push_back(Pair("fee", FormatDivisibleMP(mp_obj.getFeePaid())));
txobj.push_back(Pair("sendingaddress", mp_obj.getSender()));
if (showRefForTx(mp_obj.getType())) txobj.push_back(Pair("referenceaddress", mp_obj.getReceiver()));
txobj.push_back(Pair("ismine", fMine));
txobj.push_back(Pair("version", (uint64_t)mp_obj.getVersion()));
txobj.push_back(Pair("type_int", (uint64_t)mp_obj.getType()));
if (mp_obj.getType() != MSC_TYPE_SIMPLE_SEND) { // Type 0 will add "Type" attribute during populateRPCTypeSimpleSend
txobj.push_back(Pair("type", mp_obj.getTypeString()));
}
// populate type specific info and extended details if requested
// extended details are not available for unconfirmed transactions
if (confirmations <= 0) extendedDetails = false;
populateRPCTypeInfo(mp_obj, txobj, mp_obj.getType(), extendedDetails, extendedDetailsFilter, confirmations);
// state and chain related information
if (confirmations != 0 && !blockHash.IsNull()) {
txobj.push_back(Pair("valid", valid));
if (!valid) {
txobj.push_back(Pair("invalidreason", p_OmniTXDB->FetchInvalidReason(txid)));
}
txobj.push_back(Pair("blockhash", blockHash.GetHex()));
txobj.push_back(Pair("blocktime", blockTime));
txobj.push_back(Pair("positioninblock", positionInBlock));
}
if (confirmations != 0) {
txobj.push_back(Pair("block", blockHeight));
}
txobj.push_back(Pair("confirmations", confirmations));
// finished
//.........这里部分代码省略.........
示例8: ValidateNameDB
bool CCoinsViewDB::ValidateNameDB() const
{
const uint256 blockHash = GetBestBlock();
int nHeight;
if (blockHash.IsNull())
nHeight = 0;
else
nHeight = mapBlockIndex.find(blockHash)->second->nHeight;
/* It seems that there are no "const iterators" for LevelDB. Since we
only need read operations on it, use a const-cast to get around
that restriction. */
boost::scoped_ptr<CDBIterator> pcursor(const_cast<CDBWrapper*>(&db)->NewIterator());
pcursor->SeekToFirst();
/* Loop over the total database and read interesting
things to memory. We later use that to check
everything against each other. */
std::map<valtype, unsigned> nameHeightsIndex;
std::map<valtype, unsigned> nameHeightsData;
std::set<valtype> namesInDB;
std::set<valtype> namesInUTXO;
std::set<valtype> namesWithHistory;
for (; pcursor->Valid(); pcursor->Next())
{
boost::this_thread::interruption_point();
char chType;
if (!pcursor->GetKey(chType))
continue;
switch (chType)
{
case DB_COINS:
{
CCoins coins;
if (!pcursor->GetValue(coins))
return error("%s : failed to read coins", __func__);
BOOST_FOREACH(const CTxOut& txout, coins.vout)
if (!txout.IsNull())
{
const CNameScript nameOp(txout.scriptPubKey);
if (nameOp.isNameOp() && nameOp.isAnyUpdate())
{
const valtype& name = nameOp.getOpName();
if (namesInUTXO.count(name) > 0)
return error("%s : name %s duplicated in UTXO set",
__func__, ValtypeToString(name).c_str());
namesInUTXO.insert(nameOp.getOpName());
}
}
break;
}
case DB_NAME:
{
std::pair<char, valtype> key;
if (!pcursor->GetKey(key) || key.first != DB_NAME)
return error("%s : failed to read DB_NAME key", __func__);
const valtype& name = key.second;
CNameData data;
if (!pcursor->GetValue(data))
return error("%s : failed to read name value", __func__);
if (nameHeightsData.count(name) > 0)
return error("%s : name %s duplicated in name index",
__func__, ValtypeToString(name).c_str());
nameHeightsData.insert(std::make_pair(name, data.getHeight()));
/* Expiration is checked at height+1, because that matches
how the UTXO set is cleared in ExpireNames. */
assert(namesInDB.count(name) == 0);
if (!data.isExpired(nHeight + 1))
namesInDB.insert(name);
break;
}
case DB_NAME_HISTORY:
{
std::pair<char, valtype> key;
if (!pcursor->GetKey(key) || key.first != DB_NAME_HISTORY)
return error("%s : failed to read DB_NAME_HISTORY key",
__func__);
const valtype& name = key.second;
if (namesWithHistory.count(name) > 0)
return error("%s : name %s has duplicate history",
__func__, ValtypeToString(name).c_str());
namesWithHistory.insert(name);
break;
}
case DB_NAME_EXPIRY:
{
std::pair<char, CNameCache::ExpireEntry> key;
if (!pcursor->GetKey(key) || key.first != DB_NAME_EXPIRY)
return error("%s : failed to read DB_NAME_EXPIRY key",
//.........这里部分代码省略.........
示例9: perform_joinsplit
UniValue AsyncRPCOperation_sendmany::perform_joinsplit(
AsyncJoinSplitInfo & info,
std::vector<boost::optional < ZCIncrementalWitness>> witnesses,
uint256 anchor)
{
if (anchor.IsNull()) {
throw std::runtime_error("anchor is null");
}
if (!(witnesses.size() == info.notes.size())) {
throw runtime_error("number of notes and witnesses do not match");
}
for (size_t i = 0; i < witnesses.size(); i++) {
if (!witnesses[i]) {
throw runtime_error("joinsplit input could not be found in tree");
}
info.vjsin.push_back(JSInput(*witnesses[i], info.notes[i], boost::get<libzcash::SproutSpendingKey>(spendingkey_)));
}
// Make sure there are two inputs and two outputs
while (info.vjsin.size() < ZC_NUM_JS_INPUTS) {
info.vjsin.push_back(JSInput());
}
while (info.vjsout.size() < ZC_NUM_JS_OUTPUTS) {
info.vjsout.push_back(JSOutput());
}
if (info.vjsout.size() != ZC_NUM_JS_INPUTS || info.vjsin.size() != ZC_NUM_JS_OUTPUTS) {
throw runtime_error("unsupported joinsplit input/output counts");
}
CMutableTransaction mtx(tx_);
LogPrint("zrpcunsafe", "%s: creating joinsplit at index %d (vpub_old=%s, vpub_new=%s, in[0]=%s, in[1]=%s, out[0]=%s, out[1]=%s)\n",
getId(),
tx_.vjoinsplit.size(),
FormatMoney(info.vpub_old), FormatMoney(info.vpub_new),
FormatMoney(info.vjsin[0].note.value()), FormatMoney(info.vjsin[1].note.value()),
FormatMoney(info.vjsout[0].value), FormatMoney(info.vjsout[1].value)
);
// Generate the proof, this can take over a minute.
std::array<libzcash::JSInput, ZC_NUM_JS_INPUTS> inputs
{info.vjsin[0], info.vjsin[1]};
std::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS> outputs
{info.vjsout[0], info.vjsout[1]};
std::array<size_t, ZC_NUM_JS_INPUTS> inputMap;
std::array<size_t, ZC_NUM_JS_OUTPUTS> outputMap;
uint256 esk; // payment disclosure - secret
JSDescription jsdesc = JSDescription::Randomized(
mtx.fOverwintered && (mtx.nVersion >= SAPLING_TX_VERSION),
*pzcashParams,
joinSplitPubKey_,
anchor,
inputs,
outputs,
inputMap,
outputMap,
info.vpub_old,
info.vpub_new,
!this->testmode,
&esk); // parameter expects pointer to esk, so pass in address
{
auto verifier = libzcash::ProofVerifier::Strict();
if (!(jsdesc.Verify(*pzcashParams, verifier, joinSplitPubKey_))) {
throw std::runtime_error("error verifying joinsplit");
}
}
mtx.vjoinsplit.push_back(jsdesc);
// Empty output script.
CScript scriptCode;
CTransaction signTx(mtx);
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId_);
// Add the signature
if (!(crypto_sign_detached(&mtx.joinSplitSig[0], NULL,
dataToBeSigned.begin(), 32,
joinSplitPrivKey_
) == 0))
{
throw std::runtime_error("crypto_sign_detached failed");
}
// Sanity check
if (!(crypto_sign_verify_detached(&mtx.joinSplitSig[0],
dataToBeSigned.begin(), 32,
mtx.joinSplitPubKey.begin()
) == 0))
{
throw std::runtime_error("crypto_sign_verify_detached failed");
}
CTransaction rawTx(mtx);
tx_ = rawTx;
//.........这里部分代码省略.........