mirror of
https://git.wownero.com/wownero/onion-wownero-blockchain-explorer.git
synced 2024-08-15 00:33:12 +00:00
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
4 changed files with 162 additions and 20 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -6,4 +6,5 @@
|
||||||
*.log
|
*.log
|
||||||
*.orig
|
*.orig
|
||||||
tests/
|
tests/
|
||||||
|
build/
|
||||||
cmake-build-debug/
|
cmake-build-debug/
|
||||||
|
|
128
src/page.h
128
src/page.h
|
@ -126,6 +126,7 @@ namespace xmreg
|
||||||
crypto::hash hash;
|
crypto::hash hash;
|
||||||
crypto::hash prefix_hash;
|
crypto::hash prefix_hash;
|
||||||
crypto::public_key pk;
|
crypto::public_key pk;
|
||||||
|
std::vector<crypto::public_key> additional_pks;
|
||||||
uint64_t xmr_inputs;
|
uint64_t xmr_inputs;
|
||||||
uint64_t xmr_outputs;
|
uint64_t xmr_outputs;
|
||||||
uint64_t num_nonrct_inputs;
|
uint64_t num_nonrct_inputs;
|
||||||
|
@ -1469,11 +1470,22 @@ namespace xmreg
|
||||||
// parse string representing given private key
|
// parse string representing given private key
|
||||||
crypto::secret_key prv_view_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;
|
cerr << "Cant parse the private key: " << viewkey_str << endl;
|
||||||
return string("Cant parse private key: " + viewkey_str);
|
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
|
// just to see how would having spend keys could worked
|
||||||
|
@ -1648,12 +1660,20 @@ namespace xmreg
|
||||||
// public transaction key is combined with our viewkey
|
// public transaction key is combined with our viewkey
|
||||||
// to create, so called, derived key.
|
// to create, so called, derived key.
|
||||||
key_derivation derivation;
|
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;
|
public_key pub_key = tx_prove ? address_info.address.m_view_public_key : txd.pk;
|
||||||
|
|
||||||
//cout << "txd.pk: " << pod_to_hex(txd.pk) << endl;
|
//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"
|
cerr << "Cant get derived key for: " << "\n"
|
||||||
<< "pub_tx_key: " << pub_key << " and "
|
<< "pub_tx_key: " << pub_key << " and "
|
||||||
|
@ -1661,6 +1681,17 @@ namespace xmreg
|
||||||
|
|
||||||
return string("Cant get key_derivation");
|
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
|
// decrypt encrypted payment id, as used in integreated addresses
|
||||||
crypto::hash8 decrypted_payment_id8 = txd.payment_id8;
|
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
|
// check if generated public key matches the current output's key
|
||||||
bool mine_output = (outp.first.key == tx_pubkey);
|
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 has RingCT, i.e., tx version is 2
|
||||||
if (mine_output && tx.version == 2)
|
if (mine_output && tx.version == 2)
|
||||||
|
@ -1716,8 +1757,7 @@ namespace xmreg
|
||||||
bool r;
|
bool r;
|
||||||
|
|
||||||
r = decode_ringct(tx.rct_signatures,
|
r = decode_ringct(tx.rct_signatures,
|
||||||
pub_key,
|
with_additional ? additional_derivations[output_idx] : derivation,
|
||||||
prv_view_key,
|
|
||||||
output_idx,
|
output_idx,
|
||||||
tx.rct_signatures.ecdhInfo[output_idx].mask,
|
tx.rct_signatures.ecdhInfo[output_idx].mask,
|
||||||
rct_amount);
|
rct_amount);
|
||||||
|
@ -1888,12 +1928,14 @@ namespace xmreg
|
||||||
|
|
||||||
public_key mixin_tx_pub_key
|
public_key mixin_tx_pub_key
|
||||||
= xmreg::get_tx_pub_key_from_received_outs(mixin_tx);
|
= 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);
|
string mixin_tx_pub_key_str = pod_to_hex(mixin_tx_pub_key);
|
||||||
|
|
||||||
// public transaction key is combined with our viewkey
|
// public transaction key is combined with our viewkey
|
||||||
// to create, so called, derived key.
|
// to create, so called, derived key.
|
||||||
key_derivation derivation;
|
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))
|
if (!generate_key_derivation(mixin_tx_pub_key, prv_view_key, derivation))
|
||||||
{
|
{
|
||||||
|
@ -1903,6 +1945,17 @@ namespace xmreg
|
||||||
|
|
||||||
continue;
|
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>
|
// <public_key , amount , out idx>
|
||||||
vector<tuple<txout_to_key, uint64_t, uint64_t>> output_pub_keys;
|
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
|
// check if generated public key matches the current output's key
|
||||||
bool mine_output = (txout_k.key == tx_pubkey_generated);
|
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)
|
if (mine_output && mixin_tx.version == 2)
|
||||||
|
@ -1967,8 +2030,7 @@ namespace xmreg
|
||||||
bool r;
|
bool r;
|
||||||
|
|
||||||
r = decode_ringct(mixin_tx.rct_signatures,
|
r = decode_ringct(mixin_tx.rct_signatures,
|
||||||
mixin_tx_pub_key,
|
with_additional ? additional_derivations[output_idx_in_tx] : derivation,
|
||||||
prv_view_key,
|
|
||||||
output_idx_in_tx,
|
output_idx_in_tx,
|
||||||
mixin_tx.rct_signatures.ecdhInfo[output_idx_in_tx].mask,
|
mixin_tx.rct_signatures.ecdhInfo[output_idx_in_tx].mask,
|
||||||
rct_amount);
|
rct_amount);
|
||||||
|
@ -3308,6 +3370,7 @@ namespace xmreg
|
||||||
}
|
}
|
||||||
|
|
||||||
public_key tx_pub_key = xmreg::get_tx_pub_key_from_received_outs(tx);
|
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.
|
// cointbase txs have amounts in plain sight.
|
||||||
// so use amount from ringct, only for non-coinbase txs
|
// so use amount from ringct, only for non-coinbase txs
|
||||||
|
@ -3320,6 +3383,12 @@ namespace xmreg
|
||||||
td.m_internal_output_index,
|
td.m_internal_output_index,
|
||||||
tx.rct_signatures.ecdhInfo[td.m_internal_output_index].mask,
|
tx.rct_signatures.ecdhInfo[td.m_internal_output_index].mask,
|
||||||
xmr_amount);
|
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)
|
if (!r)
|
||||||
{
|
{
|
||||||
|
@ -4627,6 +4696,7 @@ namespace xmreg
|
||||||
// public transaction key is combined with our viewkey
|
// public transaction key is combined with our viewkey
|
||||||
// to create, so called, derived key.
|
// to create, so called, derived key.
|
||||||
key_derivation derivation;
|
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;
|
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";
|
j_response["message"] = "Cant calculate key_derivation";
|
||||||
return j_response;
|
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};
|
uint64_t output_idx {0};
|
||||||
|
|
||||||
|
@ -4661,6 +4740,16 @@ namespace xmreg
|
||||||
|
|
||||||
// check if generated public key matches the current output's key
|
// check if generated public key matches the current output's key
|
||||||
bool mine_output = (outp.first.key == tx_pubkey);
|
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 has RingCT, i.e., tx version is 2
|
||||||
if (mine_output && tx.version == 2)
|
if (mine_output && tx.version == 2)
|
||||||
|
@ -4676,8 +4765,7 @@ namespace xmreg
|
||||||
bool r;
|
bool r;
|
||||||
|
|
||||||
r = decode_ringct(tx.rct_signatures,
|
r = decode_ringct(tx.rct_signatures,
|
||||||
pub_key,
|
with_additional ? additional_derivations[output_idx] : derivation,
|
||||||
prv_view_key,
|
|
||||||
output_idx,
|
output_idx,
|
||||||
tx.rct_signatures.ecdhInfo[output_idx].mask,
|
tx.rct_signatures.ecdhInfo[output_idx].mask,
|
||||||
rct_amount);
|
rct_amount);
|
||||||
|
@ -5081,6 +5169,16 @@ namespace xmreg
|
||||||
return false;
|
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};
|
uint64_t output_idx{0};
|
||||||
|
|
||||||
std::vector<uint64_t> money_transfered(tx.vout.size(), 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
|
// check if generated public key matches the current output's key
|
||||||
bool mine_output = (outp.first.key == tx_pubkey);
|
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 has RingCT, i.e., tx version is 2
|
||||||
if (mine_output && tx.version == 2)
|
if (mine_output && tx.version == 2)
|
||||||
|
@ -5120,8 +5228,7 @@ namespace xmreg
|
||||||
rct::key mask = tx.rct_signatures.ecdhInfo[output_idx].mask;
|
rct::key mask = tx.rct_signatures.ecdhInfo[output_idx].mask;
|
||||||
|
|
||||||
r = decode_ringct(tx.rct_signatures,
|
r = decode_ringct(tx.rct_signatures,
|
||||||
txd.pk,
|
with_additional ? additional_derivations[output_idx] : derivation,
|
||||||
prv_view_key,
|
|
||||||
output_idx,
|
output_idx,
|
||||||
mask,
|
mask,
|
||||||
rct_amount);
|
rct_amount);
|
||||||
|
@ -5747,6 +5854,7 @@ namespace xmreg
|
||||||
// due to previous bug with sining txs:
|
// due to previous bug with sining txs:
|
||||||
// https://github.com/monero-project/monero/pull/1358/commits/7abfc5474c0f86e16c405f154570310468b635c2
|
// https://github.com/monero-project/monero/pull/1358/commits/7abfc5474c0f86e16c405f154570310468b635c2
|
||||||
txd.pk = xmreg::get_tx_pub_key_from_received_outs(tx);
|
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
|
// sum xmr in inputs and ouputs in the given tx
|
||||||
|
|
|
@ -903,19 +903,29 @@ namespace xmreg
|
||||||
unsigned int i,
|
unsigned int i,
|
||||||
rct::key & mask,
|
rct::key & mask,
|
||||||
uint64_t & amount)
|
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
|
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::secret_key scalar1;
|
||||||
|
|
||||||
crypto::derivation_to_scalar(derivation, i, scalar1);
|
crypto::derivation_to_scalar(derivation, i, scalar1);
|
||||||
|
|
23
src/tools.h
23
src/tools.h
|
@ -72,6 +72,22 @@ namespace xmreg
|
||||||
bool
|
bool
|
||||||
parse_str_secret_key(const string& key_str, T& secret_key);
|
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
|
bool
|
||||||
get_tx_pub_key_from_str_hash(Blockchain& core_storage,
|
get_tx_pub_key_from_str_hash(Blockchain& core_storage,
|
||||||
|
@ -227,6 +243,13 @@ namespace xmreg
|
||||||
rct::key & mask,
|
rct::key & mask,
|
||||||
uint64_t & amount);
|
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
|
bool
|
||||||
url_decode(const std::string& in, std::string& out);
|
url_decode(const std::string& in, std::string& out);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue