mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-13 12:33:42 +02:00
CA: CAssetID -> CAsset
This commit is contained in:
parent
892cb984ae
commit
a25f6c6e08
19 changed files with 347 additions and 347 deletions
|
|
@ -268,7 +268,7 @@ class CTTest (BitcoinTestFramework):
|
|||
for i in range(2):
|
||||
rawaddrs.append(self.nodes[1].getnewaddress())
|
||||
|
||||
raw_assets = self.nodes[2].createrawtransaction([{"txid":b_utxos[0]['txid'], "vout":b_utxos[0]['vout'], "nValue":b_utxos[0]['amount']}, {"txid":b_utxos[1]['txid'], "vout":b_utxos[1]['vout'], "nValue":b_utxos[1]['amount'], "assetid":b_utxos[1]['assetid']}, {"txid":t_utxos[0]['txid'], "vout":t_utxos[0]['vout'], "nValue":t_utxos[0]['amount'], "assetid":t_utxos[0]['assetid']}], {rawaddrs[1]:Decimal(t_utxos[0]['amount']), rawaddrs[0]:Decimal(b_utxos[0]['amount']+b_utxos[1]['amount']-Decimal("0.01"))}, 0, {rawaddrs[0]:b_utxos[0]['assetid'], rawaddrs[1]:t_utxos[0]['assetid']})
|
||||
raw_assets = self.nodes[2].createrawtransaction([{"txid":b_utxos[0]['txid'], "vout":b_utxos[0]['vout'], "nValue":b_utxos[0]['amount']}, {"txid":b_utxos[1]['txid'], "vout":b_utxos[1]['vout'], "nValue":b_utxos[1]['amount'], "asset":b_utxos[1]['asset']}, {"txid":t_utxos[0]['txid'], "vout":t_utxos[0]['vout'], "nValue":t_utxos[0]['amount'], "asset":t_utxos[0]['asset']}], {rawaddrs[1]:Decimal(t_utxos[0]['amount']), rawaddrs[0]:Decimal(b_utxos[0]['amount']+b_utxos[1]['amount']-Decimal("0.01"))}, 0, {rawaddrs[0]:b_utxos[0]['asset'], rawaddrs[1]:t_utxos[0]['asset']})
|
||||
|
||||
# Sign unblinded, then blinded
|
||||
signed_assets = self.nodes[2].signrawtransaction(raw_assets)
|
||||
|
|
|
|||
|
|
@ -44,14 +44,14 @@ std::string CFeeRate::ToString() const
|
|||
|
||||
CAmountMap& operator+=(CAmountMap& a, const CAmountMap& b)
|
||||
{
|
||||
for(std::map<CAssetID, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it)
|
||||
for(std::map<CAsset, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it)
|
||||
a[it->first] += it->second;
|
||||
return a;
|
||||
}
|
||||
|
||||
CAmountMap& operator-=(CAmountMap& a, const CAmountMap& b)
|
||||
{
|
||||
for(std::map<CAssetID, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it)
|
||||
for(std::map<CAsset, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it)
|
||||
a[it->first] -= it->second;
|
||||
return a;
|
||||
}
|
||||
|
|
@ -59,9 +59,9 @@ CAmountMap& operator-=(CAmountMap& a, const CAmountMap& b)
|
|||
CAmountMap operator+(const CAmountMap& a, const CAmountMap& b)
|
||||
{
|
||||
CAmountMap c;
|
||||
for(std::map<CAssetID, CAmount>::const_iterator it = a.begin(); it != a.end(); ++it)
|
||||
for(std::map<CAsset, CAmount>::const_iterator it = a.begin(); it != a.end(); ++it)
|
||||
c[it->first] += it->second;
|
||||
for(std::map<CAssetID, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it)
|
||||
for(std::map<CAsset, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it)
|
||||
c[it->first] += it->second;
|
||||
return c;
|
||||
}
|
||||
|
|
@ -69,9 +69,9 @@ CAmountMap operator+(const CAmountMap& a, const CAmountMap& b)
|
|||
CAmountMap operator-(const CAmountMap& a, const CAmountMap& b)
|
||||
{
|
||||
CAmountMap c;
|
||||
for(std::map<CAssetID, CAmount>::const_iterator it = a.begin(); it != a.end(); ++it)
|
||||
for(std::map<CAsset, CAmount>::const_iterator it = a.begin(); it != a.end(); ++it)
|
||||
c[it->first] += it->second;
|
||||
for(std::map<CAssetID, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it)
|
||||
for(std::map<CAsset, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it)
|
||||
c[it->first] -= it->second;
|
||||
return c;
|
||||
}
|
||||
|
|
@ -79,14 +79,14 @@ CAmountMap operator-(const CAmountMap& a, const CAmountMap& b)
|
|||
bool operator<(const CAmountMap& a, const CAmountMap& b)
|
||||
{
|
||||
bool smallerElement = false;
|
||||
for(std::map<CAssetID, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it) {
|
||||
for(std::map<CAsset, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it) {
|
||||
CAmount aValue = a.count(it->first) ? a.find(it->first)->second : 0;
|
||||
if (aValue > it->second)
|
||||
return false;
|
||||
if (aValue < it->second)
|
||||
smallerElement = true;
|
||||
}
|
||||
for(std::map<CAssetID, CAmount>::const_iterator it = a.begin(); it != a.end(); ++it) {
|
||||
for(std::map<CAsset, CAmount>::const_iterator it = a.begin(); it != a.end(); ++it) {
|
||||
CAmount bValue = b.count(it->first) ? b.find(it->first)->second : 0;
|
||||
if (it->second > bValue)
|
||||
return false;
|
||||
|
|
@ -98,12 +98,12 @@ bool operator<(const CAmountMap& a, const CAmountMap& b)
|
|||
|
||||
bool operator<=(const CAmountMap& a, const CAmountMap& b)
|
||||
{
|
||||
for(std::map<CAssetID, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it) {
|
||||
for(std::map<CAsset, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it) {
|
||||
CAmount aValue = a.count(it->first) ? a.find(it->first)->second : 0;
|
||||
if (aValue > it->second)
|
||||
return false;
|
||||
}
|
||||
for(std::map<CAssetID, CAmount>::const_iterator it = a.begin(); it != a.end(); ++it) {
|
||||
for(std::map<CAsset, CAmount>::const_iterator it = a.begin(); it != a.end(); ++it) {
|
||||
CAmount bValue = b.count(it->first) ? b.find(it->first)->second : 0;
|
||||
if (it->second > bValue)
|
||||
return false;
|
||||
|
|
@ -114,14 +114,14 @@ bool operator<=(const CAmountMap& a, const CAmountMap& b)
|
|||
bool operator>(const CAmountMap& a, const CAmountMap& b)
|
||||
{
|
||||
bool largerElement = false;
|
||||
for(std::map<CAssetID, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it) {
|
||||
for(std::map<CAsset, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it) {
|
||||
CAmount aValue = a.count(it->first) ? a.find(it->first)->second : 0;
|
||||
if (aValue < it->second)
|
||||
return false;
|
||||
if (aValue > it->second)
|
||||
largerElement = true;
|
||||
}
|
||||
for(std::map<CAssetID, CAmount>::const_iterator it = a.begin(); it != a.end(); ++it) {
|
||||
for(std::map<CAsset, CAmount>::const_iterator it = a.begin(); it != a.end(); ++it) {
|
||||
CAmount bValue = b.count(it->first) ? b.find(it->first)->second : 0;
|
||||
if (it->second < bValue)
|
||||
return false;
|
||||
|
|
@ -133,11 +133,11 @@ bool operator>(const CAmountMap& a, const CAmountMap& b)
|
|||
|
||||
bool operator>=(const CAmountMap& a, const CAmountMap& b)
|
||||
{
|
||||
for(std::map<CAssetID, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it) {
|
||||
for(std::map<CAsset, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it) {
|
||||
if ((a.count(it->first) ? a.find(it->first)->second : 0) < it->second)
|
||||
return false;
|
||||
}
|
||||
for(std::map<CAssetID, CAmount>::const_iterator it = a.begin(); it != a.end(); ++it) {
|
||||
for(std::map<CAsset, CAmount>::const_iterator it = a.begin(); it != a.end(); ++it) {
|
||||
if (it->second < (b.count(it->first) ? b.find(it->first)->second : 0))
|
||||
return false;
|
||||
}
|
||||
|
|
@ -146,11 +146,11 @@ bool operator>=(const CAmountMap& a, const CAmountMap& b)
|
|||
|
||||
bool operator==(const CAmountMap& a, const CAmountMap& b)
|
||||
{
|
||||
for(std::map<CAssetID, CAmount>::const_iterator it = a.begin(); it != a.end(); ++it) {
|
||||
for(std::map<CAsset, CAmount>::const_iterator it = a.begin(); it != a.end(); ++it) {
|
||||
if ((b.count(it->first) ? b.find(it->first)->second : 0) != it->second)
|
||||
return false;
|
||||
}
|
||||
for(std::map<CAssetID, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it) {
|
||||
for(std::map<CAsset, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it) {
|
||||
if ((a.count(it->first) ? a.find(it->first)->second : 0) != it->second)
|
||||
return false;
|
||||
}
|
||||
|
|
@ -164,7 +164,7 @@ bool operator!=(const CAmountMap& a, const CAmountMap& b)
|
|||
|
||||
bool hasNegativeValue(const CAmountMap& amount)
|
||||
{
|
||||
for(std::map<CAssetID, CAmount>::const_iterator it = amount.begin(); it != amount.end(); ++it) {
|
||||
for(std::map<CAsset, CAmount>::const_iterator it = amount.begin(); it != amount.end(); ++it) {
|
||||
if (it->second < 0)
|
||||
return true;
|
||||
}
|
||||
|
|
@ -173,7 +173,7 @@ bool hasNegativeValue(const CAmountMap& amount)
|
|||
|
||||
bool hasNonPostiveValue(const CAmountMap& amount)
|
||||
{
|
||||
for(std::map<CAssetID, CAmount>::const_iterator it = amount.begin(); it != amount.end(); ++it) {
|
||||
for(std::map<CAsset, CAmount>::const_iterator it = amount.begin(); it != amount.end(); ++it) {
|
||||
if (it->second <= 0)
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,13 +28,13 @@ extern const std::string CURRENCY_UNIT;
|
|||
* For the host currency, the similarly-calculated hash of the chain’s genesis
|
||||
* block is used instead.
|
||||
**/
|
||||
typedef uint256 CAssetID;
|
||||
typedef uint256 CAsset;
|
||||
|
||||
/** The sha256 of Bitcoin genesis block, for easy reference **/
|
||||
static const CAssetID BITCOINID(uint256S("09f663de96be771f50cab5ded00256ffe63773e2eaa9a604092951cc3d7c6621"));
|
||||
static const CAsset BITCOINID(uint256S("09f663de96be771f50cab5ded00256ffe63773e2eaa9a604092951cc3d7c6621"));
|
||||
|
||||
/** Used for consensus fee and general wallet accounting*/
|
||||
typedef std::map<CAssetID, CAmount> CAmountMap;
|
||||
typedef std::map<CAsset, CAmount> CAmountMap;
|
||||
|
||||
CAmountMap& operator+=(CAmountMap& a, const CAmountMap& b);
|
||||
CAmountMap& operator-=(CAmountMap& a, const CAmountMap& b);
|
||||
|
|
|
|||
|
|
@ -271,8 +271,8 @@ static void MutateTxAddOutAddr(CMutableTransaction& tx, const std::string& strIn
|
|||
|
||||
// extract and validate ASSET
|
||||
std::string strAsset = vStrOutAddrParts[2];
|
||||
CAssetID asset(uint256S(strAsset));
|
||||
if (asset == CAssetID())
|
||||
CAsset asset(uint256S(strAsset));
|
||||
if (asset == CAsset())
|
||||
throw std::runtime_error("invalid TX output asset type");
|
||||
|
||||
// build standard output script via GetScriptForDestination()
|
||||
|
|
@ -441,7 +441,7 @@ static void MutateTxBlind(CMutableTransaction& tx, const std::string& strInput)
|
|||
std::vector<CPubKey> output_pubkeys;
|
||||
std::vector<CAmount> input_amounts;
|
||||
std::vector<uint256> input_asset_blinds;
|
||||
std::vector<CAssetID> input_asset_ids;
|
||||
std::vector<CAsset> input_assets;
|
||||
for (size_t nIn = 0; nIn < tx.vin.size(); nIn++) {
|
||||
std::vector<std::string> entry;
|
||||
boost::split(entry, input_blinding[nIn], boost::is_any_of(","));
|
||||
|
|
@ -452,9 +452,9 @@ static void MutateTxBlind(CMutableTransaction& tx, const std::string& strInput)
|
|||
uint256 assetblind;
|
||||
assetblind.SetHex(entry[2]);
|
||||
input_asset_blinds.push_back(assetblind);
|
||||
CAssetID id;
|
||||
CAsset id;
|
||||
id.SetHex(entry[3]);
|
||||
input_asset_ids.push_back(id);
|
||||
input_assets.push_back(id);
|
||||
CAmount value;
|
||||
if (!ParseMoney(entry[0].data(), value))
|
||||
throw std::runtime_error("invalid TX input value");
|
||||
|
|
@ -487,7 +487,7 @@ static void MutateTxBlind(CMutableTransaction& tx, const std::string& strInput)
|
|||
if (fBlindedIns && !fBlindedOuts) {
|
||||
throw std::runtime_error("Confidential inputs without confidential outputs");
|
||||
}
|
||||
BlindOutputs(input_blinds, input_asset_blinds, input_asset_ids, input_amounts, output_blinds, output_asset_blinds, output_pubkeys, tx);
|
||||
BlindOutputs(input_blinds, input_asset_blinds, input_assets, input_amounts, output_blinds, output_asset_blinds, output_pubkeys, tx);
|
||||
}
|
||||
|
||||
static void MutateTxAddOutScript(CMutableTransaction& tx, const std::string& strInput)
|
||||
|
|
@ -510,7 +510,7 @@ static void MutateTxAddOutScript(CMutableTransaction& tx, const std::string& str
|
|||
|
||||
// extract and validate asset
|
||||
std::string strAsset = vStrOutScriptParts[2];
|
||||
CAssetID asset(uint256S(strAsset));
|
||||
CAsset asset(uint256S(strAsset));
|
||||
|
||||
// construct TxOut, append to transaction output list
|
||||
CTxOut txout(asset, value, scriptPubKey);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ public:
|
|||
|
||||
static Blind_ECC_Init ecc_init_on_load;
|
||||
|
||||
bool UnblindOutput(const CKey &key, const CTxOut& txout, CAmount& amount_out, uint256& blinding_factor_out, CAssetID& asset_id_out, uint256& asset_blinding_factor_out)
|
||||
bool UnblindOutput(const CKey &key, const CTxOut& txout, CAmount& amount_out, uint256& blinding_factor_out, CAsset& asset_out, uint256& asset_blinding_factor_out)
|
||||
{
|
||||
if (!key.IsValid()) {
|
||||
return false;
|
||||
|
|
@ -63,25 +63,25 @@ bool UnblindOutput(const CKey &key, const CTxOut& txout, CAmount& amount_out, ui
|
|||
if (!res || amount > (uint64_t)MAX_MONEY || !MoneyRange((CAmount)amount) || msg_size != 64 || secp256k1_generator_generate_blinded(secp256k1_blind_context, &recoveredGen, msg+32, msg+64) != 1 || !memcmp(&gen, &recoveredGen, 33)) {
|
||||
amount_out = 0;
|
||||
blinding_factor_out = uint256();
|
||||
asset_id_out = CAssetID();
|
||||
asset_out = CAsset();
|
||||
asset_blinding_factor_out = uint256();
|
||||
return false;
|
||||
} else {
|
||||
amount_out = (CAmount)amount;
|
||||
asset_id_out = CAssetID(std::vector<unsigned char>(msg, msg+32));
|
||||
asset_out = CAsset(std::vector<unsigned char>(msg, msg+32));
|
||||
asset_blinding_factor_out = uint256(std::vector<unsigned char>(msg+32, msg+64));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
int BlindOutputs(std::vector<uint256 >& input_blinding_factors, const std::vector<uint256 >& input_asset_blinding_factors, const std::vector<CAssetID >& input_asset_ids, const std::vector<CAmount >& input_amounts, std::vector<uint256 >& output_blinding_factors, std::vector<uint256 >& output_asset_blinding_factors, const std::vector<CPubKey>& output_pubkeys, CMutableTransaction& tx)
|
||||
int BlindOutputs(std::vector<uint256 >& input_blinding_factors, const std::vector<uint256 >& input_asset_blinding_factors, const std::vector<CAsset >& input_assets, const std::vector<CAmount >& input_amounts, std::vector<uint256 >& output_blinding_factors, std::vector<uint256 >& output_asset_blinding_factors, const std::vector<CPubKey>& output_pubkeys, CMutableTransaction& tx)
|
||||
{
|
||||
assert(tx.vout.size() == output_blinding_factors.size());
|
||||
assert(tx.vout.size() == output_pubkeys.size());
|
||||
assert(tx.vout.size() == output_asset_blinding_factors.size());
|
||||
assert(tx.vin.size() == input_blinding_factors.size());
|
||||
assert(tx.vin.size() == input_asset_blinding_factors.size());
|
||||
assert(tx.vin.size() == input_asset_ids.size());
|
||||
assert(tx.vin.size() == input_assets.size());
|
||||
assert(tx.vin.size() == input_amounts.size());
|
||||
|
||||
std::vector<unsigned char*> blindptrs;
|
||||
|
|
@ -94,13 +94,13 @@ int BlindOutputs(std::vector<uint256 >& input_blinding_factors, const std::vecto
|
|||
int nBlinded = 0;
|
||||
|
||||
//Surjection proof prep
|
||||
std::vector<secp256k1_fixed_asset_tag> inputAssetIDs;
|
||||
std::vector<secp256k1_fixed_asset_tag> inputAssets;
|
||||
std::vector<secp256k1_generator> inputAssetGenerators;
|
||||
inputAssetIDs.resize(tx.vin.size());
|
||||
inputAssets.resize(tx.vin.size());
|
||||
inputAssetGenerators.resize(tx.vin.size());
|
||||
for (size_t i = 0; i < tx.vin.size(); i++) {
|
||||
memcpy(&inputAssetIDs[i], input_asset_ids[i].begin(), 32);
|
||||
ret = secp256k1_generator_generate_blinded(secp256k1_blind_context, &inputAssetGenerators[i], input_asset_ids[i].begin(), input_asset_blinding_factors[i].begin());
|
||||
memcpy(&inputAssets[i], input_assets[i].begin(), 32);
|
||||
ret = secp256k1_generator_generate_blinded(secp256k1_blind_context, &inputAssetGenerators[i], input_assets[i].begin(), input_asset_blinding_factors[i].begin());
|
||||
assert(ret == 1);
|
||||
}
|
||||
|
||||
|
|
@ -125,7 +125,7 @@ int BlindOutputs(std::vector<uint256 >& input_blinding_factors, const std::vecto
|
|||
CTxOut& out = tx.vout[nOut];
|
||||
// Wallet only understands all-blinded or all-unblinded
|
||||
assert((output_blinding_factors[nOut] != uint256()) == !out.nValue.IsAmount());
|
||||
assert(out.nValue.IsAmount() == out.nAsset.IsAssetID());
|
||||
assert(out.nValue.IsAmount() == out.nAsset.IsAsset());
|
||||
assert(out.nAsset.IsAssetCommitment() == !out.nAsset.vchSurjectionproof.empty());
|
||||
if (output_blinding_factors[nOut] != uint256()) {
|
||||
assert(output_asset_blinding_factors[nOut] != uint256());
|
||||
|
|
@ -153,7 +153,7 @@ int BlindOutputs(std::vector<uint256 >& input_blinding_factors, const std::vecto
|
|||
unsigned char asset_blind[tx.vout.size()][32];
|
||||
secp256k1_pedersen_commitment commit;
|
||||
secp256k1_generator gen;
|
||||
CAssetID assetID;
|
||||
CAsset assetID;
|
||||
|
||||
for (size_t nOut = 0; nOut < tx.vout.size(); nOut++) {
|
||||
CTxOut& out = tx.vout[nOut];
|
||||
|
|
@ -161,7 +161,7 @@ int BlindOutputs(std::vector<uint256 >& input_blinding_factors, const std::vecto
|
|||
CTxOutValue& value = out.nValue;
|
||||
CTxOutAsset& asset = out.nAsset;
|
||||
CAmount amount = value.GetAmount();
|
||||
out.nAsset.GetAssetID(assetID);
|
||||
out.nAsset.GetAsset(assetID);
|
||||
blindedAmounts.push_back(value.GetAmount());
|
||||
|
||||
GetRandBytes(&blind[nBlinded][0], 32);
|
||||
|
|
@ -240,14 +240,14 @@ int BlindOutputs(std::vector<uint256 >& input_blinding_factors, const std::vecto
|
|||
assert(res);
|
||||
|
||||
// Create surjection proof
|
||||
size_t nInputsToSelect = std::min((size_t)3, input_asset_ids.size());
|
||||
size_t nInputsToSelect = std::min((size_t)3, input_assets.size());
|
||||
unsigned char randseed[32];
|
||||
GetRandBytes(randseed, 32);
|
||||
size_t input_index;
|
||||
secp256k1_surjectionproof proof;
|
||||
secp256k1_fixed_asset_tag tag;
|
||||
memcpy(&tag, assetID.begin(), 32);
|
||||
if (secp256k1_surjectionproof_initialize(secp256k1_blind_context, &proof, &input_index, &inputAssetIDs[0], input_asset_ids.size(), nInputsToSelect, &tag, 100, randseed) == 0) {
|
||||
if (secp256k1_surjectionproof_initialize(secp256k1_blind_context, &proof, &input_index, &inputAssets[0], input_assets.size(), nInputsToSelect, &tag, 100, randseed) == 0) {
|
||||
// actually failed to blind this one
|
||||
return nBlinded-1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,19 +5,19 @@
|
|||
#include "pubkey.h"
|
||||
#include "primitives/transaction.h"
|
||||
|
||||
bool UnblindOutput(const CKey& blinding_key, const CTxOut& txout, CAmount& amount_out, uint256& blinding_factor_out, CAssetID& asset_id_out, uint256& asset_blinding_factor_out);
|
||||
bool UnblindOutput(const CKey& blinding_key, const CTxOut& txout, CAmount& amount_out, uint256& blinding_factor_out, CAsset& asset_out, uint256& asset_blinding_factor_out);
|
||||
|
||||
/* Returns the number of ouputs that were successfully blinded.
|
||||
* In many cases a `0` can be fixed by adding an additional output.
|
||||
* @param[in] input_blinding_factors - A vector of input blinding factors that will be used to create the balanced output blinding factors
|
||||
* @param[in] input_asset_blinding_factors - A vector of input asset blinding factors that will be used to create the balanced output blinding factors
|
||||
* @param[in] input_asset_ids - the asset ids of each corresponding input
|
||||
* @param[in] input_assets - the asset ids of each corresponding input
|
||||
* @param[in] input_amounts - the unblinded amounts of each input. This is required only for calls with already-blinded inputs for sum calculations.
|
||||
* @param[in/out] output_blinding_factors - A vector of blinding factors. Null uint256 values are used to signal to the callee that a new blinding is needed. New blinds then replace the blank values.
|
||||
* @param[in/out] output_asset_blinding_factors - A vector of asset blinding factors. Null uint256 values are used to signal to the callee that a new blinding is needed. New blinds then replace the blank values. These values being blind/unblind should correspond to output_blinding_factors.
|
||||
* @param[in] output_pubkeys - If non-null, these pubkeys will be used in conjunction with the non-null passed in output blinding factors.
|
||||
* @param[in/out] tx - The transaction to be modified.
|
||||
*/
|
||||
int BlindOutputs(std::vector<uint256 >& input_blinding_factors, const std::vector<uint256 >& input_asset_blinding_factors, const std::vector<CAssetID >& input_asset_ids, const std::vector<CAmount >& input_amounts, std::vector<uint256 >& output_blinding_factors, std::vector<uint256 >& output_asset_blinding_factors, const std::vector<CPubKey>& output_pubkeys, CMutableTransaction& tx);
|
||||
int BlindOutputs(std::vector<uint256 >& input_blinding_factors, const std::vector<uint256 >& input_asset_blinding_factors, const std::vector<CAsset >& input_assets, const std::vector<CAmount >& input_amounts, std::vector<uint256 >& output_blinding_factors, std::vector<uint256 >& output_asset_blinding_factors, const std::vector<CPubKey>& output_pubkeys, CMutableTransaction& tx);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ static CScript StrHexToScriptWithDefault(std::string strScript, const CScript de
|
|||
return returnScript;
|
||||
}
|
||||
|
||||
static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, const CScript& scriptChallenge, int32_t nVersion, const CAmount& genesisReward, const uint32_t rewardShards, const CAssetID& assetID)
|
||||
static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, const CScript& scriptChallenge, int32_t nVersion, const CAmount& genesisReward, const uint32_t rewardShards, const CAsset& asset)
|
||||
{
|
||||
// Shards must be evenly divisible
|
||||
assert(MAX_MONEY % rewardShards == 0);
|
||||
|
|
@ -40,7 +40,7 @@ static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesi
|
|||
txNew.vout.resize(rewardShards);
|
||||
for (unsigned int i = 0; i < rewardShards; i++) {
|
||||
txNew.vout[i].nValue = genesisReward/rewardShards;
|
||||
txNew.vout[i].nAsset = assetID;
|
||||
txNew.vout[i].nAsset = asset;
|
||||
txNew.vout[i].scriptPubKey = genesisOutputScript;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ protected:
|
|||
std::string strNetworkID;
|
||||
CBlock genesis;
|
||||
uint256 parentGenesisBlockHash;
|
||||
CAssetID bitcoinID;
|
||||
CAsset bitcoinID;
|
||||
std::vector<SeedSpec6> vFixedSeeds;
|
||||
bool fMiningRequiresPeers;
|
||||
bool fDefaultConsistencyChecks;
|
||||
|
|
|
|||
|
|
@ -16,19 +16,19 @@ void CTxOutAsset::SetNull()
|
|||
vchSurjectionproof.clear();
|
||||
}
|
||||
|
||||
bool CTxOutAsset::GetAssetID(CAssetID& assetID) const
|
||||
bool CTxOutAsset::GetAsset(CAsset& asset) const
|
||||
{
|
||||
if (!IsAssetID())
|
||||
if (!IsAsset())
|
||||
return false;
|
||||
std::copy(vchAssetTag.begin() + 1, vchAssetTag.end(), assetID.begin());
|
||||
std::copy(vchAssetTag.begin() + 1, vchAssetTag.end(), asset.begin());
|
||||
return true;
|
||||
}
|
||||
|
||||
void CTxOutAsset::SetToAssetID(const CAssetID& assetID)
|
||||
void CTxOutAsset::SetToAsset(const CAsset& asset)
|
||||
{
|
||||
vchAssetTag.reserve(nAssetTagSize);
|
||||
vchAssetTag.push_back(1);
|
||||
vchAssetTag.insert(vchAssetTag.end(), assetID.begin(), assetID.end());
|
||||
vchAssetTag.insert(vchAssetTag.end(), asset.begin(), asset.end());
|
||||
vchSurjectionproof.clear();
|
||||
}
|
||||
|
||||
|
|
@ -86,10 +86,10 @@ CTxOut::CTxOut(const CTxOutAsset& nAssetIn, const CTxOutValue& nValueIn, CScript
|
|||
|
||||
std::string CTxOut::ToString() const
|
||||
{
|
||||
CAssetID assetID;
|
||||
CAsset asset;
|
||||
std::string strAsset;
|
||||
if (nAsset.IsAssetID() && nAsset.GetAssetID(assetID))
|
||||
strAsset = strprintf("nAsset=%s, ", assetID.ToString());
|
||||
if (nAsset.IsAsset() && nAsset.GetAsset(asset))
|
||||
strAsset = strprintf("nAsset=%s, ", asset.ToString());
|
||||
if (nAsset.IsAssetCommitment())
|
||||
strAsset = std::string("nAsset=UNKNOWN, ");
|
||||
return strprintf("CTxOut(%snValue=%s, scriptPubKey=%s)", strAsset, (nValue.IsAmount() ? strprintf("%d.%08d", nValue.GetAmount() / COIN, nValue.GetAmount() % COIN) : std::string("UNKNOWN")), HexStr(scriptPubKey).substr(0, 30));
|
||||
|
|
@ -175,9 +175,9 @@ bool CTransaction::HasValidFee() const
|
|||
fee = vout[i].nValue.GetAmount();
|
||||
if (fee == 0 || !MoneyRange(fee))
|
||||
return false;
|
||||
CAssetID assetid;
|
||||
vout[i].nAsset.GetAssetID(assetid);
|
||||
totalFee[assetid] += fee;
|
||||
CAsset asset;
|
||||
vout[i].nAsset.GetAsset(asset);
|
||||
totalFee[asset] += fee;
|
||||
}
|
||||
}
|
||||
return MoneyRange(totalFee);
|
||||
|
|
@ -188,9 +188,9 @@ CAmountMap CTransaction::GetFee() const
|
|||
CAmountMap fee;
|
||||
for (unsigned int i = 0; i < vout.size(); i++)
|
||||
if (vout[i].IsFee()) {
|
||||
CAssetID assetid;
|
||||
vout[i].nAsset.GetAssetID(assetid);
|
||||
fee[assetid] += vout[i].nValue.GetAmount();
|
||||
CAsset asset;
|
||||
vout[i].nAsset.GetAsset(asset);
|
||||
fee[asset] += vout[i].nValue.GetAmount();
|
||||
}
|
||||
return fee;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@ public:
|
|||
SetNull();
|
||||
}
|
||||
|
||||
CTxOutAsset(const CAssetID& assetID)
|
||||
CTxOutAsset(const CAsset& asset)
|
||||
{
|
||||
SetToAssetID(assetID);
|
||||
SetToAsset(asset);
|
||||
}
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
|
@ -52,11 +52,11 @@ public:
|
|||
|
||||
void SetNull();
|
||||
|
||||
bool IsAssetID() const
|
||||
bool IsAsset() const
|
||||
{
|
||||
return vchAssetTag.size()==nAssetTagSize && vchAssetTag[0]==1;
|
||||
}
|
||||
bool GetAssetID(CAssetID& assetID) const;
|
||||
bool GetAsset(CAsset& asset) const;
|
||||
|
||||
bool IsAssetCommitment() const
|
||||
{
|
||||
|
|
@ -75,7 +75,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
void SetToAssetID(const CAssetID& assetID);
|
||||
void SetToAsset(const CAsset& asset);
|
||||
};
|
||||
|
||||
class CTxOutValue
|
||||
|
|
@ -222,8 +222,8 @@ public:
|
|||
{
|
||||
if (!nValue.IsAmount())
|
||||
return false; // FIXME
|
||||
CAssetID assetid;
|
||||
if (!nAsset.GetAssetID(assetid) || assetid != BITCOINID)
|
||||
CAsset asset;
|
||||
if (!nAsset.GetAsset(asset) || asset != BITCOINID)
|
||||
return false;
|
||||
//Withdrawlocks are evaluated at a higher, static feerate
|
||||
//to ensure peg-outs are IsStandard on mainchain
|
||||
|
|
@ -234,8 +234,8 @@ public:
|
|||
|
||||
bool IsFee() const
|
||||
{
|
||||
CAssetID assetid;
|
||||
if (scriptPubKey == CScript() && nValue.IsAmount() && nAsset.IsAssetID())
|
||||
CAsset asset;
|
||||
if (scriptPubKey == CScript() && nValue.IsAmount() && nAsset.IsAsset())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,10 +144,10 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
|
|||
}
|
||||
}
|
||||
const CTxOutAsset& asset = txout.nAsset;
|
||||
if (asset.IsAssetID()) {
|
||||
CAssetID assetID;
|
||||
asset.GetAssetID(assetID);
|
||||
out.push_back(Pair("assetid", assetID.GetHex()));
|
||||
if (asset.IsAsset()) {
|
||||
CAsset assetID;
|
||||
asset.GetAsset(assetID);
|
||||
out.push_back(Pair("asset", assetID.GetHex()));
|
||||
}
|
||||
else if (asset.IsAssetCommitment()) {
|
||||
out.push_back(Pair("assettag", HexStr(asset.vchAssetTag)));
|
||||
|
|
@ -230,7 +230,7 @@ UniValue getrawtransaction(const JSONRPCRequest& request)
|
|||
" \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n"
|
||||
" \"fee_value\" : x.xxx, (numeric) The fee value in " + CURRENCY_UNIT + "\n"
|
||||
" \"n\" : n, (numeric) index\n"
|
||||
" \"assetid\" : \"hex\" (string) the asset id, if unblinded\n"
|
||||
" \"asset\" : \"hex\" (string) the asset id, if unblinded\n"
|
||||
" \"assettag\" : \"hex\" (string) the asset tag, if blinded\n"
|
||||
" \"scriptPubKey\" : { (json object)\n"
|
||||
" \"asm\" : \"asm\", (string) the asm\n"
|
||||
|
|
@ -415,7 +415,7 @@ UniValue createrawtransaction(const JSONRPCRequest& request)
|
|||
{
|
||||
if (request.fHelp || request.params.size() < 2 || request.params.size() > 4)
|
||||
throw runtime_error(
|
||||
"createrawtransaction [{\"txid\":\"id\",\"vout\":n,\"amount\":n},...] {\"address\":amount,\"data\":\"hex\",...} ( locktime {\"address\":assetid} )\n"
|
||||
"createrawtransaction [{\"txid\":\"id\",\"vout\":n,\"amount\":n},...] {\"address\":amount,\"data\":\"hex\",...} ( locktime {\"address\":asset} )\n"
|
||||
"\nCreate a transaction spending the given inputs and creating new outputs.\n"
|
||||
"Outputs can be addresses or data.\n"
|
||||
"Returns hex-encoded raw transaction.\n"
|
||||
|
|
@ -429,7 +429,7 @@ UniValue createrawtransaction(const JSONRPCRequest& request)
|
|||
" \"txid\":\"id\", (string, required) The transaction id\n"
|
||||
" \"vout\":n, (numeric, required) The output number\n"
|
||||
" \"amount\": x.xxx, (numeric, required) The amount being spent\n"
|
||||
" \"assetid\": \"string\" (string, optional, default=bitcoin) The asset of the input, as a tag string or a hex value\n"
|
||||
" \"asset\": \"string\" (string, optional, default=bitcoin) The asset of the input, as a tag string or a hex value\n"
|
||||
" \"sequence\":n (numeric, optional) The sequence number\n"
|
||||
" } \n"
|
||||
" ,...\n"
|
||||
|
|
@ -441,7 +441,7 @@ UniValue createrawtransaction(const JSONRPCRequest& request)
|
|||
" ,...\n"
|
||||
" }\n"
|
||||
"3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n"
|
||||
"4. \"output_assetids\" (strings, optional, default=bitcoin) A json object of assetids to addresses\n"
|
||||
"4. \"output_assets\" (strings, optional, default=bitcoin) A json object of assets to addresses\n"
|
||||
" {\n"
|
||||
" \"address\": \"hex\" \n"
|
||||
" ...\n"
|
||||
|
|
@ -451,10 +451,10 @@ UniValue createrawtransaction(const JSONRPCRequest& request)
|
|||
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0,\\\"amount\\\":2.5}]\" \"{\\\"address\\\":2.41}\"")
|
||||
+ HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0,\\\"amount\\\":2.5,\\\"assetid\\\":\\\"myassetid\\\"}]\" \"{\\\"address\\\":2.41}\" 0 \"{\\\"address\\\":\\\"myassetid\\\"}\"")
|
||||
+ HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0,\\\"amount\\\":2.5,\\\"asset\\\":\\\"myasset\\\"}]\" \"{\\\"address\\\":2.41}\" 0 \"{\\\"address\\\":\\\"myasset\\\"}\"")
|
||||
+ HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0,\\\"amount\\\":2.5}]\" \"{\\\"data\\\":\\\"00010203\\\"}\"")
|
||||
+ HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0,\\\"amount\\\":2.5}]\", \"{\\\"address\\\":2.41}\"")
|
||||
+ HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0,\\\"amount\\\":2.5,\\\"assetid\\\":\\\"myassetid\\\"}]\", \"{\\\"address\\\":2.41}\", 0, \"{\\\"address\\\":\\\"myassetid\\\"}\"")
|
||||
+ HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0,\\\"amount\\\":2.5,\\\"asset\\\":\\\"myasset\\\"}]\", \"{\\\"address\\\":2.41}\", 0, \"{\\\"address\\\":\\\"myasset\\\"}\"")
|
||||
+ HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0,\\\"amount\\\":2.5}]\", \"{\\\"data\\\":\\\"00010203\\\"}\"")
|
||||
);
|
||||
|
||||
|
|
@ -474,12 +474,12 @@ UniValue createrawtransaction(const JSONRPCRequest& request)
|
|||
rawTx.nLockTime = nLockTime;
|
||||
}
|
||||
|
||||
UniValue assetids;
|
||||
UniValue assets;
|
||||
if (request.params.size() > 3 && !request.params[3].isNull()) {
|
||||
assetids = request.params[3].get_obj();
|
||||
assets = request.params[3].get_obj();
|
||||
}
|
||||
|
||||
CAssetID bitcoinid(BITCOINID);
|
||||
CAsset bitcoinid(BITCOINID);
|
||||
CAmountMap inputValue;
|
||||
|
||||
for (unsigned int idx = 0; idx < inputs.size(); idx++) {
|
||||
|
|
@ -508,10 +508,10 @@ UniValue createrawtransaction(const JSONRPCRequest& request)
|
|||
|
||||
CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence);
|
||||
|
||||
CAssetID asset(bitcoinid);
|
||||
const UniValue& asset_val = find_value(o, "assetid");
|
||||
CAsset asset(bitcoinid);
|
||||
const UniValue& asset_val = find_value(o, "asset");
|
||||
if (asset_val.isStr()) {
|
||||
asset = CAssetID(ParseHashO(o, "assetid"));
|
||||
asset = CAsset(ParseHashO(o, "asset"));
|
||||
}
|
||||
|
||||
UniValue vout_value = find_value(o, "amount");
|
||||
|
|
@ -530,11 +530,11 @@ UniValue createrawtransaction(const JSONRPCRequest& request)
|
|||
vector<string> addrList = sendTo.getKeys();
|
||||
BOOST_FOREACH(const string& name_, addrList) {
|
||||
// Defaults to bitcoin
|
||||
CAssetID asset(bitcoinid);
|
||||
if (!assetids.isNull()) {
|
||||
if (find_value(assetids, name_).isNull())
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Given output_assetid address is not a valid given output address: ")+name_);
|
||||
asset = CAssetID(ParseHashO(assetids, name_));
|
||||
CAsset asset(bitcoinid);
|
||||
if (!assets.isNull()) {
|
||||
if (find_value(assets, name_).isNull())
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Given output_asset address is not a valid given output address: ")+name_);
|
||||
asset = CAsset(ParseHashO(assets, name_));
|
||||
}
|
||||
|
||||
if (name_ == "data") {
|
||||
|
|
@ -569,7 +569,7 @@ UniValue createrawtransaction(const JSONRPCRequest& request)
|
|||
|
||||
// Now add fee outputs
|
||||
CAmountMap fees = inputValue - outputValue;
|
||||
for(std::map<CAssetID, CAmount>::const_iterator it = fees.begin(); it != fees.end(); it++) {
|
||||
for(std::map<CAsset, CAmount>::const_iterator it = fees.begin(); it != fees.end(); it++) {
|
||||
if (it->second < 0) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid transaction: Value out exceeds value in for some asset type."));
|
||||
}
|
||||
|
|
@ -584,19 +584,19 @@ UniValue createrawtransaction(const JSONRPCRequest& request)
|
|||
|
||||
// Retrieve already-existing output blinds for a given transaction (if known to wallet)
|
||||
// or blank spots to be filled by BlindOutputs
|
||||
void FillOutputBlinds(const CMutableTransaction& tx, bool fUseWallet, std::vector<uint256>& output_value_blinds, std::vector<uint256>& output_asset_blinds, std::vector<CAssetID>& output_asset_ids, std::vector<CPubKey>& output_pubkeys) {
|
||||
void FillOutputBlinds(const CMutableTransaction& tx, bool fUseWallet, std::vector<uint256>& output_value_blinds, std::vector<uint256>& output_asset_blinds, std::vector<CAsset>& output_assets, std::vector<CPubKey>& output_pubkeys) {
|
||||
for (size_t nOut = 0; nOut < tx.vout.size(); nOut++) {
|
||||
if (!tx.vout[nOut].nValue.IsAmount()) {
|
||||
uint256 blinding_factor;
|
||||
uint256 asset_blinding_factor;
|
||||
CAssetID asset_id;
|
||||
CAsset asset;
|
||||
CAmount amount;
|
||||
#ifdef ENABLE_WALLET
|
||||
if (fUseWallet && UnblindOutput(pwalletMain->GetBlindingKey(&tx.vout[nOut].scriptPubKey), tx.vout[nOut], amount, blinding_factor, asset_id, asset_blinding_factor) != 0) {
|
||||
if (fUseWallet && UnblindOutput(pwalletMain->GetBlindingKey(&tx.vout[nOut].scriptPubKey), tx.vout[nOut], amount, blinding_factor, asset, asset_blinding_factor) != 0) {
|
||||
output_value_blinds.push_back(blinding_factor);
|
||||
output_pubkeys.push_back(CPubKey());
|
||||
output_asset_blinds.push_back(asset_blinding_factor);
|
||||
output_asset_ids.push_back(asset_id);
|
||||
output_assets.push_back(asset);
|
||||
} else if (fUseWallet)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter: transaction outputs must be unblinded or to wallet"));
|
||||
#endif
|
||||
|
|
@ -606,7 +606,7 @@ void FillOutputBlinds(const CMutableTransaction& tx, bool fUseWallet, std::vecto
|
|||
output_pubkeys.push_back(CPubKey());
|
||||
output_value_blinds.push_back(uint256());
|
||||
output_asset_blinds.push_back(uint256());
|
||||
output_asset_ids.push_back(CAssetID());
|
||||
output_assets.push_back(CAsset());
|
||||
} else {
|
||||
CPubKey pubkey(tx.vout[nOut].nValue.vchNonceCommitment);
|
||||
if (!pubkey.IsValid()) {
|
||||
|
|
@ -615,7 +615,7 @@ void FillOutputBlinds(const CMutableTransaction& tx, bool fUseWallet, std::vecto
|
|||
output_pubkeys.push_back(pubkey);
|
||||
output_value_blinds.push_back(uint256());
|
||||
output_asset_blinds.push_back(uint256());
|
||||
output_asset_ids.push_back(CAssetID());
|
||||
output_assets.push_back(CAsset());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -641,7 +641,7 @@ UniValue rawblindrawtransaction(const JSONRPCRequest& request)
|
|||
" \"inputamount\" (numeric, required) An amount for each input.\n"
|
||||
" ],\n"
|
||||
"4. [ (array, required) An array with one entry per transaction input.\n"
|
||||
" \"inputassetid\" (string, required) A hex-encoded asset id, one for each input.\n"
|
||||
" \"inputasset\" (string, required) A hex-encoded asset id, one for each input.\n"
|
||||
" ],\n"
|
||||
"5. [ (array, required) An array with one entry per transaction input.\n"
|
||||
" \"inputassetblinder\" (string, required) A hex-encoded asset blinding factor, one for each input.\n"
|
||||
|
|
@ -669,53 +669,53 @@ UniValue rawblindrawtransaction(const JSONRPCRequest& request)
|
|||
|
||||
UniValue inputBlinds = request.params[1].get_array();
|
||||
UniValue inputAmounts = request.params[2].get_array();
|
||||
UniValue inputAssetIDs = request.params[3].get_array();
|
||||
UniValue inputAssets = request.params[3].get_array();
|
||||
UniValue inputAssetBlinds = request.params[4].get_array();
|
||||
|
||||
if (inputBlinds.size() != tx.vin.size()) throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter: one (potentially empty) input blind for each input must be provided"));
|
||||
if (inputAmounts.size() != tx.vin.size()) throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter: one (potentially empty) input blind for each input must be provided"));
|
||||
if (inputAssetIDs.size() != tx.vin.size()) throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter: one (potentially empty) input asset id for each input must be provided"));
|
||||
if (inputAssets.size() != tx.vin.size()) throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter: one (potentially empty) input asset id for each input must be provided"));
|
||||
if (inputAssetBlinds.size() != tx.vin.size()) throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter: one (potentially empty) input asset blind for each input must be provided"));
|
||||
|
||||
std::vector<CAmount> input_amounts;
|
||||
std::vector<uint256> input_blinds;
|
||||
std::vector<uint256> input_asset_blinds;
|
||||
std::vector<CAssetID> input_asset_ids;
|
||||
std::vector<CAsset> input_assets;
|
||||
std::vector<uint256> output_value_blinds;
|
||||
std::vector<uint256> output_asset_blinds;
|
||||
std::vector<CAssetID> output_asset_ids;
|
||||
std::vector<CAsset> output_assets;
|
||||
std::vector<CPubKey> output_pubkeys;
|
||||
for (size_t nIn = 0; nIn < tx.vin.size(); nIn++) {
|
||||
if (!inputBlinds[nIn].isStr())
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "input blinds must be an array of hex strings");
|
||||
if (!inputAssetBlinds[nIn].isStr())
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "input asset blinds must be an array of hex strings");
|
||||
if (!inputAssetIDs[nIn].isStr())
|
||||
if (!inputAssets[nIn].isStr())
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "input asset ids must be an array of hex strings");
|
||||
if (!inputAmounts[nIn].isNum())
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Amounts must be numeric.");
|
||||
|
||||
std::string blind(inputBlinds[nIn].get_str());
|
||||
std::string assetblind(inputAssetBlinds[nIn].get_str());
|
||||
std::string assetid(inputAssetIDs[nIn].get_str());
|
||||
std::string asset(inputAssets[nIn].get_str());
|
||||
if (!IsHex(blind) || blind.length() != 32*2)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "input blinds must be an array of 32-byte hex-encoded strings");
|
||||
if (!IsHex(assetblind) || assetblind.length() != 32*2)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "input asset blinds must be an array of 32-byte hex-encoded strings");
|
||||
if (!IsHex(assetid) || assetid.length() != 32*2)
|
||||
if (!IsHex(asset) || asset.length() != 32*2)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "input asset blinds must be an array of 32-byte hex-encoded strings");
|
||||
|
||||
input_blinds.push_back(uint256S(blind));
|
||||
input_asset_blinds.push_back(uint256S(assetblind));
|
||||
input_asset_ids.push_back(CAssetID(uint256S(assetid)));
|
||||
input_assets.push_back(CAsset(uint256S(asset)));
|
||||
input_amounts.push_back(inputAmounts[nIn].get_int64());
|
||||
}
|
||||
|
||||
FillOutputBlinds(tx, false, output_value_blinds, output_asset_blinds, output_asset_ids, output_pubkeys);
|
||||
FillOutputBlinds(tx, false, output_value_blinds, output_asset_blinds, output_assets, output_pubkeys);
|
||||
|
||||
// Since we assume all inputs must be unblinded, we can pass in blank input_amounts to BlindOutputs
|
||||
|
||||
if (!BlindOutputs(input_blinds, input_asset_blinds, input_asset_ids, input_amounts, output_value_blinds, output_asset_blinds, output_pubkeys, tx)) {
|
||||
if (!BlindOutputs(input_blinds, input_asset_blinds, input_assets, input_amounts, output_value_blinds, output_asset_blinds, output_pubkeys, tx)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Unable to blind transaction: add an additional output with a blinding pubkey"));
|
||||
}
|
||||
|
||||
|
|
@ -760,11 +760,11 @@ UniValue blindrawtransaction(const JSONRPCRequest& request)
|
|||
|
||||
std::vector<uint256> input_blinds;
|
||||
std::vector<uint256> input_asset_blinds;
|
||||
std::vector<CAssetID> input_asset_ids;
|
||||
std::vector<CAsset> input_assets;
|
||||
std::vector<CAmount> input_amounts;
|
||||
std::vector<uint256> output_blinds;
|
||||
std::vector<uint256> output_asset_blinds;
|
||||
std::vector<CAssetID> output_asset_ids;
|
||||
std::vector<CAsset> output_assets;
|
||||
std::vector<CPubKey> output_pubkeys;
|
||||
for (size_t nIn = 0; nIn < tx.vin.size(); nIn++) {
|
||||
std::map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.find(tx.vin[nIn].prevout.hash);
|
||||
|
|
@ -776,13 +776,13 @@ UniValue blindrawtransaction(const JSONRPCRequest& request)
|
|||
}
|
||||
input_blinds.push_back(it->second.GetBlindingFactor(tx.vin[nIn].prevout.n));
|
||||
input_asset_blinds.push_back(it->second.GetAssetBlindingFactor(tx.vin[nIn].prevout.n));
|
||||
if (it->second.tx->vout[tx.vin[nIn].prevout.n].nAsset.IsAssetID()) {
|
||||
CAssetID assetID;
|
||||
it->second.tx->vout[tx.vin[nIn].prevout.n].nAsset.GetAssetID(assetID);
|
||||
input_asset_ids.push_back(assetID);
|
||||
if (it->second.tx->vout[tx.vin[nIn].prevout.n].nAsset.IsAsset()) {
|
||||
CAsset asset;
|
||||
it->second.tx->vout[tx.vin[nIn].prevout.n].nAsset.GetAsset(asset);
|
||||
input_assets.push_back(asset);
|
||||
}
|
||||
else {
|
||||
input_asset_ids.push_back(it->second.GetAssetID(tx.vin[nIn].prevout.n));
|
||||
input_assets.push_back(it->second.GetAsset(tx.vin[nIn].prevout.n));
|
||||
}
|
||||
if (it->second.tx->vout[tx.vin[nIn].prevout.n].nValue.IsAmount()) {
|
||||
input_amounts.push_back(it->second.tx->vout[tx.vin[nIn].prevout.n].nValue.GetAmount());
|
||||
|
|
@ -792,9 +792,9 @@ UniValue blindrawtransaction(const JSONRPCRequest& request)
|
|||
}
|
||||
}
|
||||
|
||||
FillOutputBlinds(tx, true, output_blinds, output_asset_blinds, output_asset_ids, output_pubkeys);
|
||||
FillOutputBlinds(tx, true, output_blinds, output_asset_blinds, output_assets, output_pubkeys);
|
||||
|
||||
if (!BlindOutputs(input_blinds, input_asset_blinds, input_asset_ids, input_amounts, output_blinds, output_asset_blinds, output_pubkeys, tx)) {
|
||||
if (!BlindOutputs(input_blinds, input_asset_blinds, input_assets, input_amounts, output_blinds, output_asset_blinds, output_pubkeys, tx)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Unable to blind transaction: add an additional output with a blinding pubkey"));
|
||||
}
|
||||
|
||||
|
|
@ -838,7 +838,7 @@ UniValue decoderawtransaction(const JSONRPCRequest& request)
|
|||
" {\n"
|
||||
" \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n"
|
||||
" \"n\" : n, (numeric) index\n"
|
||||
" \"assetid\" : \"hex\" (string) the asset id, if unblinded\n"
|
||||
" \"asset\" : \"hex\" (string) the asset id, if unblinded\n"
|
||||
" \"assettag\" : \"hex\" (string) the asset tag, if blinded\n"
|
||||
" \"scriptPubKey\" : { (json object)\n"
|
||||
" \"asm\" : \"asm\", (string) the asm\n"
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@ BOOST_AUTO_TEST_CASE(naive_blinding_test)
|
|||
CKey keyDummy;
|
||||
|
||||
// Any asset id will do
|
||||
CAssetID bitcoinID(GetRandHash());
|
||||
CAssetID otherID(GetRandHash());
|
||||
CAssetID unblinded_id;
|
||||
CAsset bitcoinID(GetRandHash());
|
||||
CAsset otherID(GetRandHash());
|
||||
CAsset unblinded_id;
|
||||
uint256 asset_blind;
|
||||
|
||||
unsigned char k1[32] = {1,2,3};
|
||||
|
|
@ -80,7 +80,7 @@ BOOST_AUTO_TEST_CASE(naive_blinding_test)
|
|||
// Try to blind with a single non-fee output, which fails as its blinding factor ends up being zero.
|
||||
std::vector<uint256> input_blinds;
|
||||
std::vector<uint256> input_asset_blinds;
|
||||
std::vector<CAssetID> input_asset_ids;
|
||||
std::vector<CAsset> input_assets;
|
||||
std::vector<CAmount> input_amounts;
|
||||
std::vector<uint256> output_blinds;
|
||||
std::vector<uint256> output_asset_blinds;
|
||||
|
|
@ -89,8 +89,8 @@ BOOST_AUTO_TEST_CASE(naive_blinding_test)
|
|||
input_blinds.push_back(uint256());
|
||||
input_asset_blinds.push_back(uint256());
|
||||
input_asset_blinds.push_back(uint256());
|
||||
input_asset_ids.push_back(bitcoinID);
|
||||
input_asset_ids.push_back(bitcoinID);
|
||||
input_assets.push_back(bitcoinID);
|
||||
input_assets.push_back(bitcoinID);
|
||||
input_amounts.push_back(11);
|
||||
input_amounts.push_back(111);
|
||||
output_blinds.push_back(uint256());
|
||||
|
|
@ -99,7 +99,7 @@ BOOST_AUTO_TEST_CASE(naive_blinding_test)
|
|||
output_asset_blinds.push_back(uint256());
|
||||
output_pubkeys.push_back(pubkey1);
|
||||
output_pubkeys.push_back(CPubKey());
|
||||
BOOST_CHECK(BlindOutputs(input_blinds, input_asset_blinds, input_asset_ids, input_amounts, output_blinds, output_asset_blinds, output_pubkeys, tx3) == 0);
|
||||
BOOST_CHECK(BlindOutputs(input_blinds, input_asset_blinds, input_assets, input_amounts, output_blinds, output_asset_blinds, output_pubkeys, tx3) == 0);
|
||||
|
||||
// Add a dummy output.
|
||||
tx3.vout.resize(3);
|
||||
|
|
@ -108,7 +108,7 @@ BOOST_AUTO_TEST_CASE(naive_blinding_test)
|
|||
output_blinds.push_back(uint256());
|
||||
output_asset_blinds.push_back(uint256());
|
||||
output_pubkeys.push_back(pubkeyDummy);
|
||||
BOOST_CHECK(BlindOutputs(input_blinds, input_asset_blinds, input_asset_ids, input_amounts, output_blinds, output_asset_blinds, output_pubkeys, tx3) == 2);
|
||||
BOOST_CHECK(BlindOutputs(input_blinds, input_asset_blinds, input_assets, input_amounts, output_blinds, output_asset_blinds, output_pubkeys, tx3) == 2);
|
||||
BOOST_CHECK(!tx3.vout[0].nValue.IsAmount());
|
||||
BOOST_CHECK(!tx3.vout[2].nValue.IsAmount());
|
||||
BOOST_CHECK(VerifyAmounts(cache, tx3));
|
||||
|
|
@ -119,9 +119,9 @@ BOOST_AUTO_TEST_CASE(naive_blinding_test)
|
|||
BOOST_CHECK(UnblindOutput(key1, tx3.vout[0], unblinded_amount, blind3, unblinded_id, asset_blind) == 1);
|
||||
BOOST_CHECK(unblinded_amount == 100);
|
||||
BOOST_CHECK(unblinded_id == bitcoinID);
|
||||
CAssetID temp_asset_id;
|
||||
CAsset temp_asset;
|
||||
uint256 temp_asset_blinder;
|
||||
BOOST_CHECK(UnblindOutput(keyDummy, tx3.vout[2], unblinded_amount, blindDummy, temp_asset_id, temp_asset_blinder) == 1);
|
||||
BOOST_CHECK(UnblindOutput(keyDummy, tx3.vout[2], unblinded_amount, blindDummy, temp_asset, temp_asset_blinder) == 1);
|
||||
BOOST_CHECK(unblinded_amount == 0);
|
||||
|
||||
CCoinsModifier in3 = cache.ModifyCoins(ArithToUint256(3));
|
||||
|
|
@ -149,7 +149,7 @@ BOOST_AUTO_TEST_CASE(naive_blinding_test)
|
|||
|
||||
std::vector<uint256> input_blinds;
|
||||
std::vector<uint256> input_asset_blinds;
|
||||
std::vector<CAssetID> input_asset_ids;
|
||||
std::vector<CAsset> input_assets;
|
||||
std::vector<CAmount> input_amounts;
|
||||
std::vector<uint256> output_blinds;
|
||||
std::vector<uint256> output_asset_blinds;
|
||||
|
|
@ -160,8 +160,8 @@ BOOST_AUTO_TEST_CASE(naive_blinding_test)
|
|||
input_asset_blinds.push_back(asset_blind);
|
||||
input_amounts.push_back(111);
|
||||
input_amounts.push_back(100);
|
||||
input_asset_ids.push_back(unblinded_id);
|
||||
input_asset_ids.push_back(unblinded_id);
|
||||
input_assets.push_back(unblinded_id);
|
||||
input_assets.push_back(unblinded_id);
|
||||
output_blinds.push_back(uint256());
|
||||
output_blinds.push_back(uint256());
|
||||
output_blinds.push_back(uint256());
|
||||
|
|
@ -171,7 +171,7 @@ BOOST_AUTO_TEST_CASE(naive_blinding_test)
|
|||
output_pubkeys.push_back(CPubKey());
|
||||
output_pubkeys.push_back(CPubKey());
|
||||
output_pubkeys.push_back(CPubKey());
|
||||
BOOST_CHECK(BlindOutputs(input_blinds, input_asset_blinds, input_asset_ids, input_amounts, output_blinds, output_asset_blinds, output_pubkeys, tx4) == 0); // Blinds nothing
|
||||
BOOST_CHECK(BlindOutputs(input_blinds, input_asset_blinds, input_assets, input_amounts, output_blinds, output_asset_blinds, output_pubkeys, tx4) == 0); // Blinds nothing
|
||||
}
|
||||
|
||||
{
|
||||
|
|
@ -191,7 +191,7 @@ BOOST_AUTO_TEST_CASE(naive_blinding_test)
|
|||
|
||||
std::vector<uint256> input_blinds;
|
||||
std::vector<uint256> input_asset_blinds;
|
||||
std::vector<CAssetID> input_asset_ids;
|
||||
std::vector<CAsset> input_assets;
|
||||
std::vector<CAmount> input_amounts;
|
||||
std::vector<uint256> output_blinds;
|
||||
std::vector<uint256> output_asset_blinds;
|
||||
|
|
@ -203,8 +203,8 @@ BOOST_AUTO_TEST_CASE(naive_blinding_test)
|
|||
input_asset_blinds.push_back(asset_blind);
|
||||
input_amounts.push_back(111);
|
||||
input_amounts.push_back(100);
|
||||
input_asset_ids.push_back(unblinded_id);
|
||||
input_asset_ids.push_back(unblinded_id);
|
||||
input_assets.push_back(unblinded_id);
|
||||
input_assets.push_back(unblinded_id);
|
||||
|
||||
output_blinds.push_back(uint256());
|
||||
output_blinds.push_back(uint256());
|
||||
|
|
@ -219,7 +219,7 @@ BOOST_AUTO_TEST_CASE(naive_blinding_test)
|
|||
output_pubkeys.push_back(pubkey2);
|
||||
output_pubkeys.push_back(CPubKey());
|
||||
|
||||
BOOST_CHECK(BlindOutputs(input_blinds, input_asset_blinds, input_asset_ids, input_amounts, output_blinds, output_asset_blinds, output_pubkeys, tx4) == 2);
|
||||
BOOST_CHECK(BlindOutputs(input_blinds, input_asset_blinds, input_assets, input_amounts, output_blinds, output_asset_blinds, output_pubkeys, tx4) == 2);
|
||||
BOOST_CHECK(!tx4.vout[0].nValue.IsAmount());
|
||||
BOOST_CHECK(tx4.vout[1].nValue.IsAmount());
|
||||
BOOST_CHECK(!tx4.vout[2].nValue.IsAmount());
|
||||
|
|
@ -230,13 +230,13 @@ BOOST_AUTO_TEST_CASE(naive_blinding_test)
|
|||
CWalletTx wtx(&wallet, MakeTransactionRef(tx4));
|
||||
uint256 factor = wtx.GetBlindingFactor(0);
|
||||
uint256 asset_factor = wtx.GetAssetBlindingFactor(0);
|
||||
CAssetID asset_id = wtx.GetAssetID(0);
|
||||
CAsset asset = wtx.GetAsset(0);
|
||||
CPubKey pubkey = wtx.GetBlindingPubKey(0);
|
||||
CAmount amount = wtx.GetValueOut(0);
|
||||
|
||||
BOOST_CHECK(factor == uint256());
|
||||
BOOST_CHECK(asset_factor == uint256());
|
||||
BOOST_CHECK(asset_id == CAssetID());
|
||||
BOOST_CHECK(asset == CAsset());
|
||||
BOOST_CHECK(pubkey == CPubKey());
|
||||
BOOST_CHECK(amount == -1);
|
||||
|
||||
|
|
@ -244,13 +244,13 @@ BOOST_AUTO_TEST_CASE(naive_blinding_test)
|
|||
|
||||
factor = wtx.GetBlindingFactor(0);
|
||||
asset_factor = wtx.GetAssetBlindingFactor(0);
|
||||
asset_id = wtx.GetAssetID(0);
|
||||
asset = wtx.GetAsset(0);
|
||||
pubkey = wtx.GetBlindingPubKey(0);
|
||||
amount = wtx.GetValueOut(0);
|
||||
|
||||
BOOST_CHECK(factor == output_blinds[0]);
|
||||
BOOST_CHECK(asset_factor == output_asset_blinds[0]);
|
||||
BOOST_CHECK(asset_id == unblinded_id);
|
||||
BOOST_CHECK(asset == unblinded_id);
|
||||
BOOST_CHECK(pubkey == output_pubkeys[0]);
|
||||
BOOST_CHECK(amount == 42);
|
||||
|
||||
|
|
@ -258,7 +258,7 @@ BOOST_AUTO_TEST_CASE(naive_blinding_test)
|
|||
|
||||
factor = wtx.GetBlindingFactor(0);
|
||||
asset_factor = wtx.GetAssetBlindingFactor(0);
|
||||
asset_id = wtx.GetAssetID(0);
|
||||
asset = wtx.GetAsset(0);
|
||||
pubkey = wtx.GetBlindingPubKey(0);
|
||||
amount = wtx.GetValueOut(0);
|
||||
|
||||
|
|
@ -268,25 +268,25 @@ BOOST_AUTO_TEST_CASE(naive_blinding_test)
|
|||
|
||||
factor = wtx.GetBlindingFactor(1);
|
||||
asset_factor = wtx.GetAssetBlindingFactor(1);
|
||||
asset_id = wtx.GetAssetID(1);
|
||||
asset = wtx.GetAsset(1);
|
||||
pubkey = wtx.GetBlindingPubKey(1);
|
||||
amount = wtx.GetValueOut(1);
|
||||
|
||||
BOOST_CHECK(factor == output_blinds[1]);
|
||||
BOOST_CHECK(asset_factor == output_asset_blinds[1]);
|
||||
BOOST_CHECK(asset_id == otherID);
|
||||
BOOST_CHECK(asset == otherID);
|
||||
BOOST_CHECK(pubkey == output_pubkeys[1]);
|
||||
BOOST_CHECK(amount == 11);
|
||||
#endif
|
||||
CAmount unblinded_amount;
|
||||
CAssetID asset_id_out;
|
||||
CAsset asset_out;
|
||||
uint256 asset_blinder_out;
|
||||
BOOST_CHECK(UnblindOutput(key1, tx4.vout[0], unblinded_amount, blind4, asset_id_out, asset_blinder_out) == 0);
|
||||
BOOST_CHECK(UnblindOutput(key2, tx4.vout[0], unblinded_amount, blind4, asset_id_out, asset_blinder_out) == 1);
|
||||
BOOST_CHECK(UnblindOutput(key1, tx4.vout[0], unblinded_amount, blind4, asset_out, asset_blinder_out) == 0);
|
||||
BOOST_CHECK(UnblindOutput(key2, tx4.vout[0], unblinded_amount, blind4, asset_out, asset_blinder_out) == 1);
|
||||
BOOST_CHECK(unblinded_amount == 30);
|
||||
BOOST_CHECK(asset_id_out == unblinded_id);
|
||||
BOOST_CHECK(UnblindOutput(key2, tx4.vout[2], unblinded_amount, blind4, asset_id_out, asset_blinder_out) == 1);
|
||||
BOOST_CHECK(asset_id_out == unblinded_id);
|
||||
BOOST_CHECK(asset_out == unblinded_id);
|
||||
BOOST_CHECK(UnblindOutput(key2, tx4.vout[2], unblinded_amount, blind4, asset_out, asset_blinder_out) == 1);
|
||||
BOOST_CHECK(asset_out == unblinded_id);
|
||||
BOOST_CHECK(unblinded_amount == 50);
|
||||
|
||||
CCoinsModifier in4 = cache.ModifyCoins(ArithToUint256(4));
|
||||
|
|
|
|||
|
|
@ -683,9 +683,9 @@ bool VerifyAmounts(const CCoinsViewCache& cache, const CTransaction& tx, std::ve
|
|||
if (val.IsNull() || asset.IsNull())
|
||||
return false;
|
||||
|
||||
if (asset.IsAssetID()) {
|
||||
CAssetID fixedAsset;
|
||||
asset.GetAssetID(fixedAsset);
|
||||
if (asset.IsAsset()) {
|
||||
CAsset fixedAsset;
|
||||
asset.GetAsset(fixedAsset);
|
||||
ret = secp256k1_generator_generate(secp256k1_ctx_verify_amounts, &gen, fixedAsset.begin());
|
||||
assert(ret != 0);
|
||||
}
|
||||
|
|
@ -728,9 +728,9 @@ bool VerifyAmounts(const CCoinsViewCache& cache, const CTransaction& tx, std::ve
|
|||
if (val.vchNonceCommitment.size() > CTxOutValue::nCommittedSize || val.vchRangeproof.size() > 5000)
|
||||
return false;
|
||||
|
||||
if (asset.IsAssetID()) {
|
||||
CAssetID fixedAsset;
|
||||
asset.GetAssetID(fixedAsset);
|
||||
if (asset.IsAsset()) {
|
||||
CAsset fixedAsset;
|
||||
asset.GetAsset(fixedAsset);
|
||||
ret = secp256k1_generator_generate(secp256k1_ctx_verify_amounts, &gen, fixedAsset.begin());
|
||||
assert(ret != 0);
|
||||
}
|
||||
|
|
@ -787,9 +787,9 @@ bool VerifyAmounts(const CCoinsViewCache& cache, const CTransaction& tx, std::ve
|
|||
for (size_t i = 0; i < tx.vin.size(); i++)
|
||||
{
|
||||
const CTxOutAsset& asset = cache.GetOutputFor(tx.vin[i]).nAsset;
|
||||
if (asset.IsAssetID()) {
|
||||
CAssetID fixedAsset;
|
||||
asset.GetAssetID(fixedAsset);
|
||||
if (asset.IsAsset()) {
|
||||
CAsset fixedAsset;
|
||||
asset.GetAsset(fixedAsset);
|
||||
ret = secp256k1_generator_generate(secp256k1_ctx_verify_amounts, &ephemeral_input_tags[i], fixedAsset.begin());
|
||||
assert(ret != 0);
|
||||
}
|
||||
|
|
@ -805,7 +805,7 @@ bool VerifyAmounts(const CCoinsViewCache& cache, const CTransaction& tx, std::ve
|
|||
{
|
||||
const CTxOutAsset& asset = tx.vout[i].nAsset;
|
||||
//No need for surjective proof
|
||||
if (asset.IsAssetID()) {
|
||||
if (asset.IsAsset()) {
|
||||
assert(asset.vchSurjectionproof.size() == 0);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -832,11 +832,11 @@ bool VerifyCoinbaseAmount(const CTransaction& tx, const CAmountMap& mapFees)
|
|||
assert(tx.IsCoinBase());
|
||||
CAmountMap remaining = mapFees;
|
||||
for (unsigned int i = 0; i < tx.vout.size(); i++) {
|
||||
if (!tx.vout[i].nValue.IsAmount() || !tx.vout[i].nAsset.IsAssetID())
|
||||
if (!tx.vout[i].nValue.IsAmount() || !tx.vout[i].nAsset.IsAsset())
|
||||
return false;
|
||||
CAssetID assetid;
|
||||
tx.vout[i].nAsset.GetAssetID(assetid);
|
||||
remaining[assetid] -= tx.vout[i].nValue.GetAmount();
|
||||
CAsset asset;
|
||||
tx.vout[i].nAsset.GetAsset(asset);
|
||||
remaining[asset] -= tx.vout[i].nValue.GetAmount();
|
||||
}
|
||||
return MoneyRange(remaining);
|
||||
}
|
||||
|
|
@ -1902,7 +1902,7 @@ void GenerateAssetEntropy(uint256& entropy, const COutPoint& prevout, const uint
|
|||
entropy = ComputeFastMerkleRoot(leaves);
|
||||
}
|
||||
|
||||
void CalculateAssetID(CAssetID& assetID, const uint256& entropy)
|
||||
void CalculateAsset(CAsset& asset, const uint256& entropy)
|
||||
{
|
||||
static const uint256 kZero = uint256S("0x0000000000000000000000000000000000000000000000000000000000000000");
|
||||
// H_a : asset tag
|
||||
|
|
@ -1912,10 +1912,10 @@ void CalculateAssetID(CAssetID& assetID, const uint256& entropy)
|
|||
leaves.reserve(2);
|
||||
leaves.push_back(entropy);
|
||||
leaves.push_back(kZero);
|
||||
assetID = CAssetID(ComputeFastMerkleRoot(leaves));
|
||||
asset = CAsset(ComputeFastMerkleRoot(leaves));
|
||||
}
|
||||
|
||||
void CalculateReissuanceToken(CAssetID& reissuanceTokenID, const uint256& entropy, bool fConfidential)
|
||||
void CalculateReissuanceToken(CAsset& reissuanceToken, const uint256& entropy, bool fConfidential)
|
||||
{
|
||||
static const uint256 kOne = uint256S("0x0000000000000000000000000000000000000000000000000000000000000001");
|
||||
static const uint256 kTwo = uint256S("0x0000000000000000000000000000000000000000000000000000000000000002");
|
||||
|
|
@ -1929,7 +1929,7 @@ void CalculateReissuanceToken(CAssetID& reissuanceTokenID, const uint256& entrop
|
|||
leaves.reserve(2);
|
||||
leaves.push_back(entropy);
|
||||
leaves.push_back(fConfidential? kTwo: kOne);
|
||||
reissuanceTokenID = CAssetID(ComputeFastMerkleRoot(leaves));
|
||||
reissuanceToken = CAsset(ComputeFastMerkleRoot(leaves));
|
||||
}
|
||||
|
||||
bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, PrecomputedTransactionData& txdata, std::set<std::pair<uint256, COutPoint> >& setWithdrawsSpent, std::vector<CCheck*> *pvChecks)
|
||||
|
|
|
|||
|
|
@ -400,7 +400,7 @@ bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoins
|
|||
* Ricardian contract. See Definition 18 of the confidential assets paper.
|
||||
*
|
||||
* @param[out] entropy The asset entropy, which is used as input to
|
||||
* CalculateAssetID and CalculateReissuanceToken.
|
||||
* CalculateAsset and CalculateReissuanceToken.
|
||||
* @param[in] prevout Reference to the UTXO being spent.
|
||||
* @param[in] contracthash Root hash of the issuer-specified Ricardian
|
||||
* contract.
|
||||
|
|
@ -408,28 +408,28 @@ bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoins
|
|||
void GenerateAssetEntropy(uint256& entropy, const COutPoint& prevout, const uint256& contracthash);
|
||||
|
||||
/**
|
||||
* Derive the assetID from the entropy. See Definintion 19 of the confidential
|
||||
* Derive the asset from the entropy. See Definintion 19 of the confidential
|
||||
* assets paper.
|
||||
*
|
||||
* @param[out] assetID The nonce used as auxiliary input to the Pedersen
|
||||
* @param[out] asset The nonce used as auxiliary input to the Pedersen
|
||||
* commitment setup to derive the unblinded asset tag.
|
||||
* @param[in] entropy The asset entropy returned by GenerateAssetEntropy.
|
||||
*/
|
||||
void CalculateAssetID(CAssetID& assetID, const uint256& entropy);
|
||||
void CalculateAsset(CAsset& asset, const uint256& entropy);
|
||||
|
||||
/**
|
||||
* Derive the asset reissuance token assetID from the entropy and reissuance
|
||||
* Derive the asset reissuance token asset from the entropy and reissuance
|
||||
* parameters (confidential or explicit). See Definition 21 of the confidential
|
||||
* assets paper.
|
||||
*
|
||||
* @param[out] reissuanceTokenID The nonce used as auxiliary input to the
|
||||
* Pedersen commitment setup to derive the
|
||||
* unblinded reissuance asset tag.
|
||||
* @param[in] entropy The asset entropy returned by GenerateAssetEntropy.
|
||||
* @param[in] fConfidential Set to true if the initial issuance was blinded,
|
||||
* false otherwise.
|
||||
* @param[out] reissuanceToken The nonce used as auxiliary input to the
|
||||
* Pedersen commitment setup to derive the
|
||||
* unblinded reissuance asset tag.
|
||||
* @param[in] entropy The asset entropy returned by GenerateAssetEntropy.
|
||||
* @param[in] fConfidential Set to true if the initial issuance was blinded,
|
||||
* false otherwise.
|
||||
*/
|
||||
void CalculateReissuanceToken(CAssetID& reissuanceTokenID, const uint256& entropy, bool fConfidential);
|
||||
void CalculateReissuanceToken(CAsset& reissuanceToken, const uint256& entropy, bool fConfidential);
|
||||
|
||||
/**
|
||||
* Verify the transaction's outputs spend exactly what its inputs provide, plus some excess amount.
|
||||
|
|
@ -444,7 +444,7 @@ bool VerifyAmounts(const CCoinsViewCache& cache, const CTransaction& tx, std::ve
|
|||
|
||||
/**
|
||||
* Verify the amounts of coinbase transactions. It will fail for any blinded amount or type.
|
||||
* Each output must be IsAmount && IsAssetID.
|
||||
* Each output must be IsAmount && IsAsset.
|
||||
*/
|
||||
bool VerifyCoinbaseAmount(const CTransaction& tx, const CAmountMap& mapFees);
|
||||
|
||||
|
|
|
|||
|
|
@ -71,30 +71,30 @@ void EnsureWalletIsUnlocked()
|
|||
UniValue PushAssetBalance(CAmountMap& balance, CWallet* wallet, std::string& strasset)
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
CAssetID id = wallet->GetAssetIDFromLabel(strasset);
|
||||
std::string label = wallet->GetAssetLabelFromID(CAssetID(uint256S(strasset)));
|
||||
if (strasset != "*" && (id == CAssetID() && label == "")) {
|
||||
CAsset id = wallet->GetAssetFromLabel(strasset);
|
||||
std::string label = wallet->GetLabelFromAsset(CAsset(uint256S(strasset)));
|
||||
if (strasset != "*" && (id == CAsset() && label == "")) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Input does not match a known asset tag/label pair.");
|
||||
}
|
||||
else if (id != CAssetID()) {
|
||||
else if (id != CAsset()) {
|
||||
strasset = id.GetHex();
|
||||
}
|
||||
|
||||
if (strasset == "*") {
|
||||
for(std::map<CAssetID, CAmount>::const_iterator it = balance.begin(); it != balance.end(); ++it) {
|
||||
for(std::map<CAsset, CAmount>::const_iterator it = balance.begin(); it != balance.end(); ++it) {
|
||||
// Unknown assets
|
||||
if (it->first == CAssetID())
|
||||
if (it->first == CAsset())
|
||||
continue;
|
||||
UniValue pair(UniValue::VOBJ);
|
||||
if (wallet->mapAssetLabels.count(it->first)) {
|
||||
obj.push_back((Pair(wallet->GetAssetLabelFromID(it->first), ValueFromAmount(it->second))));
|
||||
obj.push_back((Pair(wallet->GetLabelFromAsset(it->first), ValueFromAmount(it->second))));
|
||||
}
|
||||
else
|
||||
obj.push_back(Pair(it->first.GetHex(), ValueFromAmount(it->second)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
return ValueFromAmount(balance[CAssetID(uint256S(strasset))]);
|
||||
return ValueFromAmount(balance[CAsset(uint256S(strasset))]);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
|
@ -386,9 +386,9 @@ UniValue getaddressesbyaccount(const JSONRPCRequest& request)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void SendMoney(const CScript& scriptPubKey, CAmount nValue, CAssetID assetID, bool fSubtractFeeFromAmount, const CPubKey &confidentiality_key, CWalletTx& wtxNew)
|
||||
static void SendMoney(const CScript& scriptPubKey, CAmount nValue, CAsset asset, bool fSubtractFeeFromAmount, const CPubKey &confidentiality_key, CWalletTx& wtxNew)
|
||||
{
|
||||
CAmount curBalance = pwalletMain->GetBalance()[assetID];
|
||||
CAmount curBalance = pwalletMain->GetBalance()[asset];
|
||||
|
||||
// Check amount
|
||||
if (nValue <= 0)
|
||||
|
|
@ -406,7 +406,7 @@ static void SendMoney(const CScript& scriptPubKey, CAmount nValue, CAssetID asse
|
|||
vChangeKey.reserve(2);
|
||||
vChangeKey.emplace_back(pwalletMain);
|
||||
vpChangeKey.push_back(&vChangeKey[0]);
|
||||
if (pwalletMain->GetAssetIDFromLabel("bitcoin") != assetID) {
|
||||
if (pwalletMain->GetAssetFromLabel("bitcoin") != asset) {
|
||||
vChangeKey.emplace_back(pwalletMain);
|
||||
vpChangeKey.push_back(&vChangeKey[1]);
|
||||
}
|
||||
|
|
@ -415,7 +415,7 @@ static void SendMoney(const CScript& scriptPubKey, CAmount nValue, CAssetID asse
|
|||
std::string strError;
|
||||
vector<CRecipient> vecSend;
|
||||
int nChangePosRet = -1;
|
||||
CRecipient recipient = {scriptPubKey, nValue, assetID, confidentiality_key, fSubtractFeeFromAmount};
|
||||
CRecipient recipient = {scriptPubKey, nValue, asset, confidentiality_key, fSubtractFeeFromAmount};
|
||||
vecSend.push_back(recipient);
|
||||
if (!pwalletMain->CreateTransaction(vecSend, wtxNew, vpChangeKey, nFeeRequired, nChangePosRet, strError)) {
|
||||
if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance)
|
||||
|
|
@ -429,9 +429,9 @@ static void SendMoney(const CScript& scriptPubKey, CAmount nValue, CAssetID asse
|
|||
}
|
||||
}
|
||||
|
||||
static void SendMoney(const CTxDestination &address, CAmount nValue, CAssetID assetID, bool fSubtractFeeFromAmount, const CPubKey &confidentiality_key, CWalletTx& wtxNew)
|
||||
static void SendMoney(const CTxDestination &address, CAmount nValue, CAsset asset, bool fSubtractFeeFromAmount, const CPubKey &confidentiality_key, CWalletTx& wtxNew)
|
||||
{
|
||||
SendMoney(GetScriptForDestination(address), nValue, assetID, fSubtractFeeFromAmount, confidentiality_key, wtxNew);
|
||||
SendMoney(GetScriptForDestination(address), nValue, asset, fSubtractFeeFromAmount, confidentiality_key, wtxNew);
|
||||
}
|
||||
|
||||
UniValue sendtoaddress(const JSONRPCRequest& request)
|
||||
|
|
@ -497,10 +497,10 @@ UniValue sendtoaddress(const JSONRPCRequest& request)
|
|||
asset = request.params[5].get_str();
|
||||
}
|
||||
|
||||
CAssetID id(uint256S(asset));
|
||||
if (pwalletMain->GetAssetLabelFromID(CAssetID(uint256S(asset))) == "")
|
||||
id = pwalletMain->GetAssetIDFromLabel(asset);
|
||||
if (id == CAssetID())
|
||||
CAsset id(uint256S(asset));
|
||||
if (pwalletMain->GetLabelFromAsset(CAsset(uint256S(asset))) == "")
|
||||
id = pwalletMain->GetAssetFromLabel(asset);
|
||||
if (id == CAsset())
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Unknown or invalid asset id/label");
|
||||
|
||||
EnsureWalletIsUnlocked();
|
||||
|
|
@ -679,7 +679,7 @@ UniValue getreceivedbyaddress(const JSONRPCRequest& request)
|
|||
if (wtx.tx->vout[i].scriptPubKey == scriptPubKey)
|
||||
if (wtx.GetDepthInMainChain() >= nMinDepth && wtx.GetValueOut(i) >= 0) {
|
||||
CAmountMap wtxValue;
|
||||
wtxValue[wtx.GetAssetID(i)] = wtx.GetValueOut(i);
|
||||
wtxValue[wtx.GetAsset(i)] = wtx.GetValueOut(i);
|
||||
mapAmount += wtxValue;
|
||||
}
|
||||
}
|
||||
|
|
@ -792,7 +792,7 @@ UniValue getbalance(const JSONRPCRequest& request)
|
|||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
if (request.params.size() == 0)
|
||||
return ValueFromAmount(pwalletMain->GetBalance()[pwalletMain->mapAssetIDs["bitcoin"]]);
|
||||
return ValueFromAmount(pwalletMain->GetBalance()[pwalletMain->mapAssets["bitcoin"]]);
|
||||
|
||||
int nMinDepth = 1;
|
||||
if (request.params.size() > 1)
|
||||
|
|
@ -873,7 +873,7 @@ UniValue getunconfirmedbalance(const JSONRPCRequest &request)
|
|||
return PushAssetBalance(balance, pwalletMain, strasset);
|
||||
}
|
||||
|
||||
return ValueFromAmount(balance[pwalletMain->mapAssetIDs["bitcoin"]]);
|
||||
return ValueFromAmount(balance[pwalletMain->mapAssets["bitcoin"]]);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -950,7 +950,7 @@ UniValue sendmany(const JSONRPCRequest& request)
|
|||
" \"address\" (string) Subtract fee from this address\n"
|
||||
" ,...\n"
|
||||
" ]\n"
|
||||
"6. \"output_assetids\" (string, optional, default=bitcoin) a json object of assetids to addresses\n"
|
||||
"6. \"output_assets\" (string, optional, default=bitcoin) a json object of assets to addresses\n"
|
||||
" {\n"
|
||||
" \"address\": \"hex\" \n"
|
||||
" ...\n"
|
||||
|
|
@ -989,11 +989,11 @@ UniValue sendmany(const JSONRPCRequest& request)
|
|||
if (request.params.size() > 4)
|
||||
subtractFeeFromAmount = request.params[4].get_array();
|
||||
|
||||
UniValue assetids;
|
||||
UniValue assets;
|
||||
if (request.params.size() > 5 && !request.params[5].isNull()) {
|
||||
if (strAccount != "")
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "Accounts can not be used with assets.");
|
||||
assetids = request.params[5].get_obj();
|
||||
assets = request.params[5].get_obj();
|
||||
}
|
||||
|
||||
set<CBitcoinAddress> setAddress;
|
||||
|
|
@ -1009,14 +1009,14 @@ UniValue sendmany(const JSONRPCRequest& request)
|
|||
CBitcoinAddress address(name_);
|
||||
|
||||
std::string strasset = "bitcoin";
|
||||
if (!assetids.isNull() && assetids[name_].isStr()) {
|
||||
strasset = assetids[name_].get_str();
|
||||
if (!assets.isNull() && assets[name_].isStr()) {
|
||||
strasset = assets[name_].get_str();
|
||||
}
|
||||
|
||||
CAssetID asset(uint256S(strasset));
|
||||
if (pwalletMain->GetAssetLabelFromID(CAssetID(uint256S(strasset))) == "")
|
||||
asset = pwalletMain->GetAssetIDFromLabel(strasset);
|
||||
if (asset == CAssetID())
|
||||
CAsset asset(uint256S(strasset));
|
||||
if (pwalletMain->GetLabelFromAsset(CAsset(uint256S(strasset))) == "")
|
||||
asset = pwalletMain->GetAssetFromLabel(strasset);
|
||||
if (asset == CAsset())
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Unknown or invalid asset id/label");
|
||||
|
||||
if (!address.IsValid())
|
||||
|
|
@ -1060,14 +1060,14 @@ UniValue sendmany(const JSONRPCRequest& request)
|
|||
// Send
|
||||
std::vector<CReserveKey> vChangeKey;
|
||||
std::vector<CReserveKey*> vpChangeKey;
|
||||
std::set<CAssetID> setAssetIDs;
|
||||
setAssetIDs.insert(pwalletMain->GetAssetIDFromLabel("bitcoin"));
|
||||
std::set<CAsset> setAssets;
|
||||
setAssets.insert(pwalletMain->GetAssetFromLabel("bitcoin"));
|
||||
for (auto recipient : vecSend) {
|
||||
setAssetIDs.insert(recipient.asset);
|
||||
setAssets.insert(recipient.asset);
|
||||
}
|
||||
// Need to reserve or possibly segfault? TODO Diagnose
|
||||
vChangeKey.reserve(setAssetIDs.size());
|
||||
for (unsigned int i = 0; i < setAssetIDs.size(); i++) {
|
||||
vChangeKey.reserve(setAssets.size());
|
||||
for (unsigned int i = 0; i < setAssets.size(); i++) {
|
||||
vChangeKey.emplace_back(pwalletMain);
|
||||
vpChangeKey.push_back(&vChangeKey[i]);
|
||||
}
|
||||
|
|
@ -1276,10 +1276,10 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts)
|
|||
throw JSONRPCError(RPC_WALLET_ERROR, "Accounts are completely disabled for assets.");
|
||||
asset = params[3].get_str();
|
||||
}
|
||||
CAssetID id(uint256S(asset));
|
||||
if (asset != "*" && pwalletMain->GetAssetLabelFromID(CAssetID(uint256S(asset))) == "")
|
||||
id = pwalletMain->GetAssetIDFromLabel(asset);
|
||||
if (asset != "*" && id == CAssetID())
|
||||
CAsset id(uint256S(asset));
|
||||
if (asset != "*" && pwalletMain->GetLabelFromAsset(CAsset(uint256S(asset))) == "")
|
||||
id = pwalletMain->GetAssetFromLabel(asset);
|
||||
if (asset != "*" && id == CAsset())
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Unknown or invalid asset id/label");
|
||||
|
||||
// Tally
|
||||
|
|
@ -1308,7 +1308,7 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts)
|
|||
if (wtx.GetValueOut(i) < 0)
|
||||
continue;
|
||||
|
||||
if (wtx.GetAssetID(i) != id && asset != "*")
|
||||
if (wtx.GetAsset(i) != id && asset != "*")
|
||||
continue;
|
||||
|
||||
CBitcoinAddress bitcoinaddress(address);
|
||||
|
|
@ -1510,7 +1510,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
|
|||
entry.push_back(Pair("category", "send"));
|
||||
entry.push_back(Pair("amount", ValueFromAmount(-s.amount)));
|
||||
entry.push_back(Pair("amountblinder", s.amountBlindingFactor.GetHex()));
|
||||
entry.push_back(Pair("assetid", s.asset.GetHex()));
|
||||
entry.push_back(Pair("asset", s.asset.GetHex()));
|
||||
entry.push_back(Pair("assetblinder", s.assetBlindingFactor.GetHex()));
|
||||
if (pwalletMain->mapAddressBook.count(s.destination))
|
||||
entry.push_back(Pair("label", pwalletMain->mapAddressBook[s.destination].name));
|
||||
|
|
@ -1553,7 +1553,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
|
|||
}
|
||||
entry.push_back(Pair("amount", ValueFromAmount(r.amount)));
|
||||
entry.push_back(Pair("amountblinder", r.amountBlindingFactor.GetHex()));
|
||||
entry.push_back(Pair("assetid", r.asset.GetHex()));
|
||||
entry.push_back(Pair("asset", r.asset.GetHex()));
|
||||
entry.push_back(Pair("assetblinder", r.assetBlindingFactor.GetHex()));
|
||||
if (pwalletMain->mapAddressBook.count(r.destination))
|
||||
entry.push_back(Pair("label", account));
|
||||
|
|
@ -1610,7 +1610,7 @@ UniValue listtransactions(const JSONRPCRequest& request)
|
|||
" associated with an address, transaction id and block details\n"
|
||||
" \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the\n"
|
||||
" 'move' category for moves outbound. It is positive for the 'receive' category,\n"
|
||||
" \"assetid\" (string) The asset id of the amount being moved.)\n"
|
||||
" \"asset\" (string) The asset id of the amount being moved.)\n"
|
||||
" and for the 'move' category for inbound funds.\n"
|
||||
" \"label\": \"label\", (string) A comment for the address/transaction, if any\n"
|
||||
" \"vout\": n, (numeric) the vout value\n"
|
||||
|
|
@ -1932,7 +1932,7 @@ UniValue gettransaction(const JSONRPCRequest& request)
|
|||
" \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n"
|
||||
" \"amount\" : x.xxx, (numeric) The amount in the asset below\n"
|
||||
" \"amountblinder\": \"hex\" (string) The blinding factor of the amount.\n"
|
||||
" \"assetid\": \"asset\" (string) The asset id.\n"
|
||||
" \"asset\": \"asset\" (string) The asset id.\n"
|
||||
" \"assetblinder\": \"hex\" (string) The blinding factor of the asset.\n"
|
||||
" \"label\" : \"label\", (string) A comment for the address/transaction, if any\n"
|
||||
" \"vout\" : n, (numeric) the vout value\n"
|
||||
|
|
@ -1977,7 +1977,7 @@ UniValue gettransaction(const JSONRPCRequest& request)
|
|||
assert(wtx.tx->HasValidFee());
|
||||
CAmount nFee = (wtx.IsFromMe(filter) ? -wtx.tx->GetFee()[BITCOINID] : 0);
|
||||
CAmountMap nNet = nCredit - nDebit;
|
||||
nNet[pwalletMain->GetAssetIDFromLabel("bitcoin")] -= nFee;
|
||||
nNet[pwalletMain->GetAssetFromLabel("bitcoin")] -= nFee;
|
||||
|
||||
entry.push_back(Pair("amount", PushAssetBalance(nNet, pwalletMain, strasset)));
|
||||
if (wtx.IsFromMe(filter))
|
||||
|
|
@ -2592,7 +2592,7 @@ UniValue listunspent(const JSONRPCRequest& request)
|
|||
" \"account\": \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n"
|
||||
" \"scriptPubKey\": \"key\", (string) the script key\n"
|
||||
" \"amount\" : x.xxx, (numeric) the transaction output amount in " + CURRENCY_UNIT + "\n"
|
||||
" \"assetid\": \"hex\" (string) the asset id for this output\n"
|
||||
" \"asset\": \"hex\" (string) the asset id for this output\n"
|
||||
" \"confirmations\": n, (numeric) The number of confirmations\n"
|
||||
" \"serValue\": \"hex\", (string) the output's value commitment\n"
|
||||
" \"blinder\": \"blind\" (string) The blinding factor used for a confidential output (or \"\")\n"
|
||||
|
|
@ -2606,7 +2606,7 @@ UniValue listunspent(const JSONRPCRequest& request)
|
|||
"\nExamples:\n"
|
||||
+ HelpExampleCli("listunspent", "")
|
||||
+ HelpExampleCli("listunspent", "6 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"")
|
||||
+ HelpExampleCli("listunspent", "6 9999999 \"[]\" \"myassetid\"")
|
||||
+ HelpExampleCli("listunspent", "6 9999999 \"[]\" \"myasset\"")
|
||||
+ HelpExampleCli("listunspent", "6 9999999 \"[]\" \"*\"")
|
||||
+ HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"")
|
||||
);
|
||||
|
|
@ -2644,14 +2644,14 @@ UniValue listunspent(const JSONRPCRequest& request)
|
|||
include_unsafe = request.params[3].get_bool();
|
||||
}
|
||||
|
||||
std::string asset = "bitcoin";
|
||||
std::string assetstr = "bitcoin";
|
||||
if (request.params.size() > 4 && request.params[4].isStr()) {
|
||||
asset = request.params[3].get_str();
|
||||
assetstr = request.params[4].get_str();
|
||||
}
|
||||
CAssetID id;
|
||||
if (asset != "*") {
|
||||
id = pwalletMain->GetAssetIDFromString(asset);
|
||||
if (id == CAssetID())
|
||||
CAsset asset;
|
||||
if (assetstr != "*") {
|
||||
asset = pwalletMain->GetAssetFromString(assetstr);
|
||||
if (asset == CAsset())
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Unknown or invalid asset id/label");
|
||||
}
|
||||
|
||||
|
|
@ -2672,11 +2672,11 @@ UniValue listunspent(const JSONRPCRequest& request)
|
|||
continue;
|
||||
|
||||
CAmount nValue = out.tx->GetValueOut(out.i);
|
||||
CAssetID assetid = out.tx->GetAssetID(out.i);
|
||||
if (nValue == -1 || assetid == CAssetID())
|
||||
CAsset assetid = out.tx->GetAsset(out.i);
|
||||
if (nValue == -1 || assetid == CAsset())
|
||||
continue;
|
||||
|
||||
if (asset != "*" && id != assetid) {
|
||||
if (assetstr != "*" && asset != assetid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -2700,7 +2700,7 @@ UniValue listunspent(const JSONRPCRequest& request)
|
|||
|
||||
entry.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
|
||||
entry.push_back(Pair("amount", ValueFromAmount(nValue)));
|
||||
entry.push_back(Pair("assetid", assetid.GetHex()));
|
||||
entry.push_back(Pair("asset", assetid.GetHex()));
|
||||
entry.push_back(Pair("confirmations", out.nDepth));
|
||||
entry.push_back(Pair("spendable", out.fSpendable));
|
||||
entry.push_back(Pair("solvable", out.fSolvable));
|
||||
|
|
@ -3635,7 +3635,7 @@ UniValue addassetlabel(const JSONRPCRequest& request)
|
|||
throw JSONRPCError(RPC_TYPE_ERROR, "Please pick a label between 3 and 32 characters.");
|
||||
}
|
||||
|
||||
pwalletMain->SetAssetPair(label, CAssetID(uint256S(id)));
|
||||
pwalletMain->SetAssetPair(label, CAsset(uint256S(id)));
|
||||
|
||||
return NullUniValue;
|
||||
}
|
||||
|
|
@ -3653,7 +3653,7 @@ UniValue dumpassetlabels(const JSONRPCRequest& request)
|
|||
+ HelpExampleRpc("generateasset", "\"my asset\" 10" )
|
||||
);
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
for (std::map<std::string, CAssetID>::const_iterator it = pwalletMain->mapAssetIDs.begin(); it != pwalletMain->mapAssetIDs.end(); it++) {
|
||||
for (std::map<std::string, CAsset>::const_iterator it = pwalletMain->mapAssets.begin(); it != pwalletMain->mapAssets.end(); it++) {
|
||||
obj.push_back(Pair(it->first, it->second.GetHex()));
|
||||
}
|
||||
return obj;
|
||||
|
|
|
|||
|
|
@ -1230,7 +1230,7 @@ CAmountMap CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) cons
|
|||
if (txin.prevout.n < prev.tx->vout.size()) {
|
||||
if (IsMine(prev.tx->vout[txin.prevout.n]) & filter) {
|
||||
CAmountMap map;
|
||||
map[prev.GetAssetID(txin.prevout.n)] = std::max<CAmount>(0, prev.GetValueOut(txin.prevout.n));
|
||||
map[prev.GetAsset(txin.prevout.n)] = std::max<CAmount>(0, prev.GetValueOut(txin.prevout.n));
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
|
@ -1398,14 +1398,14 @@ bool CWallet::IsHDEnabled()
|
|||
return !hdChain.masterKeyID.IsNull();
|
||||
}
|
||||
|
||||
bool CWallet::SetAssetPair(const std::string& label, const CAssetID& id)
|
||||
bool CWallet::SetAssetPair(const std::string& label, const CAsset& id)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
if (!CWalletDB(strWalletFile).WriteAssetIDLabelPair(id, label) ||
|
||||
!CWalletDB(strWalletFile).WriteAssetLabelIDPair(label, id))
|
||||
if (!CWalletDB(strWalletFile).WriteAssetLabelPair(id, label) ||
|
||||
!CWalletDB(strWalletFile).WriteLabelAssetPair(label, id))
|
||||
throw runtime_error(std::string(__func__) + ": writing asset pair failed");
|
||||
mapAssetLabels[id] = label;
|
||||
mapAssetIDs[label] = id;
|
||||
mapAssets[label] = id;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1480,10 +1480,10 @@ void CWalletTx::GetAmounts(list<COutputEntry>& listReceived,
|
|||
{
|
||||
const CTxOut& txout = tx->vout[i];
|
||||
CAmount nValueOut = GetValueOut(i);
|
||||
CAssetID assetID = GetAssetID(i);
|
||||
CAsset asset = GetAsset(i);
|
||||
|
||||
if (nValueOut >= 0) {
|
||||
nValueUnaccounted[assetID] -= nValueOut;
|
||||
nValueUnaccounted[asset] -= nValueOut;
|
||||
}
|
||||
isminetype fIsMine = nValueOut >= 0 ? pwallet->IsMine(txout) : ISMINE_NO;
|
||||
// Only need to handle txouts if AT LEAST one of these is true:
|
||||
|
|
@ -1520,7 +1520,7 @@ void CWalletTx::GetAmounts(list<COutputEntry>& listReceived,
|
|||
continue;
|
||||
}
|
||||
|
||||
COutputEntry output = {address, nValueOut, assetID, (int)i, GetBlindingPubKey(i), GetBlindingFactor(i), GetAssetBlindingFactor(i)};
|
||||
COutputEntry output = {address, nValueOut, asset, (int)i, GetBlindingPubKey(i), GetBlindingFactor(i), GetAssetBlindingFactor(i)};
|
||||
|
||||
// If we are debited by the transaction, add the output as a "sent" entry
|
||||
if (nDebit > CAmountMap() && !txout.IsFee())
|
||||
|
|
@ -1535,12 +1535,12 @@ void CWalletTx::GetAmounts(list<COutputEntry>& listReceived,
|
|||
if (nValueUnaccounted != CAmountMap() && nDebit > CAmountMap()) {
|
||||
if (nValueUnaccounted > CAmountMap() && nUnaccountedOutputs == 1) {
|
||||
// There is exactly one sent output with unknown value. Reconstruct it.
|
||||
CAssetID unaccountedID;
|
||||
CAsset unaccountedAsset;
|
||||
for (const auto &entry : nValueUnaccounted) {
|
||||
if (entry.second > 0)
|
||||
unaccountedID = entry.first;
|
||||
unaccountedAsset = entry.first;
|
||||
}
|
||||
COutputEntry unaccounted = {addressUnaccounted, nValueUnaccounted[unaccountedID], unaccountedID, voutUnaccounted, CPubKey(), uint256(), uint256()};
|
||||
COutputEntry unaccounted = {addressUnaccounted, nValueUnaccounted[unaccountedAsset], unaccountedAsset, voutUnaccounted, CPubKey(), uint256(), uint256()};
|
||||
listSent.push_back(unaccounted);
|
||||
} else {
|
||||
// It's not simple. Create synthetic unknown output entries for each asset.
|
||||
|
|
@ -1745,9 +1745,9 @@ CAmountMap CWalletTx::GetCredit(unsigned int nTxOut, const isminefilter& filter)
|
|||
{
|
||||
CAmountMap amount;
|
||||
if (pwallet->IsMine(tx->vout[nTxOut]) & filter)
|
||||
amount[GetAssetID(nTxOut)] = GetValueOut(nTxOut);
|
||||
amount[GetAsset(nTxOut)] = GetValueOut(nTxOut);
|
||||
// Can be -1 if someone sent us a transaction using a wrong scanning key:
|
||||
if (amount[CAssetID()] == -1)
|
||||
if (amount[CAsset()] == -1)
|
||||
return CAmountMap();
|
||||
if (!MoneyRange(amount))
|
||||
throw std::runtime_error("CWallet::GetCredit(): value out of range");
|
||||
|
|
@ -1876,7 +1876,7 @@ CAmountMap CWalletTx::GetChange(unsigned int nTxOut) const
|
|||
{
|
||||
CAmountMap amount;
|
||||
if (pwallet->IsChange(tx->vout[nTxOut]))
|
||||
amount[GetAssetID(nTxOut)] = GetValueOut(nTxOut);
|
||||
amount[GetAsset(nTxOut)] = GetValueOut(nTxOut);
|
||||
if (!MoneyRange(amount))
|
||||
throw std::runtime_error("CWallet::GetChange(): value out of range");
|
||||
return amount;
|
||||
|
|
@ -1940,7 +1940,7 @@ bool CWalletTx::IsEquivalentTo(const CWalletTx& _tx) const
|
|||
return CTransaction(tx1) == CTransaction(tx2);
|
||||
}
|
||||
|
||||
void CWalletTx::SetBlindingData(unsigned int nOut, CAmount amountIn, CPubKey pubkeyIn, uint256 blindingfactorIn, const CAssetID& assetIn, uint256 assetBlindingFactorIn) const
|
||||
void CWalletTx::SetBlindingData(unsigned int nOut, CAmount amountIn, CPubKey pubkeyIn, uint256 blindingfactorIn, const CAsset& assetIn, uint256 assetBlindingFactorIn) const
|
||||
{
|
||||
assert(nOut < tx->vout.size());
|
||||
if (mapValue["blindingdata"].size() < (nOut + 1) * 138) {
|
||||
|
|
@ -1962,7 +1962,7 @@ void CWalletTx::SetBlindingData(unsigned int nOut, CAmount amountIn, CPubKey pub
|
|||
|
||||
}
|
||||
|
||||
void CWalletTx::GetBlindingData(unsigned int nOut, CAmount* pamountOut, CPubKey* ppubkeyOut, uint256* pblindingfactorOut, CAssetID* pAssetOut, uint256* passetBlindingFactorOut) const
|
||||
void CWalletTx::GetBlindingData(unsigned int nOut, CAmount* pamountOut, CPubKey* ppubkeyOut, uint256* pblindingfactorOut, CAsset* pAssetOut, uint256* passetBlindingFactorOut) const
|
||||
{
|
||||
// Blinding data is cached in a serialized record mapWallet["blindingdata"].
|
||||
// It contains a concatenation byte vectors, 74 bytes per txout.
|
||||
|
|
@ -1985,7 +1985,7 @@ void CWalletTx::GetBlindingData(unsigned int nOut, CAmount* pamountOut, CPubKey*
|
|||
CAmount amount = -1;
|
||||
CPubKey pubkey;
|
||||
uint256 blindingfactor;
|
||||
CAssetID asset;
|
||||
CAsset asset;
|
||||
uint256 assetBlindingFactor;
|
||||
|
||||
if (*it == 1) {
|
||||
|
|
@ -2033,8 +2033,8 @@ uint256 CWalletTx::GetAssetBlindingFactor(unsigned int nOut) const {
|
|||
return ret;
|
||||
}
|
||||
|
||||
CAssetID CWalletTx::GetAssetID(unsigned int nOut) const {
|
||||
CAssetID ret;
|
||||
CAsset CWalletTx::GetAsset(unsigned int nOut) const {
|
||||
CAsset ret;
|
||||
GetBlindingData(nOut, NULL, NULL, NULL, &ret, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -2322,13 +2322,13 @@ bool CWallet::SelectCoinsMinConf(const CAmountMap& mapTargetValue, const int nCo
|
|||
mapValueRet = CAmountMap();
|
||||
assert(mapTargetValue >= CAmountMap());
|
||||
CAmountMap mapTotalLower;
|
||||
std::map<CAssetID, std::vector<SelectCoin> > mapVValue;
|
||||
std::map<CAsset, std::vector<SelectCoin> > mapVValue;
|
||||
|
||||
// List of values less than target
|
||||
std::map<CAssetID, SelectCoin> mapCoinLowestLarger;
|
||||
std::map<CAsset, SelectCoin > mapCoinLowestLarger;
|
||||
// For all positive assets
|
||||
std::set<CAssetID> setAssetsToMatch;
|
||||
for(std::map<CAssetID, CAmount>::const_iterator it = mapTargetValue.begin(); it != mapTargetValue.end(); it++) {
|
||||
std::set<CAsset> setAssetsToMatch;
|
||||
for(std::map<CAsset, CAmount>::const_iterator it = mapTargetValue.begin(); it != mapTargetValue.end(); it++) {
|
||||
if (it->second <= 0)
|
||||
continue;
|
||||
setAssetsToMatch.insert(it->first);
|
||||
|
|
@ -2343,7 +2343,7 @@ bool CWallet::SelectCoinsMinConf(const CAmountMap& mapTargetValue, const int nCo
|
|||
|
||||
// TODO Remove dust rule, remove need for this
|
||||
CAmountMap mapTargetValuePlusMinChange = mapTargetValue;
|
||||
mapTargetValuePlusMinChange[GetAssetIDFromLabel("bitcoin")] += MIN_CHANGE;
|
||||
mapTargetValuePlusMinChange[GetAssetFromLabel("bitcoin")] += MIN_CHANGE;
|
||||
|
||||
BOOST_FOREACH(const COutput &output, vCoins)
|
||||
{
|
||||
|
|
@ -2360,7 +2360,7 @@ bool CWallet::SelectCoinsMinConf(const CAmountMap& mapTargetValue, const int nCo
|
|||
|
||||
int i = output.i;
|
||||
CAmount n = pcoin->GetValueOut(i);
|
||||
CAssetID asset = pcoin->GetAssetID(i);
|
||||
CAsset asset = pcoin->GetAsset(i);
|
||||
|
||||
if (mapTargetValue.count(asset) && mapTargetValue.at(asset) <= 0)
|
||||
continue;
|
||||
|
|
@ -2390,8 +2390,8 @@ bool CWallet::SelectCoinsMinConf(const CAmountMap& mapTargetValue, const int nCo
|
|||
}
|
||||
|
||||
// Exact match using all coins lower than value
|
||||
for (std::set<CAssetID>::iterator it = setAssetsToMatch.begin(); it != setAssetsToMatch.end(); ) {
|
||||
CAssetID asset = *it;
|
||||
for (std::set<CAsset>::iterator it = setAssetsToMatch.begin(); it != setAssetsToMatch.end(); ) {
|
||||
CAsset asset = *it;
|
||||
if (mapTotalLower.at(asset) == mapTargetValue.at(asset))
|
||||
{
|
||||
for (unsigned int i = 0; i < mapVValue[asset].size(); ++i)
|
||||
|
|
@ -2406,8 +2406,8 @@ bool CWallet::SelectCoinsMinConf(const CAmountMap& mapTargetValue, const int nCo
|
|||
}
|
||||
|
||||
// For any particular asset, if sum of small isn't enough, take smallest larger
|
||||
for (std::set<CAssetID>::iterator it = setAssetsToMatch.begin(); it != setAssetsToMatch.end(); ) {
|
||||
CAssetID asset = *it;
|
||||
for (std::set<CAsset>::iterator it = setAssetsToMatch.begin(); it != setAssetsToMatch.end(); ) {
|
||||
CAsset asset = *it;
|
||||
if (mapTotalLower.at(asset) < mapTargetValue.at(asset))
|
||||
{
|
||||
if (mapCoinLowestLarger.at(asset).second.first == NULL)
|
||||
|
|
@ -2421,8 +2421,8 @@ bool CWallet::SelectCoinsMinConf(const CAmountMap& mapTargetValue, const int nCo
|
|||
}
|
||||
|
||||
// For the assets we haven't yet solved for, we throw each into the stochastic approx section
|
||||
for (std::set<CAssetID>::iterator it = setAssetsToMatch.begin(); it != setAssetsToMatch.end(); ) {
|
||||
CAssetID asset = *it;
|
||||
for (std::set<CAsset>::iterator it = setAssetsToMatch.begin(); it != setAssetsToMatch.end(); ) {
|
||||
CAsset asset = *it;
|
||||
std::vector<SelectCoin> vValue = mapVValue[asset];
|
||||
// Solve subset sum by stochastic approximation
|
||||
std::sort(vValue.begin(), vValue.end(), CompareValueOnly());
|
||||
|
|
@ -2474,7 +2474,7 @@ bool CWallet::SelectCoins(const vector<COutput>& vAvailableCoins, const CAmountM
|
|||
{
|
||||
if (!out.fSpendable)
|
||||
continue;
|
||||
mapValueRet[out.tx->GetAssetID(out.i)] += out.tx->GetValueOut(out.i);
|
||||
mapValueRet[out.tx->GetAsset(out.i)] += out.tx->GetValueOut(out.i);
|
||||
setCoinsRet.insert(make_pair(out.tx, out.i));
|
||||
}
|
||||
return (mapValueRet >= mapTargetValue);
|
||||
|
|
@ -2496,7 +2496,7 @@ bool CWallet::SelectCoins(const vector<COutput>& vAvailableCoins, const CAmountM
|
|||
// Clearly invalid input, fail
|
||||
if (pcoin->tx->vout.size() <= outpoint.n)
|
||||
return false;
|
||||
mapValueFromPresetInputs[pcoin->GetAssetID(outpoint.n)] += pcoin->GetValueOut(outpoint.n);
|
||||
mapValueFromPresetInputs[pcoin->GetAsset(outpoint.n)] += pcoin->GetValueOut(outpoint.n);
|
||||
setPresetCoins.insert(make_pair(pcoin, outpoint.n));
|
||||
} else
|
||||
return false; // TODO: Allow non-wallet inputs
|
||||
|
|
@ -2539,29 +2539,29 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, bool ov
|
|||
vector<CRecipient> vecSend;
|
||||
std::vector<CReserveKey> vChangeKey;
|
||||
std::vector<CReserveKey*> vpChangeKey;
|
||||
std::set<CAssetID> setAssetIDs;
|
||||
std::set<CAsset> setAssets;
|
||||
|
||||
// Turn the txout set into a CRecipient vector
|
||||
for (size_t idx = 0; idx < tx.vout.size(); idx++)
|
||||
{
|
||||
const CTxOut& txOut = tx.vout[idx];
|
||||
if (!txOut.nValue.IsAmount() || !txOut.nAsset.IsAssetID()) {
|
||||
if (!txOut.nValue.IsAmount() || !txOut.nAsset.IsAsset()) {
|
||||
strFailReason = _("Pre-funded amounts must be non-blinded");
|
||||
return false;
|
||||
}
|
||||
CAssetID assetID;
|
||||
txOut.nAsset.GetAssetID(assetID);
|
||||
CRecipient recipient = {txOut.scriptPubKey, txOut.nValue.GetAmount(), assetID, CPubKey(txOut.nValue.vchNonceCommitment), false};
|
||||
CAsset asset;
|
||||
txOut.nAsset.GetAsset(asset);
|
||||
CRecipient recipient = {txOut.scriptPubKey, txOut.nValue.GetAmount(), asset, CPubKey(txOut.nValue.vchNonceCommitment), false};
|
||||
vecSend.push_back(recipient);
|
||||
|
||||
if (setAssetIDs.count(assetID) == 0) {
|
||||
if (setAssets.count(asset) == 0) {
|
||||
vChangeKey.push_back(CReserveKey(this));
|
||||
vpChangeKey.push_back(&vChangeKey[vChangeKey.size()-1]);
|
||||
setAssetIDs.insert(assetID);
|
||||
setAssets.insert(asset);
|
||||
}
|
||||
}
|
||||
// Always add bitcoin, as fees via bitcoin may create change
|
||||
if (setAssetIDs.count(GetAssetIDFromLabel("bitcoin")) == 0) {
|
||||
if (setAssets.count(GetAssetFromLabel("bitcoin")) == 0) {
|
||||
vChangeKey.push_back(CReserveKey(this));
|
||||
vpChangeKey.push_back(&vChangeKey[vChangeKey.size()-1]);
|
||||
}
|
||||
|
|
@ -2615,12 +2615,12 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
|||
int& nChangePosInOut, std::string& strFailReason, const CCoinControl* coinControl, bool sign, std::vector<CAmount> *outAmounts)
|
||||
{
|
||||
CAmountMap mapValue;
|
||||
CAssetID BITCOINID = GetAssetIDFromLabel("bitcoin");
|
||||
CAsset BITCOINID = GetAssetFromLabel("bitcoin");
|
||||
int nChangePosRequest = nChangePosInOut;
|
||||
unsigned int nSubtractFeeFromAmount = 0;
|
||||
for (const auto& recipient : vecSend)
|
||||
{
|
||||
if (mapValue[recipient.asset] < 0 || recipient.nAmount < 0 || recipient.asset == CAssetID())
|
||||
if (mapValue[recipient.asset] < 0 || recipient.nAmount < 0 || recipient.asset == CAsset())
|
||||
{
|
||||
strFailReason = _("Transaction amounts must not be negative");
|
||||
return false;
|
||||
|
|
@ -2761,7 +2761,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
|||
const CAmountMap mapChange = mapValueIn - mapValueToSelect;
|
||||
assert(!hasNegativeValue(mapChange));
|
||||
unsigned int changeCounter = 0;
|
||||
for(std::map<CAssetID, CAmount>::const_iterator it = mapChange.begin(); it != mapChange.end(); ++it) {
|
||||
for(std::map<CAsset, CAmount>::const_iterator it = mapChange.begin(); it != mapChange.end(); ++it) {
|
||||
if (it->second > 0)
|
||||
{
|
||||
// Fill a vout to ourself
|
||||
|
|
@ -2876,18 +2876,18 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
|||
// Create blinded outputs
|
||||
std::vector<uint256> input_blinds;
|
||||
std::vector<uint256> input_asset_blinds;
|
||||
std::vector<CAssetID> input_asset_ids;
|
||||
std::vector<CAsset> input_assets;
|
||||
std::vector<uint256> output_blinds;
|
||||
std::vector<CAmount> input_amounts;
|
||||
std::vector<uint256> output_asset_blinds;
|
||||
std::vector<CAssetID> output_asset_ids;
|
||||
std::vector<CAsset> output_assets;
|
||||
BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins) {
|
||||
uint256 blind = coin.first->GetBlindingFactor(coin.second);
|
||||
input_blinds.push_back(blind);
|
||||
uint256 asset_blind = coin.first->GetAssetBlindingFactor(coin.second);
|
||||
input_asset_blinds.push_back(asset_blind);
|
||||
CAssetID asset_id = coin.first->GetAssetID(coin.second);
|
||||
input_asset_ids.push_back(asset_id);
|
||||
CAsset asset = coin.first->GetAsset(coin.second);
|
||||
input_assets.push_back(asset);
|
||||
CAmount amount = coin.first->GetValueOut(coin.second);
|
||||
input_amounts.push_back(amount);
|
||||
}
|
||||
|
|
@ -2899,26 +2899,26 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
|||
if (outAmounts)
|
||||
outAmounts->push_back(txNew.vout[nOut].nValue.GetAmount());
|
||||
vAmounts.push_back(txNew.vout[nOut].nValue.GetAmount());
|
||||
CAssetID asset;
|
||||
txNew.vout[nOut].nAsset.GetAssetID(asset);
|
||||
output_asset_ids.push_back(asset);
|
||||
CAsset asset;
|
||||
txNew.vout[nOut].nAsset.GetAsset(asset);
|
||||
output_assets.push_back(asset);
|
||||
}
|
||||
|
||||
if (BlindOutputs(input_blinds, input_asset_blinds, input_asset_ids, input_amounts, output_blinds, output_asset_blinds, output_pubkeys, txNew) != numBlindingKeys) {
|
||||
if (BlindOutputs(input_blinds, input_asset_blinds, input_assets, input_amounts, output_blinds, output_asset_blinds, output_pubkeys, txNew) != numBlindingKeys) {
|
||||
// We need a dummy output to put a non-zero blinding factor.
|
||||
// TODO: if fBlindedOutputs, don't use an OP_RETURN but create an (extra) change output
|
||||
// instead, as this does not actually provide better privacy.
|
||||
|
||||
// We need to make sure to dupe an asset that is in input set
|
||||
CTxOut newTxOut(output_asset_ids.back(), 0, CScript() << OP_RETURN);
|
||||
CTxOut newTxOut(output_assets.back(), 0, CScript() << OP_RETURN);
|
||||
txNew.vout.push_back(newTxOut);
|
||||
output_pubkeys.push_back(GetBlindingPubKey(newTxOut.scriptPubKey));
|
||||
output_blinds.push_back(uint256());
|
||||
output_asset_blinds.push_back(uint256());
|
||||
output_asset_ids.push_back(output_asset_ids.back());
|
||||
output_assets.push_back(output_assets.back());
|
||||
vAmounts.push_back(0);
|
||||
// Now it has to succeed
|
||||
bool ret = BlindOutputs(input_blinds, input_asset_blinds, input_asset_ids, input_amounts, output_blinds, output_asset_blinds, output_pubkeys, txNew);
|
||||
bool ret = BlindOutputs(input_blinds, input_asset_blinds, input_assets, input_amounts, output_blinds, output_asset_blinds, output_pubkeys, txNew);
|
||||
assert(ret);
|
||||
}
|
||||
|
||||
|
|
@ -2943,13 +2943,13 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
|||
assert(vAmounts.size() == output_pubkeys.size());
|
||||
assert(output_pubkeys.size() == output_blinds.size());
|
||||
assert(output_blinds.size() == output_asset_blinds.size());
|
||||
assert(output_asset_blinds.size() == output_asset_ids.size());
|
||||
assert(output_asset_blinds.size() == output_assets.size());
|
||||
|
||||
for (unsigned int i = 0; i< vAmounts.size(); i++) {
|
||||
assert((output_pubkeys[i] == CPubKey())==(output_blinds[i] == uint256()));
|
||||
assert((output_pubkeys[i] == CPubKey())==(output_asset_blinds[i] == uint256()));
|
||||
assert(output_asset_ids[i] != CAssetID());
|
||||
wtxNew.SetBlindingData(i, vAmounts[i], output_pubkeys[i], output_blinds[i], output_asset_ids[i], output_asset_blinds[i]);
|
||||
assert(output_assets[i] != CAsset());
|
||||
wtxNew.SetBlindingData(i, vAmounts[i], output_pubkeys[i], output_blinds[i], output_assets[i], output_asset_blinds[i]);
|
||||
}
|
||||
|
||||
// Remove scriptSigs to eliminate the fee calculation dummy signatures
|
||||
|
|
@ -4317,29 +4317,29 @@ bool CMerkleTx::AcceptToMemoryPool(const CAmount& nAbsurdFee, CValidationState&
|
|||
return ::AcceptToMemoryPool(mempool, state, tx, true, NULL, NULL, false, nAbsurdFee);
|
||||
}
|
||||
|
||||
std::string CWallet::GetAssetLabelFromID(const CAssetID& id) const
|
||||
std::string CWallet::GetLabelFromAsset(const CAsset& id) const
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
std::map<CAssetID, std::string>::const_iterator it = mapAssetLabels.find(id);
|
||||
std::map<CAsset, std::string>::const_iterator it = mapAssetLabels.find(id);
|
||||
if (it != mapAssetLabels.end())
|
||||
return it->second;
|
||||
return "";
|
||||
}
|
||||
|
||||
CAssetID CWallet::GetAssetIDFromLabel(const std::string& label) const
|
||||
CAsset CWallet::GetAssetFromLabel(const std::string& label) const
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
std::map<std::string, CAssetID>::const_iterator it = mapAssetIDs.find(label);
|
||||
if (it != mapAssetIDs.end())
|
||||
std::map<std::string, CAsset>::const_iterator it = mapAssets.find(label);
|
||||
if (it != mapAssets.end())
|
||||
return it->second;
|
||||
return CAssetID();
|
||||
return CAsset();
|
||||
}
|
||||
|
||||
CAssetID CWallet::GetAssetIDFromString(const std::string& asset) const
|
||||
CAsset CWallet::GetAssetFromString(const std::string& asset) const
|
||||
{
|
||||
// TODO: may be worth LOCK(cs_wallet) here and do GetAsset* inline instead
|
||||
CAssetID id(uint256S(asset));
|
||||
return GetAssetLabelFromID(id) == "" ? GetAssetIDFromLabel(asset) : id;
|
||||
CAsset id(uint256S(asset));
|
||||
return GetLabelFromAsset(id) == "" ? GetAssetFromLabel(asset) : id;
|
||||
}
|
||||
|
||||
CKey CWallet::GetBlindingKey(const CScript* script) const
|
||||
|
|
@ -4396,25 +4396,25 @@ bool CWallet::AddSpecificBlindingKey(const CScriptID& scriptid, const uint256& k
|
|||
return CWalletDB(strWalletFile).WriteSpecificBlindingKey(scriptid, key);
|
||||
}
|
||||
|
||||
bool CWallet::LoadAssetLabelIDMapping(const std::string& label, const CAssetID& id)
|
||||
bool CWallet::LoadLabelAssetMapping(const std::string& label, const CAsset& id)
|
||||
{
|
||||
AssertLockHeld(cs_wallet);
|
||||
mapAssetIDs[label] = id;
|
||||
mapAssets[label] = id;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CWallet::LoadAssetIDLabelMapping(const CAssetID& id, const std::string& label)
|
||||
bool CWallet::LoadAssetLabelMapping(const CAsset& id, const std::string& label)
|
||||
{
|
||||
AssertLockHeld(cs_wallet);
|
||||
mapAssetLabels[id] = label;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CWallet::ComputeBlindingData(const CTxOut& output, CAmount& amount, CPubKey& pubkey, uint256& blindingfactor, CAssetID& assetID, uint256& assetBlindingFactor) const
|
||||
void CWallet::ComputeBlindingData(const CTxOut& output, CAmount& amount, CPubKey& pubkey, uint256& blindingfactor, CAsset& asset, uint256& assetBlindingFactor) const
|
||||
{
|
||||
if (output.nValue.IsAmount() && output.nAsset.IsAssetID()) {
|
||||
if (output.nValue.IsAmount() && output.nAsset.IsAsset()) {
|
||||
amount = output.nValue.GetAmount();
|
||||
output.nAsset.GetAssetID(assetID);
|
||||
output.nAsset.GetAsset(asset);
|
||||
pubkey = CPubKey();
|
||||
blindingfactor.SetNull();
|
||||
assetBlindingFactor.SetNull();
|
||||
|
|
@ -4425,7 +4425,7 @@ void CWallet::ComputeBlindingData(const CTxOut& output, CAmount& amount, CPubKey
|
|||
if ((blinding_key = GetBlindingKey(&output.scriptPubKey)).IsValid()) {
|
||||
// For outputs using derived blinding.
|
||||
if (UnblindOutput(blinding_key, output, amount, blindingfactor,
|
||||
assetID, assetBlindingFactor)) {
|
||||
asset, assetBlindingFactor)) {
|
||||
pubkey = blinding_key.GetPubKey();
|
||||
return;
|
||||
}
|
||||
|
|
@ -4434,7 +4434,7 @@ void CWallet::ComputeBlindingData(const CTxOut& output, CAmount& amount, CPubKey
|
|||
amount = -1;
|
||||
pubkey = CPubKey();
|
||||
blindingfactor.SetNull();
|
||||
assetID.SetNull();
|
||||
asset.SetNull();
|
||||
assetBlindingFactor.SetNull();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ struct CRecipient
|
|||
{
|
||||
CScript scriptPubKey;
|
||||
CAmount nAmount;
|
||||
CAssetID asset;
|
||||
CAsset asset;
|
||||
CPubKey confidentiality_key;
|
||||
bool fSubtractFeeFromAmount;
|
||||
};
|
||||
|
|
@ -171,7 +171,7 @@ struct COutputEntry
|
|||
{
|
||||
CTxDestination destination;
|
||||
CAmount amount;
|
||||
CAssetID asset;
|
||||
CAsset asset;
|
||||
int vout;
|
||||
CPubKey confidentiality_pubkey;
|
||||
uint256 amountBlindingFactor;
|
||||
|
|
@ -447,10 +447,10 @@ public:
|
|||
std::set<uint256> GetConflicts() const;
|
||||
|
||||
// For use in wallet transaction creation to remember 3rd party values
|
||||
void SetBlindingData(unsigned int nOut, CAmount amountIn, CPubKey pubkeyIn, uint256 blindingfactorIn, const CAssetID& assetIn, uint256 assetBlindingFactorIn) const;
|
||||
void SetBlindingData(unsigned int nOut, CAmount amountIn, CPubKey pubkeyIn, uint256 blindingfactorIn, const CAsset& assetIn, uint256 assetBlindingFactorIn) const;
|
||||
|
||||
private:
|
||||
void GetBlindingData(unsigned int nOut, CAmount* pamountOut, CPubKey* ppubkeyOut, uint256* pblindingfactorOut, CAssetID* pAssetOut, uint256* passetBlindingFactorOut) const;
|
||||
void GetBlindingData(unsigned int nOut, CAmount* pamountOut, CPubKey* ppubkeyOut, uint256* pblindingfactorOut, CAsset* pAssetOut, uint256* passetBlindingFactorOut) const;
|
||||
void WipeUnknownBlindingData() const;
|
||||
|
||||
public:
|
||||
|
|
@ -460,7 +460,7 @@ public:
|
|||
//! Returns either the blinding factor (if it is to us) or 0
|
||||
uint256 GetBlindingFactor(unsigned int nOut) const;
|
||||
uint256 GetAssetBlindingFactor(unsigned int nOut) const;
|
||||
CAssetID GetAssetID(unsigned int nOut) const;
|
||||
CAsset GetAsset(unsigned int nOut) const;
|
||||
CPubKey GetBlindingPubKey(unsigned int nOut) const;
|
||||
};
|
||||
|
||||
|
|
@ -692,8 +692,8 @@ public:
|
|||
MasterKeyMap mapMasterKeys;
|
||||
unsigned int nMasterKeyMaxID;
|
||||
std::map<CScriptID, uint256> mapSpecificBlindingKeys;
|
||||
std::map<CAssetID, std::string> mapAssetLabels;
|
||||
std::map<std::string, CAssetID> mapAssetIDs;
|
||||
std::map<CAsset, std::string> mapAssetLabels;
|
||||
std::map<std::string, CAsset> mapAssets;
|
||||
|
||||
|
||||
CWallet()
|
||||
|
|
@ -920,9 +920,9 @@ public:
|
|||
bool IsAllFromMe(const CTransaction& tx, const isminefilter& filter) const;
|
||||
void SetBestChain(const CBlockLocator& loc) override;
|
||||
|
||||
bool SetAssetPair(const std::string& label, const CAssetID& id);
|
||||
bool LoadAssetLabelIDMapping(const std::string& label, const CAssetID& id);
|
||||
bool LoadAssetIDLabelMapping(const CAssetID&, const std::string&);
|
||||
bool SetAssetPair(const std::string& label, const CAsset& id);
|
||||
bool LoadLabelAssetMapping(const std::string& label, const CAsset& id);
|
||||
bool LoadAssetLabelMapping(const CAsset&, const std::string&);
|
||||
|
||||
DBErrors LoadWallet(bool& fFirstRunRet);
|
||||
DBErrors ZapWalletTx(std::vector<CWalletTx>& vWtx);
|
||||
|
|
@ -1011,21 +1011,21 @@ public:
|
|||
bool AbandonTransaction(const uint256& hashTx);
|
||||
|
||||
/* Returns the label of associated asset id */
|
||||
std::string GetAssetLabelFromID(const CAssetID& id) const;
|
||||
std::string GetLabelFromAsset(const CAsset& id) const;
|
||||
/* Returns asset id corresponding to asset label */
|
||||
CAssetID GetAssetIDFromLabel(const std::string& label) const;
|
||||
CAsset GetAssetFromLabel(const std::string& label) const;
|
||||
/**
|
||||
* Returns asset id corresponding to the given asset expression, which is either an asset label or a hex value.
|
||||
* @param asset A label string or a hex value corresponding to an asset
|
||||
* @return The asset ID for the given expression
|
||||
*/
|
||||
CAssetID GetAssetIDFromString(const std::string& asset) const;
|
||||
CAsset GetAssetFromString(const std::string& asset) const;
|
||||
|
||||
//! script == NULL gives the backward compatible blinding key
|
||||
CKey GetBlindingKey(const CScript* script) const;
|
||||
CPubKey GetBlindingPubKey(const CScript& script) const;
|
||||
|
||||
void ComputeBlindingData(const CTxOut& output, CAmount& amount, CPubKey& pubkey, uint256& blindingfactor, CAssetID& asset, uint256& assetBlindingFactor) const;
|
||||
void ComputeBlindingData(const CTxOut& output, CAmount& amount, CPubKey& pubkey, uint256& blindingfactor, CAsset& asset, uint256& assetBlindingFactor) const;
|
||||
|
||||
/** Mark a transaction as replaced by another transaction (e.g., BIP 125). */
|
||||
bool MarkReplaced(const uint256& originalHash, const uint256& newHash);
|
||||
|
|
|
|||
|
|
@ -214,14 +214,14 @@ bool CWalletDB::WriteBlindingDerivationKey(const uint256& key)
|
|||
return Write(std::string("blindingderivationkey"), key);
|
||||
}
|
||||
|
||||
bool CWalletDB::WriteAssetIDLabelPair(const CAssetID& id, const std::string& label)
|
||||
bool CWalletDB::WriteAssetLabelPair(const CAsset& asset, const std::string& label)
|
||||
{
|
||||
return Write(make_pair(std::string("idlabelmapping"), id), label);
|
||||
return Write(make_pair(std::string("assetlabelmapping"), asset), label);
|
||||
}
|
||||
|
||||
bool CWalletDB::WriteAssetLabelIDPair(const std::string& label, const CAssetID& id)
|
||||
bool CWalletDB::WriteLabelAssetPair(const std::string& label, const CAsset& asset)
|
||||
{
|
||||
return Write(make_pair(std::string("labelidmapping"), label), id);
|
||||
return Write(make_pair(std::string("labelassetmapping"), label), asset);
|
||||
}
|
||||
|
||||
CAmount CWalletDB::GetAccountCreditDebit(const string& strAccount)
|
||||
|
|
@ -577,25 +577,25 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
|
|||
return false;
|
||||
}
|
||||
}
|
||||
else if (strType == "labelidmapping")
|
||||
else if (strType == "labelassetmapping")
|
||||
{
|
||||
string label;
|
||||
ssKey >> label;
|
||||
CAssetID id;
|
||||
ssValue >> id;
|
||||
if (!pwallet->LoadAssetLabelIDMapping(label, id)) {
|
||||
strErr = "Error reading wallet database: LoadAssetLabelIDMapping failed";
|
||||
CAsset asset;
|
||||
ssValue >> asset;
|
||||
if (!pwallet->LoadLabelAssetMapping(label, asset)) {
|
||||
strErr = "Error reading wallet database: LoadLabelAssetMapping failed";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (strType == "idlabelmapping")
|
||||
else if (strType == "assetlabelmapping")
|
||||
{
|
||||
CAssetID id;
|
||||
ssKey >> id;
|
||||
CAsset asset;
|
||||
ssKey >> asset;
|
||||
string label;
|
||||
ssValue >> label;
|
||||
if (!pwallet->LoadAssetIDLabelMapping(id, label)) {
|
||||
strErr = "Error reading wallet database: LoadAssetIDLabelMapping failed";
|
||||
if (!pwallet->LoadAssetLabelMapping(asset, label)) {
|
||||
strErr = "Error reading wallet database: LoadAssetLabelMapping failed";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,8 +170,8 @@ public:
|
|||
bool WriteSpecificBlindingKey(const CScriptID& scriptid, const uint256& key);
|
||||
bool WriteBlindingDerivationKey(const uint256& key);
|
||||
|
||||
bool WriteAssetIDLabelPair(const CAssetID& id, const std::string& label);
|
||||
bool WriteAssetLabelIDPair(const std::string& label, const CAssetID& id);
|
||||
bool WriteAssetLabelPair(const CAsset& asset, const std::string& label);
|
||||
bool WriteLabelAssetPair(const std::string& label, const CAsset& asset);
|
||||
|
||||
DBErrors LoadWallet(CWallet* pwallet);
|
||||
DBErrors FindWalletTx(CWallet* pwallet, std::vector<uint256>& vTxHash, std::vector<CWalletTx>& vWtx);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue