get_tx added

pull/39/head
moneroexamples 7 years ago
parent 56019a9998
commit 7ba1fb2757

@ -414,6 +414,31 @@ Output (only part shown):
```
#### get_tx
```bash
curl -w "\n" -X POST http://127.0.0.1:1984/get_tx -d '{"tx_hash": "bfbfbb3bfa169731a092891795be1c3c923a018882ac0efc0ed3e79e2d2b2e54"}'
```
Output (only part shown):
```json
{
"coinbase": false,
"error": "",
"fee": 22893920000,
"mixin_no": 11,
"no_confirmations": 2898,
"pub_key": "b753c863c64565ae81630bfdbf497f06955b6ce041f656565809d04be6ef9343",
"size": 13461,
"status": "OK",
"tx_hash": "bfbfbb3bfa169731a092891795be1c3c923a018882ac0efc0ed3e79e2d2b2e54",
"tx_height": 960491,
"xmr_inputs": 0,
"xmr_outputs": 0
}
```
#### get_unspent_outs
```bash

@ -65,6 +65,7 @@
<script src="js/controllers/transactions.js?1"></script>
<script src="js/controllers/vanity_address.js?1"></script>
<script src="js/controllers/account.js?1"></script>
<script src="js/controllers/transaction_details.js"></script>
<!--<script src="js/directives/scroll.js?1"></script>-->
<script src="js/directives/qr_code.js?1"></script>
<script src="js/directives/modal.js?1"></script>

@ -26,7 +26,9 @@
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
thinwalletCtrls.controller('AccountOverviewCtrl', function ($scope, $rootScope, $http, $interval, AccountService, EVENT_CODES) {
thinwalletCtrls.controller('AccountOverviewCtrl', function ($scope, $rootScope, $http,
$interval, AccountService,
EVENT_CODES) {
"use strict";
$rootScope.$watch('account', $scope.fetchTransactions);

@ -0,0 +1,14 @@
/**
* Created by mwo on 02/08/17.
*/
thinwalletCtrls.controller('TransactionDetailsCtrl', function ($scope, $http,
AccountService,
ModalService,
ApiCalls) {
"use strict";
console.log("TransactionDetailsCtrl");
});

@ -0,0 +1,57 @@
<div class="review-details-modal" modal-name="transfer-confirm" ng-controller="TransactionDetailsCtrl">
<div class="w-container review-details-container">
<div class="w-clearfix review-details-div">
<a class="w-inline-block close-modal" data-ix="close-login-key" ng-click="transferConfirmDialog.cancel()">
<div class="close-overlay pointer" data-ix="close-overlay">+</div>
</a>
<h1 class="head-modal">Transaction details</h1>
<div class="subhead-text modal review">Transaction details</div>
<div class="w-form form-wrapper">
<label class="field-label review" for="Mnemonic-2">Receiver Address</label>
<div class="move-text-div">
<div class="review-text address">{{transferConfirmDialog.address}} </span></div>
</div>
<div class="w-row">
<div class="w-col w-col-4 responsive-column">
<label class="field-label review" for="Amount">Amount</label>
<div class="review-text">{{transferConfirmDialog.amount | money}} (+{{transferConfirmDialog.fee | money}} fee)</div>
</div>
<div class="w-col w-col-4 responsive-column">
<label class="field-label review">Ring Size</label>
<div class="review-text">{{transferConfirmDialog.mixin}}</div>
</div>
<div class="w-col w-col-4 responsive-column">
<label class="field-label review">Priority</label>
<div class="review-text">{{transferConfirmDialog.priority}}</div>
</div>
</div>
<div class="w-row">
<div class="w-col w-col-8 responsive-column">
<label class="field-label review" for="Mnemonic-2">Payment ID</label>
<div class="review-text">{{transferConfirmDialog.payment_id || "N/A"}}</div>
</div>
<div class="w-col w-col-4 responsive-column">
<label class="field-label review" for="Mnemonic-2">Size [kB]</label>
<div class="review-text">{{transferConfirmDialog.txBlobKBytes}}</div>
</div>
</div>
<label class="field-label review" for="Mnemonic-2" ng-show="transferConfirmDialog.tx_hash">Transaction ID/Hash</label>
<div class="move-text-div">
<div class="review-text">{{transferConfirmDialog.tx_hash}}</div>
</div>
<label class="field-label review" for="Mnemonic-2" ng-show="transferConfirmDialog.tx_hash">Transaction Private Key</label>
<div class="move-text-div">
<div class="review-text">{{transferConfirmDialog.tx_prv_key}}</div>
</div>
<br/>
<div class="move-text-div">
<div class="review-text ">After pressing "Confirm", an attempt will be made to
submit this tx to a Monero node. The node will perform additional checks of the tx
(e.g., if the miner fee is sufficient), and if the tests pass, the tx will be submitted to
Monero network awaiting miners confirmation.
</div>
</div>
</div>
</div>
</div>
</div>

@ -162,6 +162,7 @@ MAKE_RESOURCE(get_random_outs);
MAKE_RESOURCE(submit_raw_tx);
MAKE_RESOURCE(import_wallet_request);
MAKE_RESOURCE(import_recent_wallet_request);
MAKE_RESOURCE(get_tx);
MAKE_RESOURCE(get_version);
// restbed service
@ -176,6 +177,7 @@ service.publish(get_random_outs);
service.publish(submit_raw_tx);
service.publish(import_wallet_request);
service.publish(import_recent_wallet_request);
service.publish(get_tx);
service.publish(get_version);
auto settings = make_shared<Settings>( );

@ -247,7 +247,7 @@ CurrentBlockchainStatus::tx_exist(const string& tx_hash_str, uint64_t& tx_index)
return tx_exist(tx_hash, tx_index);
}
throw runtime_error("hex_to_pod(tx_hash_str, tx_hash) failed!");
false;
}
bool
@ -863,8 +863,38 @@ CurrentBlockchainStatus::find_txs_in_mempool(
return true;
};
bool
CurrentBlockchainStatus::get_tx(crypto::hash const& tx_hash, transaction& tx)
{
return mcore->get_tx(tx_hash, tx);
}
bool
CurrentBlockchainStatus::get_tx(string const& tx_hash_str, transaction& tx)
{
crypto::hash tx_hash;
if (!hex_to_pod(tx_hash_str, tx_hash))
{
return false;
}
bool
return mcore->get_tx(tx_hash, tx);
}
bool
CurrentBlockchainStatus::get_tx_block_height(crypto::hash const& tx_hash, int64_t& tx_height)
{
if (!tx_exist(tx_hash))
return false;
tx_height = core_storage->get_db().get_tx_block_height(tx_hash);
return true;
}
bool
CurrentBlockchainStatus::set_new_searched_blk_no(const string& address, uint64_t new_value)
{
std::lock_guard<std::mutex> lck (searching_threads_map_mtx);

@ -188,6 +188,15 @@ struct CurrentBlockchainStatus
find_txs_in_mempool(const string& address_str,
json& transactions);
static bool
get_tx(crypto::hash const& tx_hash, transaction& tx);
static bool
get_tx(string const& tx_hash_str, transaction& tx);
static bool
get_tx_block_height(crypto::hash const& tx_hash, int64_t& tx_height);
static bool
set_new_searched_blk_no(const string& address,
uint64_t new_value);

@ -133,7 +133,7 @@ YourMoneroRequests::get_address_txs(const shared_ptr< Session > session, const B
json j_response;
json j_request;
vector<string> requested_values{"address", "view_key"};
vector<string> requested_values {"address", "view_key"};
if (!parse_request(body, requested_values, j_request, j_response))
{
@ -993,6 +993,156 @@ YourMoneroRequests::import_recent_wallet_request(const shared_ptr< Session > ses
}
void
YourMoneroRequests::get_tx(const shared_ptr< Session > session, const Bytes & body)
{
json j_request = body_to_json(body);
string tx_hash_str = j_request["tx_hash"];
json j_response;
j_response["status"] = "error";
j_response["error"] = "Some error occured";
crypto::hash tx_hash;
if (!hex_to_pod(tx_hash_str, tx_hash))
{
cerr << "Cant parse tx hash! : " << tx_hash_str << '\n';
j_response["status"] = "Cant parse tx hash! : " + tx_hash_str;
session_close(session, j_response.dump());
return;
}
transaction tx;
bool tx_found {false};
if (!CurrentBlockchainStatus::get_tx(tx_hash, tx))
{
// if tx not found in the blockchain, check if its in mempool
vector<pair<uint64_t, transaction>> mempool_txs =
CurrentBlockchainStatus::get_mempool_txs();
for (auto const& mtx: mempool_txs)
{
cout << (get_transaction_hash(mtx.second)) << endl;
if (get_transaction_hash(mtx.second) == tx_hash)
{
tx = mtx.second;
tx_found = true;
break;
}
}
tx_found = false;
}
else
{
tx_found = true;
}
if (tx_found)
{
crypto::hash tx_hash = get_transaction_hash(tx);
// return tx hash. can be used to check if we acctually
// delivered the tx that was requested
j_response["tx_hash"] = pod_to_hex(tx_hash);
j_response["pub_key"] = pod_to_hex(xmreg::get_tx_pub_key_from_received_outs(tx));
bool coinbase = is_coinbase(tx);
j_response["coinbase"] = coinbase;
// key images of inputs
vector<txin_to_key> input_key_imgs;
// public keys and xmr amount of outputs
vector<pair<txout_to_key, uint64_t>> output_pub_keys;
uint64_t xmr_inputs;
uint64_t xmr_outputs;
uint64_t num_nonrct_inputs;
uint64_t fee;
uint64_t mixin_no;
uint64_t size;
uint64_t blk_height;
// sum xmr in inputs and ouputs in the given tx
array<uint64_t, 4> const& sum_data = xmreg::summary_of_in_out_rct(
tx, output_pub_keys, input_key_imgs);
xmr_outputs = sum_data[0];
xmr_inputs = sum_data[1];
mixin_no = sum_data[2];
num_nonrct_inputs = sum_data[3];
j_response["xmr_outputs"] = xmr_outputs;
j_response["xmr_inputs"] = xmr_inputs;
j_response["mixin_no"] = mixin_no;
fee = 0;
if (!coinbase && tx.vin.size() > 0)
{
// check if not miner tx
// i.e., for blocks without any user transactions
if (tx.vin.at(0).type() != typeid(txin_gen))
{
// get tx fee
fee = get_tx_fee(tx);
}
}
j_response["fee"] = fee;
// get tx size in bytes
size = get_object_blobsize(tx);
j_response["size"] = size;
int64_t tx_height {-1};
int64_t no_confirmations {-1};
if (CurrentBlockchainStatus::get_tx_block_height(tx_hash, tx_height))
{
// get the current blockchain height. Just to check
uint64_t bc_height = get_current_blockchain_height();
no_confirmations = bc_height - tx_height;
}
j_response["tx_height"] = tx_height;
j_response["no_confirmations"] = no_confirmations;
j_response["status"] = "OK";
j_response["error"] = "";
}
else
{
cerr << "Cant get tx details for tx hash! : " << tx_hash_str << '\n';
j_response["status"] = "Cant get tx details for tx hash! : " + tx_hash_str;
}
string response_body = j_response.dump();
auto response_headers = make_headers({{ "Content-Length", to_string(response_body.size())}});
session->close( OK, response_body, response_headers);
}
void
YourMoneroRequests::get_version(const shared_ptr< Session > session, const Bytes & body)
{

@ -105,6 +105,9 @@ public:
void
import_recent_wallet_request(const shared_ptr< Session > session, const Bytes & body);
void
get_tx(const shared_ptr< Session > session, const Bytes & body);
void
get_version(const shared_ptr< Session > session, const Bytes & body);

@ -290,7 +290,112 @@ get_blockchain_path(bf::path& blockchain_path,
}
uint64_t
array<uint64_t, 4>
summary_of_in_out_rct(
const transaction& tx,
vector<pair<txout_to_key, uint64_t>>& output_pub_keys,
vector<txin_to_key>& input_key_imgs)
{
uint64_t xmr_outputs {0};
uint64_t xmr_inputs {0};
uint64_t mixin_no {0};
uint64_t num_nonrct_inputs {0};
for (const tx_out& txout: tx.vout)
{
if (txout.target.type() != typeid(txout_to_key))
{
// push empty pair.
output_pub_keys.push_back(pair<txout_to_key, uint64_t>{});
continue;
}
// get tx input key
const txout_to_key& txout_key
= boost::get<cryptonote::txout_to_key>(txout.target);
output_pub_keys.push_back(make_pair(txout_key, txout.amount));
xmr_outputs += txout.amount;
}
size_t input_no = tx.vin.size();
for (size_t i = 0; i < input_no; ++i)
{
if(tx.vin[i].type() != typeid(cryptonote::txin_to_key))
{
continue;
}
// get tx input key
const cryptonote::txin_to_key& tx_in_to_key
= boost::get<cryptonote::txin_to_key>(tx.vin[i]);
xmr_inputs += tx_in_to_key.amount;
if (tx_in_to_key.amount != 0)
{
++num_nonrct_inputs;
}
if (mixin_no == 0)
{
mixin_no = tx_in_to_key.key_offsets.size();
}
input_key_imgs.push_back(tx_in_to_key);
} // for (size_t i = 0; i < input_no; ++i)
return {xmr_outputs, xmr_inputs, mixin_no, num_nonrct_inputs};
};
// this version for mempool txs from json
array<uint64_t, 6>
summary_of_in_out_rct(const json& _json)
{
uint64_t xmr_outputs {0};
uint64_t xmr_inputs {0};
uint64_t no_outputs {0};
uint64_t no_inputs {0};
uint64_t mixin_no {0};
uint64_t num_nonrct_inputs {0};
for (const json& vout: _json["vout"])
{
xmr_outputs += vout["amount"].get<uint64_t>();
}
no_outputs = _json["vout"].size();
for (const json& vin: _json["vin"])
{
uint64_t amount = vin["key"]["amount"].get<uint64_t>();
xmr_inputs += amount;
if (amount != 0)
++num_nonrct_inputs;
}
no_inputs = _json["vin"].size();
mixin_no = _json["vin"].at(0)["key"]["key_offsets"].size() - 1;
return {xmr_outputs, xmr_inputs, no_outputs, no_inputs, mixin_no, num_nonrct_inputs};
};
uint64_t
sum_money_in_outputs(const transaction& tx)
{
uint64_t sum_xmr {0};

@ -105,6 +105,16 @@ bool
get_blockchain_path(bf::path& blockchain_path,
bool testnet = false);
array<uint64_t, 4>
summary_of_in_out_rct(
const transaction& tx,
vector<pair<txout_to_key, uint64_t>>& output_pub_keys,
vector<txin_to_key>& input_key_imgs);
// this version for mempool txs from json
array<uint64_t, 6>
summary_of_in_out_rct(const json& _json);
uint64_t
sum_money_in_outputs(const transaction& tx);

Loading…
Cancel
Save