apply patch from @stoffu for sub-addresses
https://github.com/moneroexamples/onion-monero-blockchain-explorer/pull/86#issuecomment-342997868
This commit is contained in:
parent
886d2a5749
commit
ddc6ef7405
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,4 +6,5 @@
|
||||
*.log
|
||||
*.orig
|
||||
tests/
|
||||
build/
|
||||
cmake-build-debug/
|
||||
|
128
src/page.h
128
src/page.h
@ -126,6 +126,7 @@ namespace xmreg
|
||||
crypto::hash hash;
|
||||
crypto::hash prefix_hash;
|
||||
crypto::public_key pk;
|
||||
std::vector<crypto::public_key> additional_pks;
|
||||
uint64_t xmr_inputs;
|
||||
uint64_t xmr_outputs;
|
||||
uint64_t num_nonrct_inputs;
|
||||
@ -1469,11 +1470,22 @@ namespace xmreg
|
||||
// parse string representing given private key
|
||||
crypto::secret_key prv_view_key;
|
||||
|
||||
if (!xmreg::parse_str_secret_key(viewkey_str, prv_view_key))
|
||||
std::vector<crypto::secret_key> multiple_tx_secret_keys;
|
||||
|
||||
if (!xmreg::parse_str_secret_key(viewkey_str, multiple_tx_secret_keys))
|
||||
{
|
||||
cerr << "Cant parse the private key: " << viewkey_str << endl;
|
||||
return string("Cant parse private key: " + viewkey_str);
|
||||
}
|
||||
if (multiple_tx_secret_keys.size() == 1)
|
||||
{
|
||||
prv_view_key = multiple_tx_secret_keys[0];
|
||||
}
|
||||
else if (!tx_prove)
|
||||
{
|
||||
cerr << "Concatenated secret keys are only for tx proving!" << endl;
|
||||
return string("Concatenated secret keys are only for tx proving!");
|
||||
}
|
||||
|
||||
|
||||
// just to see how would having spend keys could worked
|
||||
@ -1648,12 +1660,20 @@ namespace xmreg
|
||||
// public transaction key is combined with our viewkey
|
||||
// to create, so called, derived key.
|
||||
key_derivation derivation;
|
||||
std::vector<key_derivation> additional_derivations(txd.additional_pks.size());
|
||||
|
||||
//cout << multiple_tx_secret_keys.size() << " " << txd.additional_pks.size() + 1 << '\n';
|
||||
|
||||
if (tx_prove && multiple_tx_secret_keys.size() != txd.additional_pks.size() + 1)
|
||||
{
|
||||
return string("This transaction includes additional tx pubkeys whose size doesn't match with the provided tx secret keys");
|
||||
}
|
||||
|
||||
public_key pub_key = tx_prove ? address_info.address.m_view_public_key : txd.pk;
|
||||
|
||||
//cout << "txd.pk: " << pod_to_hex(txd.pk) << endl;
|
||||
|
||||
if (!generate_key_derivation(pub_key, prv_view_key, derivation))
|
||||
if (!generate_key_derivation(pub_key, tx_prove ? multiple_tx_secret_keys[0] : prv_view_key, derivation))
|
||||
{
|
||||
cerr << "Cant get derived key for: " << "\n"
|
||||
<< "pub_tx_key: " << pub_key << " and "
|
||||
@ -1661,6 +1681,17 @@ namespace xmreg
|
||||
|
||||
return string("Cant get key_derivation");
|
||||
}
|
||||
for (size_t i = 0; i < txd.additional_pks.size(); ++i)
|
||||
{
|
||||
if (!generate_key_derivation(tx_prove ? pub_key : txd.additional_pks[i], tx_prove ? multiple_tx_secret_keys[i + 1] : prv_view_key, additional_derivations[i]))
|
||||
{
|
||||
cerr << "Cant get derived key for: " << "\n"
|
||||
<< "pub_tx_key: " << txd.additional_pks[i] << " and "
|
||||
<< "prv_view_key" << prv_view_key << endl;
|
||||
|
||||
return string("Cant get key_derivation");
|
||||
}
|
||||
}
|
||||
|
||||
// decrypt encrypted payment id, as used in integreated addresses
|
||||
crypto::hash8 decrypted_payment_id8 = txd.payment_id8;
|
||||
@ -1701,6 +1732,16 @@ namespace xmreg
|
||||
|
||||
// check if generated public key matches the current output's key
|
||||
bool mine_output = (outp.first.key == tx_pubkey);
|
||||
bool with_additional = false;
|
||||
if (!mine_output && txd.additional_pks.size() == txd.output_pub_keys.size())
|
||||
{
|
||||
derive_public_key(additional_derivations[output_idx],
|
||||
output_idx,
|
||||
address_info.address.m_spend_public_key,
|
||||
tx_pubkey);
|
||||
mine_output = (outp.first.key == tx_pubkey);
|
||||
with_additional = true;
|
||||
}
|
||||
|
||||
// if mine output has RingCT, i.e., tx version is 2
|
||||
if (mine_output && tx.version == 2)
|
||||
@ -1716,8 +1757,7 @@ namespace xmreg
|
||||
bool r;
|
||||
|
||||
r = decode_ringct(tx.rct_signatures,
|
||||
pub_key,
|
||||
prv_view_key,
|
||||
with_additional ? additional_derivations[output_idx] : derivation,
|
||||
output_idx,
|
||||
tx.rct_signatures.ecdhInfo[output_idx].mask,
|
||||
rct_amount);
|
||||
@ -1888,12 +1928,14 @@ namespace xmreg
|
||||
|
||||
public_key mixin_tx_pub_key
|
||||
= xmreg::get_tx_pub_key_from_received_outs(mixin_tx);
|
||||
std::vector<public_key> mixin_additional_tx_pub_keys = cryptonote::get_additional_tx_pub_keys_from_extra(mixin_tx);
|
||||
|
||||
string mixin_tx_pub_key_str = pod_to_hex(mixin_tx_pub_key);
|
||||
|
||||
// public transaction key is combined with our viewkey
|
||||
// to create, so called, derived key.
|
||||
key_derivation derivation;
|
||||
std::vector<key_derivation> additional_derivations(mixin_additional_tx_pub_keys.size());
|
||||
|
||||
if (!generate_key_derivation(mixin_tx_pub_key, prv_view_key, derivation))
|
||||
{
|
||||
@ -1903,6 +1945,17 @@ namespace xmreg
|
||||
|
||||
continue;
|
||||
}
|
||||
for (size_t i = 0; i < mixin_additional_tx_pub_keys.size(); ++i)
|
||||
{
|
||||
if (!generate_key_derivation(mixin_additional_tx_pub_keys[i], prv_view_key, additional_derivations[i]))
|
||||
{
|
||||
cerr << "Cant get derived key for: " << "\n"
|
||||
<< "pub_tx_key: " << mixin_additional_tx_pub_keys[i] << " and "
|
||||
<< "prv_view_key" << prv_view_key << endl;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// <public_key , amount , out idx>
|
||||
vector<tuple<txout_to_key, uint64_t, uint64_t>> output_pub_keys;
|
||||
@ -1953,6 +2006,16 @@ namespace xmreg
|
||||
|
||||
// check if generated public key matches the current output's key
|
||||
bool mine_output = (txout_k.key == tx_pubkey_generated);
|
||||
bool with_additional = false;
|
||||
if (!mine_output && mixin_additional_tx_pub_keys.size() == output_pub_keys.size())
|
||||
{
|
||||
derive_public_key(additional_derivations[output_idx_in_tx],
|
||||
output_idx_in_tx,
|
||||
address_info.address.m_spend_public_key,
|
||||
tx_pubkey_generated);
|
||||
mine_output = (txout_k.key == tx_pubkey_generated);
|
||||
with_additional = true;
|
||||
}
|
||||
|
||||
|
||||
if (mine_output && mixin_tx.version == 2)
|
||||
@ -1967,8 +2030,7 @@ namespace xmreg
|
||||
bool r;
|
||||
|
||||
r = decode_ringct(mixin_tx.rct_signatures,
|
||||
mixin_tx_pub_key,
|
||||
prv_view_key,
|
||||
with_additional ? additional_derivations[output_idx_in_tx] : derivation,
|
||||
output_idx_in_tx,
|
||||
mixin_tx.rct_signatures.ecdhInfo[output_idx_in_tx].mask,
|
||||
rct_amount);
|
||||
@ -3308,6 +3370,7 @@ namespace xmreg
|
||||
}
|
||||
|
||||
public_key tx_pub_key = xmreg::get_tx_pub_key_from_received_outs(tx);
|
||||
std::vector<public_key> additional_tx_pub_keys = cryptonote::get_additional_tx_pub_keys_from_extra(tx);
|
||||
|
||||
// cointbase txs have amounts in plain sight.
|
||||
// so use amount from ringct, only for non-coinbase txs
|
||||
@ -3320,6 +3383,12 @@ namespace xmreg
|
||||
td.m_internal_output_index,
|
||||
tx.rct_signatures.ecdhInfo[td.m_internal_output_index].mask,
|
||||
xmr_amount);
|
||||
r = r || decode_ringct(tx.rct_signatures,
|
||||
additional_tx_pub_keys[td.m_internal_output_index],
|
||||
prv_view_key,
|
||||
td.m_internal_output_index,
|
||||
tx.rct_signatures.ecdhInfo[td.m_internal_output_index].mask,
|
||||
xmr_amount);
|
||||
|
||||
if (!r)
|
||||
{
|
||||
@ -4627,6 +4696,7 @@ namespace xmreg
|
||||
// public transaction key is combined with our viewkey
|
||||
// to create, so called, derived key.
|
||||
key_derivation derivation;
|
||||
std::vector<key_derivation> additional_derivations(txd.additional_pks.size());
|
||||
|
||||
public_key pub_key = tx_prove ? address_info.address.m_view_public_key : txd.pk;
|
||||
|
||||
@ -4638,6 +4708,15 @@ namespace xmreg
|
||||
j_response["message"] = "Cant calculate key_derivation";
|
||||
return j_response;
|
||||
}
|
||||
for (size_t i = 0; i < txd.additional_pks.size(); ++i)
|
||||
{
|
||||
if (!generate_key_derivation(txd.additional_pks[i], prv_view_key, additional_derivations[i]))
|
||||
{
|
||||
j_response["status"] = "error";
|
||||
j_response["message"] = "Cant calculate key_derivation";
|
||||
return j_response;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t output_idx {0};
|
||||
|
||||
@ -4661,6 +4740,16 @@ namespace xmreg
|
||||
|
||||
// check if generated public key matches the current output's key
|
||||
bool mine_output = (outp.first.key == tx_pubkey);
|
||||
bool with_additional = false;
|
||||
if (!mine_output && txd.additional_pks.size() == txd.output_pub_keys.size())
|
||||
{
|
||||
derive_public_key(additional_derivations[output_idx],
|
||||
output_idx,
|
||||
address_info.address.m_spend_public_key,
|
||||
tx_pubkey);
|
||||
mine_output = (outp.first.key == tx_pubkey);
|
||||
with_additional = true;
|
||||
}
|
||||
|
||||
// if mine output has RingCT, i.e., tx version is 2
|
||||
if (mine_output && tx.version == 2)
|
||||
@ -4676,8 +4765,7 @@ namespace xmreg
|
||||
bool r;
|
||||
|
||||
r = decode_ringct(tx.rct_signatures,
|
||||
pub_key,
|
||||
prv_view_key,
|
||||
with_additional ? additional_derivations[output_idx] : derivation,
|
||||
output_idx,
|
||||
tx.rct_signatures.ecdhInfo[output_idx].mask,
|
||||
rct_amount);
|
||||
@ -5081,6 +5169,16 @@ namespace xmreg
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<key_derivation> additional_derivations(txd.additional_pks.size());
|
||||
for (size_t i = 0; i < txd.additional_pks.size(); ++i)
|
||||
{
|
||||
if (!generate_key_derivation(txd.additional_pks[i], prv_view_key, additional_derivations[i]))
|
||||
{
|
||||
error_msg = "Cant calculate key_derivation";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t output_idx{0};
|
||||
|
||||
std::vector<uint64_t> money_transfered(tx.vout.size(), 0);
|
||||
@ -5103,6 +5201,16 @@ namespace xmreg
|
||||
|
||||
// check if generated public key matches the current output's key
|
||||
bool mine_output = (outp.first.key == tx_pubkey);
|
||||
bool with_additional = false;
|
||||
if (!mine_output && txd.additional_pks.size() == txd.output_pub_keys.size())
|
||||
{
|
||||
derive_public_key(additional_derivations[output_idx],
|
||||
output_idx,
|
||||
address.m_spend_public_key,
|
||||
tx_pubkey);
|
||||
mine_output = (outp.first.key == tx_pubkey);
|
||||
with_additional = true;
|
||||
}
|
||||
|
||||
// if mine output has RingCT, i.e., tx version is 2
|
||||
if (mine_output && tx.version == 2)
|
||||
@ -5120,8 +5228,7 @@ namespace xmreg
|
||||
rct::key mask = tx.rct_signatures.ecdhInfo[output_idx].mask;
|
||||
|
||||
r = decode_ringct(tx.rct_signatures,
|
||||
txd.pk,
|
||||
prv_view_key,
|
||||
with_additional ? additional_derivations[output_idx] : derivation,
|
||||
output_idx,
|
||||
mask,
|
||||
rct_amount);
|
||||
@ -5747,6 +5854,7 @@ namespace xmreg
|
||||
// due to previous bug with sining txs:
|
||||
// https://github.com/monero-project/monero/pull/1358/commits/7abfc5474c0f86e16c405f154570310468b635c2
|
||||
txd.pk = xmreg::get_tx_pub_key_from_received_outs(tx);
|
||||
txd.additional_pks = cryptonote::get_additional_tx_pub_keys_from_extra(tx);
|
||||
|
||||
|
||||
// sum xmr in inputs and ouputs in the given tx
|
||||
|
@ -903,19 +903,29 @@ namespace xmreg
|
||||
unsigned int i,
|
||||
rct::key & mask,
|
||||
uint64_t & amount)
|
||||
{
|
||||
crypto::key_derivation derivation;
|
||||
|
||||
bool r = crypto::generate_key_derivation(pub, sec, derivation);
|
||||
|
||||
if (!r)
|
||||
{
|
||||
cerr <<"Failed to generate key derivation to decode rct output " << i << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return decode_ringct(rv, derivation, i, mask, amount);
|
||||
}
|
||||
|
||||
bool
|
||||
decode_ringct(const rct::rctSig& rv,
|
||||
const crypto::key_derivation &derivation,
|
||||
unsigned int i,
|
||||
rct::key & mask,
|
||||
uint64_t & amount)
|
||||
{
|
||||
try
|
||||
{
|
||||
crypto::key_derivation derivation;
|
||||
|
||||
bool r = crypto::generate_key_derivation(pub, sec, derivation);
|
||||
|
||||
if (!r)
|
||||
{
|
||||
cerr <<"Failed to generate key derivation to decode rct output " << i << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
crypto::secret_key scalar1;
|
||||
|
||||
crypto::derivation_to_scalar(derivation, i, scalar1);
|
||||
|
23
src/tools.h
23
src/tools.h
@ -72,6 +72,22 @@ namespace xmreg
|
||||
bool
|
||||
parse_str_secret_key(const string& key_str, T& secret_key);
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
parse_str_secret_key(const string& key_str, std::vector<T>& secret_keys)
|
||||
{
|
||||
const size_t num_keys = key_str.size() / 64;
|
||||
if (num_keys * 64 != key_str.size())
|
||||
return false;
|
||||
secret_keys.resize(num_keys);
|
||||
for (size_t i = 0; i < num_keys; ++i)
|
||||
{
|
||||
if (!parse_str_secret_key(key_str.substr(64*i, 64), secret_keys[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
get_tx_pub_key_from_str_hash(Blockchain& core_storage,
|
||||
@ -227,6 +243,13 @@ namespace xmreg
|
||||
rct::key & mask,
|
||||
uint64_t & amount);
|
||||
|
||||
bool
|
||||
decode_ringct(const rct::rctSig & rv,
|
||||
const crypto::key_derivation &derivation,
|
||||
unsigned int i,
|
||||
rct::key & mask,
|
||||
uint64_t & amount);
|
||||
|
||||
bool
|
||||
url_decode(const std::string& in, std::string& out);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user