BitShares-Core  5.0.0
BitShares blockchain implementation and command-line interface software
wallet.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Cryptonomex, Inc., and contributors.
3  *
4  * The MIT License
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #include <algorithm>
25 #include <cctype>
26 #include <iomanip>
27 #include <iostream>
28 #include <iterator>
29 #include <sstream>
30 #include <string>
31 #include <list>
32 
33 #include <boost/version.hpp>
34 #include <boost/lexical_cast.hpp>
35 #include <boost/algorithm/string/replace.hpp>
36 
37 #include <boost/range/adaptor/map.hpp>
38 #include <boost/range/algorithm_ext/erase.hpp>
39 #include <boost/range/algorithm/unique.hpp>
40 #include <boost/range/algorithm/sort.hpp>
41 
42 #include <boost/multi_index_container.hpp>
43 #include <boost/multi_index/ordered_index.hpp>
44 #include <boost/multi_index/mem_fun.hpp>
45 #include <boost/multi_index/member.hpp>
46 #include <boost/multi_index/random_access_index.hpp>
47 #include <boost/multi_index/tag.hpp>
48 #include <boost/multi_index/sequenced_index.hpp>
49 #include <boost/multi_index/hashed_index.hpp>
50 
51 #include <fc/git_revision.hpp>
52 #include <fc/io/fstream.hpp>
53 #include <fc/io/json.hpp>
54 #include <fc/io/stdio.hpp>
56 #include <fc/rpc/cli.hpp>
57 #include <fc/rpc/websocket_api.hpp>
58 #include <fc/crypto/hex.hpp>
59 #include <fc/thread/mutex.hpp>
61 #include <fc/crypto/base58.hpp>
62 #include <fc/crypto/aes.hpp>
63 
64 #include <graphene/app/api.hpp>
65 #include <graphene/app/util.hpp>
69 #include <graphene/chain/hardfork.hpp>
75 #include "wallet_api_impl.hpp"
77 
78 #include "operation_printer.hpp"
80 
81 #define BRAIN_KEY_WORD_COUNT 16
82 #define RANGE_PROOF_MANTISSA 49 // Minimum mantissa bits to "hide" in the range proof.
83  // If this number is set too low, then for large value
84  // commitments the length of the range proof will hint
85  // strongly at the value amount that is being hidden.
86 
87 namespace graphene { namespace wallet {
89  {
90  fc::stringstream to_sign;
91  to_sign << message << '\n';
92  to_sign << "account=" << meta.account << '\n';
93  to_sign << "memokey=" << std::string( meta.memo_key ) << '\n';
94  to_sign << "block=" << meta.block << '\n';
95  to_sign << "timestamp=" << meta.time;
96 
97  return fc::sha256::hash( to_sign.str() );
98  }
99  vector<brain_key_info> utility::derive_owner_keys_from_brain_key(string brain_key, int number_of_desired_keys)
100  {
101  // Safety-check
102  FC_ASSERT( number_of_desired_keys >= 1 );
103 
104  // Create as many derived owner keys as requested
105  vector<brain_key_info> results;
106  brain_key = graphene::wallet::detail::normalize_brain_key(brain_key);
107  for (int i = 0; i < number_of_desired_keys; ++i) {
109 
110  brain_key_info result;
111  result.brain_priv_key = brain_key;
112  result.wif_priv_key = key_to_wif( priv_key );
113  result.pub_key = priv_key.get_public_key();
114 
115  results.push_back(result);
116  }
117 
118  return results;
119  }
120 
122  {
123  brain_key_info result;
124  // create a private key for secure entropy
127  fc::bigint entropy1(sha_entropy1.data(), sha_entropy1.data_size());
128  fc::bigint entropy2(sha_entropy2.data(), sha_entropy2.data_size());
129  fc::bigint entropy(entropy1);
130  entropy <<= 8 * sha_entropy1.data_size();
131  entropy += entropy2;
132  string brain_key = "";
133 
134  for (int i = 0; i < BRAIN_KEY_WORD_COUNT; i++)
135  {
136  fc::bigint choice = entropy % graphene::words::word_list_size;
138  if (i > 0)
139  brain_key += " ";
140  brain_key += graphene::words::word_list[choice.to_int64()];
141  }
142 
143  brain_key = detail::normalize_brain_key(brain_key);
144  fc::ecc::private_key priv_key = detail::derive_private_key(brain_key, 0);
145  result.brain_priv_key = brain_key;
146  result.wif_priv_key = key_to_wif(priv_key);
147  result.pub_key = priv_key.get_public_key();
148  return result;
149  }
150 }}
151 
152 namespace graphene { namespace wallet {
153 
155  : my(new detail::wallet_api_impl(*this, initial_data, rapi))
156 {
157 }
158 
160 {
161 }
162 
163 bool wallet_api::copy_wallet_file(string destination_filename)
164 {
165  return my->copy_wallet_file(destination_filename);
166 }
167 
168 optional<signed_block_with_info> wallet_api::get_block(uint32_t num)
169 {
170  return my->_remote_db->get_block(num);
171 }
172 
174 {
175  return my->_remote_db->get_account_count();
176 }
177 
178 vector<account_object> wallet_api::list_my_accounts()
179 {
180  return vector<account_object>(my->_wallet.my_accounts.begin(), my->_wallet.my_accounts.end());
181 }
182 
183 map<string,account_id_type> wallet_api::list_accounts(const string& lowerbound, uint32_t limit)
184 {
185  return my->_remote_db->lookup_accounts(lowerbound, limit, {});
186 }
187 
188 vector<asset> wallet_api::list_account_balances(const string& id)
189 {
190  return my->_remote_db->get_account_balances(id, flat_set<asset_id_type>());
191 }
192 
193 vector<extended_asset_object> wallet_api::list_assets(const string& lowerbound, uint32_t limit)const
194 {
195  return my->_remote_db->list_assets( lowerbound, limit );
196 }
197 
199 {
200  return my->_remote_db->get_asset_count();
201 }
202 
203 signed_transaction wallet_api::htlc_create( string source, string destination, string amount, string asset_symbol,
204  string hash_algorithm, const std::string& preimage_hash, uint32_t preimage_size,
205  const uint32_t claim_period_seconds, const std::string& memo, bool broadcast)
206 {
207  return my->htlc_create(source, destination, amount, asset_symbol, hash_algorithm, preimage_hash, preimage_size,
208  claim_period_seconds, memo, broadcast);
209 }
210 
212 {
213  fc::optional<htlc_object> optional_obj = my->get_htlc(htlc_id);
214  if ( optional_obj.valid() )
215  {
216  const htlc_object& obj = *optional_obj;
217  // convert to formatted variant
219  const auto& from = my->get_account( obj.transfer.from );
220  transfer["from"] = from.name;
221  const auto& to = my->get_account( obj.transfer.to );
222  transfer["to"] = to.name;
223  const auto& asset = my->get_asset( obj.transfer.asset_id );
224  transfer["asset"] = asset.symbol;
225  transfer["amount"] = graphene::app::uint128_amount_to_string( obj.transfer.amount.value, asset.precision );
226  if (obj.memo.valid())
227  transfer["memo"] = my->read_memo( *obj.memo );
228  class htlc_hash_to_variant_visitor
229  {
230  public:
232 
233  result_type operator()(const fc::ripemd160& obj)const
234  { return convert("RIPEMD160", obj.str()); }
235  result_type operator()(const fc::sha1& obj)const
236  { return convert("SHA1", obj.str()); }
237  result_type operator()(const fc::sha256& obj)const
238  { return convert("SHA256", obj.str()); }
239  result_type operator()(const fc::hash160& obj)const
240  { return convert("HASH160", obj.str()); }
241  private:
242  result_type convert(const std::string& type, const std::string& hash)const
243  {
245  ret_val["hash_algo"] = type;
246  ret_val["preimage_hash"] = hash;
247  return ret_val;
248  }
249  };
250  static htlc_hash_to_variant_visitor hash_visitor;
251  fc::mutable_variant_object htlc_lock = obj.conditions.hash_lock.preimage_hash.visit(hash_visitor);
252  htlc_lock["preimage_size"] = obj.conditions.hash_lock.preimage_size;
253  fc::mutable_variant_object time_lock;
254  time_lock["expiration"] = obj.conditions.time_lock.expiration;
256  fc::mutable_variant_object conditions;
257  conditions["htlc_lock"] = htlc_lock;
258  conditions["time_lock"] = time_lock;
260  result["transfer"] = transfer;
261  result["conditions"] = conditions;
262  return fc::optional<fc::variant>(result);
263  }
264  return fc::optional<fc::variant>();
265 }
266 
267 signed_transaction wallet_api::htlc_redeem( std::string htlc_id, std::string issuer, const std::string& preimage,
268  bool broadcast)
269 {
270 
271  return my->htlc_redeem(htlc_id, issuer, std::vector<char>(preimage.begin(), preimage.end()), broadcast);
272 }
273 
274 signed_transaction wallet_api::htlc_extend ( std::string htlc_id, std::string issuer, const uint32_t seconds_to_add,
275  bool broadcast)
276 {
277  return my->htlc_extend(htlc_id, issuer, seconds_to_add, broadcast);
278 }
279 
280 vector<operation_detail> wallet_api::get_account_history(string name, int limit)const
281 {
282  vector<operation_detail> result;
283 
284  while( limit > 0 )
285  {
286  bool skip_first_row = false;
287  operation_history_id_type start;
288  if( result.size() )
289  {
290  start = result.back().op.id;
291  if( start == operation_history_id_type() ) // no more data
292  break;
293  start = start + (-1);
294  if( start == operation_history_id_type() ) // will return most recent history if
295  // directly call remote API with this
296  {
297  start = start + 1;
298  skip_first_row = true;
299  }
300  }
301 
302  int page_limit = skip_first_row ? std::min( 100, limit + 1 ) : std::min( 100, limit );
303 
304  vector<operation_history_object> current = my->_remote_hist->get_account_history(
305  name,
306  operation_history_id_type(),
307  page_limit,
308  start );
309  bool first_row = true;
310  for( auto& o : current )
311  {
312  if( first_row )
313  {
314  first_row = false;
315  if( skip_first_row )
316  {
317  continue;
318  }
319  }
320  std::stringstream ss;
321  auto memo = o.op.visit(detail::operation_printer(ss, *my, o));
322  result.push_back( operation_detail{ memo, ss.str(), o } );
323  }
324 
325  if( int(current.size()) < page_limit )
326  break;
327 
328  limit -= current.size();
329  if( skip_first_row )
330  ++limit;
331  }
332 
333  return result;
334 }
335 
337  string name,
338  uint32_t stop,
339  int limit,
340  uint32_t start)const
341 {
342  vector<operation_detail> result;
343  auto account_id = get_account(name).get_id();
344 
345  const account_object& account = my->get_account(account_id);
346  const account_statistics_object& stats = my->get_object(account.statistics);
347 
348  if(start == 0)
349  start = stats.total_ops;
350  else
351  start = std::min<uint32_t>(start, stats.total_ops);
352 
353  while( limit > 0 )
354  {
355  vector <operation_history_object> current = my->_remote_hist->get_relative_account_history(
356  name,
357  stop,
358  std::min<uint32_t>(100, limit),
359  start);
360  for (auto &o : current) {
361  std::stringstream ss;
362  auto memo = o.op.visit(detail::operation_printer(ss, *my, o));
363  result.push_back(operation_detail{memo, ss.str(), o});
364  }
365  if (current.size() < std::min<uint32_t>(100, limit))
366  break;
367  limit -= current.size();
368  start -= 100;
369  if( start == 0 ) break;
370  }
371  return result;
372 }
373 
375  string name,
376  flat_set<uint16_t> operation_types,
377  uint32_t start,
378  int limit)
379 {
381  auto account_id = get_account(name).get_id();
382 
383  const auto& account = my->get_account(account_id);
384  const auto& stats = my->get_object(account.statistics);
385 
386  // sequence of account_transaction_history_object start with 1
387  start = start == 0 ? 1 : start;
388 
389  if (start <= stats.removed_ops) {
390  start = stats.removed_ops;
391  result.total_count =stats.removed_ops;
392  }
393 
394  while (limit > 0 && start <= stats.total_ops) {
395  uint32_t min_limit = std::min<uint32_t> (100, limit);
396  auto current = my->_remote_hist->get_account_history_by_operations(name, operation_types, start, min_limit);
397  for (auto& obj : current.operation_history_objs) {
398  std::stringstream ss;
399  auto memo = obj.op.visit(detail::operation_printer(ss, *my, obj));
400 
401  transaction_id_type transaction_id;
402  auto block = get_block(obj.block_num);
403  if (block.valid() && obj.trx_in_block < block->transaction_ids.size()) {
404  transaction_id = block->transaction_ids[obj.trx_in_block];
405  }
406  result.details.push_back(operation_detail_ex{memo, ss.str(), obj, transaction_id});
407  }
408  result.result_count += current.operation_history_objs.size();
409  result.total_count += current.total_count;
410 
411  start += current.total_count > 0 ? current.total_count : min_limit;
412  limit -= current.operation_history_objs.size();
413  }
414 
415  return result;
416 }
417 
418 full_account wallet_api::get_full_account( const string& name_or_id)
419 {
420  return my->_remote_db->get_full_accounts({name_or_id}, false)[name_or_id];
421 }
422 
423 vector<bucket_object> wallet_api::get_market_history(
424  string symbol1,
425  string symbol2,
426  uint32_t bucket,
427  fc::time_point_sec start,
428  fc::time_point_sec end )const
429 {
430  return my->_remote_hist->get_market_history( symbol1, symbol2, bucket, start, end );
431 }
432 
433 vector<limit_order_object> wallet_api::get_account_limit_orders(
434  const string& name_or_id,
435  const string &base,
436  const string &quote,
437  uint32_t limit,
438  optional<limit_order_id_type> ostart_id,
439  optional<price> ostart_price)
440 {
441  return my->_remote_db->get_account_limit_orders(name_or_id, base, quote, limit, ostart_id, ostart_price);
442 }
443 
444 vector<limit_order_object> wallet_api::get_limit_orders(std::string a, std::string b, uint32_t limit)const
445 {
446  return my->_remote_db->get_limit_orders(a, b, limit);
447 }
448 
449 vector<call_order_object> wallet_api::get_call_orders(std::string a, uint32_t limit)const
450 {
451  return my->_remote_db->get_call_orders(a, limit);
452 }
453 
454 vector<force_settlement_object> wallet_api::get_settle_orders(std::string a, uint32_t limit)const
455 {
456  return my->_remote_db->get_settle_orders(a, limit);
457 }
458 
459 vector<collateral_bid_object> wallet_api::get_collateral_bids(std::string asset, uint32_t limit, uint32_t start)const
460 {
461  return my->_remote_db->get_collateral_bids(asset, limit, start);
462 }
463 
465 {
467 }
468 
470  string brain_key,
471  int number_of_desired_keys) const
472 {
473  return graphene::wallet::utility::derive_owner_keys_from_brain_key(brain_key, number_of_desired_keys);
474 }
475 
477 {
478  bool is_known = my->_remote_db->is_public_key_registered(public_key);
479  return is_known;
480 }
481 
482 
483 string wallet_api::serialize_transaction( signed_transaction tx )const
484 {
485  return fc::to_hex(fc::raw::pack(tx));
486 }
487 
488 variant wallet_api::get_object( object_id_type id ) const
489 {
490  return my->_remote_db->get_objects({id}, {});
491 }
492 
494 {
495  return my->get_wallet_filename();
496 }
497 
499 {
500  return my->begin_builder_transaction();
501 }
502 
504  transaction_handle_type transaction_handle,
505  const operation& op)
506 {
507  my->add_operation_to_builder_transaction(transaction_handle, op);
508 }
509 
512  unsigned operation_index,
513  const operation& new_op)
514 {
515  my->replace_operation_in_builder_transaction(handle, operation_index, new_op);
516 }
517 
519 {
520  return my->set_fees_on_builder_transaction(handle, fee_asset);
521 }
522 
524 {
525  return my->preview_builder_transaction(handle);
526 }
527 
528 signed_transaction wallet_api::sign_builder_transaction(transaction_handle_type transaction_handle, bool broadcast)
529 {
530  return my->sign_builder_transaction(transaction_handle, broadcast);
531 }
532 
534  const vector<public_key_type>& explicit_keys,
535  bool broadcast)
536 {
537  return my->sign_builder_transaction2(transaction_handle, explicit_keys, broadcast);
538 }
539 
540 pair<transaction_id_type,signed_transaction> wallet_api::broadcast_transaction(signed_transaction tx)
541 {
542  return my->broadcast_transaction(tx);
543 }
544 
547  time_point_sec expiration,
548  uint32_t review_period_seconds,
549  bool broadcast)
550 {
551  return my->propose_builder_transaction(handle, expiration, review_period_seconds, broadcast);
552 }
553 
556  string account_name_or_id,
557  time_point_sec expiration,
558  uint32_t review_period_seconds,
559  bool broadcast)
560 {
561  return my->propose_builder_transaction2(handle, account_name_or_id, expiration, review_period_seconds, broadcast);
562 }
563 
565 {
566  return my->remove_builder_transaction(handle);
567 }
568 
569 account_object wallet_api::get_account(string account_name_or_id) const
570 {
571  return my->get_account(account_name_or_id);
572 }
573 
574 extended_asset_object wallet_api::get_asset(string asset_name_or_id) const
575 {
576  auto found_asset = my->find_asset(asset_name_or_id);
577  FC_ASSERT( found_asset, "Unable to find asset '${a}'", ("a",asset_name_or_id) );
578  return *found_asset;
579 }
580 
582 {
583  auto asset = get_asset(asset_name_or_id);
584  FC_ASSERT(asset.is_market_issued() && asset.bitasset_data_id);
585  return my->get_object(*asset.bitasset_data_id);
586 }
587 
588 account_id_type wallet_api::get_account_id(string account_name_or_id) const
589 {
590  return my->get_account_id(account_name_or_id);
591 }
592 
593 asset_id_type wallet_api::get_asset_id(string asset_symbol_or_id) const
594 {
595  return my->get_asset_id(asset_symbol_or_id);
596 }
597 
598 bool wallet_api::import_key(string account_name_or_id, string wif_key)
599 {
600  FC_ASSERT(!is_locked());
601  // backup wallet
602  fc::optional<fc::ecc::private_key> optional_private_key = wif_to_key(wif_key);
603  if (!optional_private_key)
604  FC_THROW("Invalid private key");
605  string shorthash = detail::address_to_shorthash(optional_private_key->get_public_key());
606  copy_wallet_file( "before-import-key-" + shorthash );
607 
608  if( my->import_key(account_name_or_id, wif_key) )
609  {
611  copy_wallet_file( "after-import-key-" + shorthash );
612  return true;
613  }
614  return false;
615 }
616 
617 map<string, bool> wallet_api::import_accounts( string filename, string password )
618 {
619  FC_ASSERT( !is_locked() );
620  FC_ASSERT( fc::exists( filename ) );
621 
622  const auto imported_keys = fc::json::from_file<exported_keys>( filename );
623 
624  const auto password_hash = fc::sha512::hash( password );
625  FC_ASSERT( fc::sha512::hash( password_hash ) == imported_keys.password_checksum );
626 
627  map<string, bool> result;
628  for( const auto& item : imported_keys.account_keys )
629  {
630  const auto import_this_account = [ & ]() -> bool
631  {
632  try
633  {
634  const account_object account = get_account( item.account_name );
635  const auto& owner_keys = account.owner.get_keys();
636  const auto& active_keys = account.active.get_keys();
637 
638  for( const auto& public_key : item.public_keys )
639  {
640  if( std::find( owner_keys.begin(), owner_keys.end(), public_key ) != owner_keys.end() )
641  return true;
642 
643  if( std::find( active_keys.begin(), active_keys.end(), public_key ) != active_keys.end() )
644  return true;
645  }
646  }
647  catch( ... )
648  {
649  }
650 
651  return false;
652  };
653 
654  const auto should_proceed = import_this_account();
655  result[ item.account_name ] = should_proceed;
656 
657  if( should_proceed )
658  {
659  uint32_t import_successes = 0;
660  uint32_t import_failures = 0;
661  // TODO: First check that all private keys match public keys
662  for( const auto& encrypted_key : item.encrypted_private_keys )
663  {
664  try
665  {
666  const auto plain_text = fc::aes_decrypt( password_hash, encrypted_key );
667  const auto private_key = fc::raw::unpack<private_key_type>( plain_text );
668 
669  import_key( item.account_name, string( graphene::utilities::key_to_wif( private_key ) ) );
670  ++import_successes;
671  }
672  catch( const fc::exception& e )
673  {
674  elog( "Couldn't import key due to exception ${e}", ("e", e.to_detail_string()) );
675  ++import_failures;
676  }
677  }
678  ilog( "successfully imported ${n} keys for account ${name}",
679  ("n", import_successes)("name", item.account_name) );
680  if( import_failures > 0 )
681  elog( "failed to import ${n} keys for account ${name}",
682  ("n", import_failures)("name", item.account_name) );
683  }
684  }
685 
686  return result;
687 }
688 
690  string filename,
691  string password,
692  string src_account_name,
693  string dest_account_name )
694 {
695  FC_ASSERT( !is_locked() );
696  FC_ASSERT( fc::exists( filename ) );
697 
698  bool is_my_account = false;
699  const auto accounts = list_my_accounts();
700  for( const auto& account : accounts )
701  {
702  if( account.name == dest_account_name )
703  {
704  is_my_account = true;
705  break;
706  }
707  }
708  FC_ASSERT( is_my_account );
709 
710  const auto imported_keys = fc::json::from_file<exported_keys>( filename );
711 
712  const auto password_hash = fc::sha512::hash( password );
713  FC_ASSERT( fc::sha512::hash( password_hash ) == imported_keys.password_checksum );
714 
715  bool found_account = false;
716  for( const auto& item : imported_keys.account_keys )
717  {
718  if( item.account_name != src_account_name )
719  continue;
720 
721  found_account = true;
722 
723  for( const auto& encrypted_key : item.encrypted_private_keys )
724  {
725  const auto plain_text = fc::aes_decrypt( password_hash, encrypted_key );
726  const auto private_key = fc::raw::unpack<private_key_type>( plain_text );
727 
728  my->import_key( dest_account_name, string( graphene::utilities::key_to_wif( private_key ) ) );
729  }
730 
731  return true;
732  }
734 
735  FC_ASSERT( found_account );
736 
737  return false;
738 }
739 
740 string wallet_api::normalize_brain_key(string s) const
741 {
742  return detail::normalize_brain_key( s );
743 }
744 
746 {
747  return my->info();
748 }
749 
750 variant_object wallet_api::about() const
751 {
752  return my->about();
753 }
754 
755 fc::ecc::private_key wallet_api::derive_private_key(const std::string& prefix_string, int sequence_number) const
756 {
757  return detail::derive_private_key( prefix_string, sequence_number );
758 }
759 
760 signed_transaction wallet_api::register_account(string name,
761  public_key_type owner_pubkey,
762  public_key_type active_pubkey,
763  string registrar_account,
764  string referrer_account,
765  uint32_t referrer_percent,
766  bool broadcast)
767 {
768  return my->register_account( name, owner_pubkey, active_pubkey,
769  registrar_account, referrer_account, referrer_percent, broadcast );
770 }
771 signed_transaction wallet_api::create_account_with_brain_key(string brain_key, string account_name,
772  string registrar_account, string referrer_account,
773  bool broadcast /* = false */)
774 {
775  return my->create_account_with_brain_key(
776  brain_key, account_name, registrar_account,
777  referrer_account, broadcast
778  );
779 }
780 signed_transaction wallet_api::issue_asset(string to_account, string amount, string symbol,
781  string memo, bool broadcast)
782 {
783  return my->issue_asset(to_account, amount, symbol, memo, broadcast);
784 }
785 
786 signed_transaction wallet_api::transfer(string from, string to, string amount,
787  string asset_symbol, string memo, bool broadcast /* = false */)
788 {
789  return my->transfer(from, to, amount, asset_symbol, memo, broadcast);
790 }
791 signed_transaction wallet_api::create_asset(string issuer,
792  string symbol,
793  uint8_t precision,
794  asset_options common,
795  fc::optional<bitasset_options> bitasset_opts,
796  bool broadcast)
797 
798 {
799  return my->create_asset(issuer, symbol, precision, common, bitasset_opts, broadcast);
800 }
801 
802 signed_transaction wallet_api::update_asset(string symbol,
803  optional<string> new_issuer,
804  asset_options new_options,
805  bool broadcast /* = false */)
806 {
807  return my->update_asset(symbol, new_issuer, new_options, broadcast);
808 }
809 
810 signed_transaction wallet_api::update_asset_issuer(string symbol,
811  string new_issuer,
812  bool broadcast /* = false */)
813 {
814  return my->update_asset_issuer(symbol, new_issuer, broadcast);
815 }
816 
817 signed_transaction wallet_api::update_bitasset(string symbol,
818  bitasset_options new_options,
819  bool broadcast /* = false */)
820 {
821  return my->update_bitasset(symbol, new_options, broadcast);
822 }
823 
824 signed_transaction wallet_api::update_asset_feed_producers(string symbol,
825  flat_set<string> new_feed_producers,
826  bool broadcast /* = false */)
827 {
828  return my->update_asset_feed_producers(symbol, new_feed_producers, broadcast);
829 }
830 
831 signed_transaction wallet_api::publish_asset_feed(string publishing_account,
832  string symbol,
833  price_feed feed,
834  bool broadcast /* = false */)
835 {
836  return my->publish_asset_feed(publishing_account, symbol, feed, broadcast);
837 }
838 
839 signed_transaction wallet_api::fund_asset_fee_pool(string from,
840  string symbol,
841  string amount,
842  bool broadcast /* = false */)
843 {
844  return my->fund_asset_fee_pool(from, symbol, amount, broadcast);
845 }
846 
847 signed_transaction wallet_api::claim_asset_fee_pool(string symbol,
848  string amount,
849  bool broadcast /* = false */)
850 {
851  return my->claim_asset_fee_pool(symbol, amount, broadcast);
852 }
853 
854 signed_transaction wallet_api::reserve_asset(string from,
855  string amount,
856  string symbol,
857  bool broadcast /* = false */)
858 {
859  return my->reserve_asset(from, amount, symbol, broadcast);
860 }
861 
862 signed_transaction wallet_api::global_settle_asset(string symbol,
863  price settle_price,
864  bool broadcast /* = false */)
865 {
866  return my->global_settle_asset(symbol, settle_price, broadcast);
867 }
868 
869 signed_transaction wallet_api::settle_asset(string account_to_settle,
870  string amount_to_settle,
871  string symbol,
872  bool broadcast /* = false */)
873 {
874  return my->settle_asset(account_to_settle, amount_to_settle, symbol, broadcast);
875 }
876 
877 signed_transaction wallet_api::bid_collateral(string bidder_name,
878  string debt_amount, string debt_symbol,
879  string additional_collateral,
880  bool broadcast )
881 {
882  return my->bid_collateral(bidder_name, debt_amount, debt_symbol, additional_collateral, broadcast);
883 }
884 
885 signed_transaction wallet_api::whitelist_account(string authorizing_account,
886  string account_to_list,
887  account_whitelist_operation::account_listing new_listing_status,
888  bool broadcast /* = false */)
889 {
890  return my->whitelist_account(authorizing_account, account_to_list, new_listing_status, broadcast);
891 }
892 
893 signed_transaction wallet_api::create_committee_member(string owner_account, string url,
894  bool broadcast /* = false */)
895 {
896  return my->create_committee_member(owner_account, url, broadcast);
897 }
898 
899 map<string,witness_id_type> wallet_api::list_witnesses(const string& lowerbound, uint32_t limit)
900 {
901  return my->_remote_db->lookup_witness_accounts(lowerbound, limit);
902 }
903 
904 map<string,committee_member_id_type> wallet_api::list_committee_members(const string& lowerbound, uint32_t limit)
905 {
906  return my->_remote_db->lookup_committee_member_accounts(lowerbound, limit);
907 }
908 
910 {
911  return my->get_witness(owner_account);
912 }
913 
915 {
916  return my->get_committee_member(owner_account);
917 }
918 
919 signed_transaction wallet_api::create_witness(string owner_account,
920  string url,
921  bool broadcast /* = false */)
922 {
923  return my->create_witness(owner_account, url, broadcast);
924 }
925 
926 signed_transaction wallet_api::create_worker(
927  string owner_account,
928  time_point_sec work_begin_date,
929  time_point_sec work_end_date,
930  share_type daily_pay,
931  string name,
932  string url,
933  variant worker_settings,
934  bool broadcast /* = false */)
935 {
936  return my->create_worker( owner_account, work_begin_date, work_end_date,
937  daily_pay, name, url, worker_settings, broadcast );
938 }
939 
941  string owner_account,
942  worker_vote_delta delta,
943  bool broadcast /* = false */)
944 {
945  return my->update_worker_votes( owner_account, delta, broadcast );
946 }
947 
948 signed_transaction wallet_api::update_witness(
949  string witness_name,
950  string url,
951  string block_signing_key,
952  bool broadcast /* = false */)
953 {
954  return my->update_witness(witness_name, url, block_signing_key, broadcast);
955 }
956 
957 vector< vesting_balance_object_with_info > wallet_api::get_vesting_balances( string account_name )
958 {
959  return my->get_vesting_balances( account_name );
960 }
961 
962 signed_transaction wallet_api::withdraw_vesting(
963  string witness_name,
964  string amount,
965  string asset_symbol,
966  bool broadcast /* = false */)
967 {
968  return my->withdraw_vesting( witness_name, amount, asset_symbol, broadcast );
969 }
970 
971 signed_transaction wallet_api::vote_for_committee_member(string voting_account,
972  string witness,
973  bool approve,
974  bool broadcast /* = false */)
975 {
976  return my->vote_for_committee_member(voting_account, witness, approve, broadcast);
977 }
978 
979 signed_transaction wallet_api::vote_for_witness(string voting_account,
980  string witness,
981  bool approve,
982  bool broadcast /* = false */)
983 {
984  return my->vote_for_witness(voting_account, witness, approve, broadcast);
985 }
986 
987 signed_transaction wallet_api::set_voting_proxy(string account_to_modify,
988  optional<string> voting_account,
989  bool broadcast /* = false */)
990 {
991  return my->set_voting_proxy(account_to_modify, voting_account, broadcast);
992 }
993 
994 signed_transaction wallet_api::set_desired_witness_and_committee_member_count(string account_to_modify,
995  uint16_t desired_number_of_witnesses,
996  uint16_t desired_number_of_committee_members,
997  bool broadcast /* = false */)
998 {
999  return my->set_desired_witness_and_committee_member_count(account_to_modify, desired_number_of_witnesses,
1000  desired_number_of_committee_members, broadcast);
1001 }
1002 
1003 void wallet_api::set_wallet_filename(string wallet_filename)
1004 {
1005  my->_wallet_filename = wallet_filename;
1006 }
1007 
1008 signed_transaction wallet_api::sign_transaction(signed_transaction tx, bool broadcast /* = false */)
1009 { try {
1010  return my->sign_transaction( tx, broadcast);
1011 } FC_CAPTURE_AND_RETHROW( (tx) ) }
1012 
1013 signed_transaction wallet_api::sign_transaction2(signed_transaction tx, const vector<public_key_type>& signing_keys,
1014  bool broadcast /* = false */)
1015 { try {
1016  return my->sign_transaction2( tx, signing_keys, broadcast);
1017 } FC_CAPTURE_AND_RETHROW( (tx) ) }
1018 
1019 flat_set<public_key_type> wallet_api::get_transaction_signers(const signed_transaction &tx) const
1020 { try {
1021  return my->get_transaction_signers(tx);
1022 } FC_CAPTURE_AND_RETHROW( (tx) ) }
1023 
1024 vector<flat_set<account_id_type>> wallet_api::get_key_references(const vector<public_key_type> &keys) const
1025 { try {
1026  return my->get_key_references(keys);
1027 } FC_CAPTURE_AND_RETHROW( (keys) ) }
1028 
1030 {
1031  return my->get_prototype_operation( operation_name );
1032 }
1033 
1034 void wallet_api::dbg_make_uia(string creator, string symbol)
1035 {
1036  FC_ASSERT(!is_locked());
1037  my->dbg_make_uia(creator, symbol);
1038 }
1039 
1040 void wallet_api::dbg_make_mia(string creator, string symbol)
1041 {
1042  FC_ASSERT(!is_locked());
1043  my->dbg_make_mia(creator, symbol);
1044 }
1045 
1046 void wallet_api::dbg_push_blocks( std::string src_filename, uint32_t count )
1047 {
1048  my->dbg_push_blocks( src_filename, count );
1049 }
1050 
1051 void wallet_api::dbg_generate_blocks( std::string debug_wif_key, uint32_t count )
1052 {
1053  my->dbg_generate_blocks( debug_wif_key, count );
1054 }
1055 
1056 void wallet_api::dbg_stream_json_objects( const std::string& filename )
1057 {
1058  my->dbg_stream_json_objects( filename );
1059 }
1060 
1062 {
1063  my->dbg_update_object( update );
1064 }
1065 
1066 void wallet_api::network_add_nodes( const vector<string>& nodes )
1067 {
1068  my->network_add_nodes( nodes );
1069 }
1070 
1072 {
1073  return my->network_get_connected_peers();
1074 }
1075 
1076 void wallet_api::flood_network(string prefix, uint32_t number_of_transactions)
1077 {
1078  FC_ASSERT(!is_locked());
1079  my->flood_network(prefix, number_of_transactions);
1080 }
1081 
1083  const string& proposing_account,
1084  fc::time_point_sec expiration_time,
1085  const variant_object& changed_values,
1086  bool broadcast /* = false */
1087  )
1088 {
1089  return my->propose_parameter_change( proposing_account, expiration_time, changed_values, broadcast );
1090 }
1091 
1093  const string& proposing_account,
1094  fc::time_point_sec expiration_time,
1095  const variant_object& changed_fees,
1096  bool broadcast /* = false */
1097  )
1098 {
1099  return my->propose_fee_change( proposing_account, expiration_time, changed_fees, broadcast );
1100 }
1101 
1102 signed_transaction wallet_api::approve_proposal(
1103  const string& fee_paying_account,
1104  const string& proposal_id,
1105  const approval_delta& delta,
1106  bool broadcast /* = false */
1107  )
1108 {
1109  return my->approve_proposal( fee_paying_account, proposal_id, delta, broadcast );
1110 }
1111 
1113 {
1114  return my->get_global_properties();
1115 }
1116 
1118 {
1119  return my->get_dynamic_global_properties();
1120 }
1121 
1122 signed_transaction wallet_api::add_transaction_signature( signed_transaction tx,
1123  bool broadcast )
1124 {
1125  return my->add_transaction_signature( tx, broadcast );
1126 }
1127 
1128 string wallet_api::help()const
1129 {
1130  std::vector<std::string> method_names = my->method_documentation.get_method_names();
1131  std::stringstream ss;
1132  for (const std::string method_name : method_names)
1133  {
1134  try
1135  {
1136  ss << my->method_documentation.get_brief_description(method_name);
1137  }
1138  catch (const fc::key_not_found_exception&)
1139  {
1140  ss << method_name << " (no help available)\n";
1141  }
1142  }
1143  return ss.str();
1144 }
1145 
1146 string wallet_api::gethelp(const string& method)const
1147 {
1148  fc::api<wallet_api> tmp;
1149  std::stringstream ss;
1150  ss << "\n";
1151 
1152  std::string doxygenHelpString = my->method_documentation.get_detailed_description(method);
1153  if (!doxygenHelpString.empty())
1154  ss << doxygenHelpString << "\n";
1155 
1156  if( method == "import_key" )
1157  {
1158  ss << "usage: import_key ACCOUNT_NAME_OR_ID WIF_PRIVATE_KEY\n\n";
1159  ss << "example: import_key \"1.3.11\" 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3\n";
1160  ss << "example: import_key \"usera\" 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3\n";
1161  }
1162  else if( method == "transfer" )
1163  {
1164  ss << "usage: transfer FROM TO AMOUNT SYMBOL \"memo\" BROADCAST\n\n";
1165  ss << "example: transfer \"1.3.11\" \"1.3.4\" 1000.03 CORE \"memo\" true\n";
1166  ss << "example: transfer \"usera\" \"userb\" 1000.123 CORE \"memo\" true\n";
1167  }
1168  else if( method == "create_account_with_brain_key" )
1169  {
1170  ss << "usage: create_account_with_brain_key BRAIN_KEY ACCOUNT_NAME REGISTRAR REFERRER BROADCAST\n\n";
1171  ss << "example: create_account_with_brain_key "
1172  << "\"my really long brain key\" \"newaccount\" \"1.3.11\" \"1.3.11\" true\n";
1173  ss << "example: create_account_with_brain_key "
1174  << "\"my really long brain key\" \"newaccount\" \"someaccount\" \"otheraccount\" true\n";
1175  ss << "\n";
1176  ss << "This method should be used if you would like the wallet to generate new keys derived from the "
1177  << "brain key.\n";
1178  ss << "The BRAIN_KEY will be used as the owner key, and the active key will be derived from the BRAIN_KEY. "
1179  << "Use\n";
1180  ss << "register_account if you already know the keys you know the public keys that you would like to "
1181  << "register.\n";
1182 
1183  }
1184  else if( method == "register_account" )
1185  {
1186  ss << "usage: register_account ACCOUNT_NAME OWNER_PUBLIC_KEY ACTIVE_PUBLIC_KEY REGISTRAR "
1187  << "REFERRER REFERRER_PERCENT BROADCAST\n\n";
1188  ss << "example: register_account \"newaccount\" \"CORE6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV\" "
1189  << "\"CORE6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV\" \"1.3.11\" \"1.3.11\" 50 true\n";
1190  ss << "\n";
1191  ss << "Use this method to register an account for which you do not know the private keys.";
1192  }
1193  else if( method == "create_asset" )
1194  {
1195  ss << "usage: ISSUER SYMBOL PRECISION_DIGITS OPTIONS BITASSET_OPTIONS BROADCAST\n\n";
1196  ss << "PRECISION_DIGITS: the number of digits after the decimal point\n\n";
1197  ss << "Example value of OPTIONS: \n";
1199  ss << "\nExample value of BITASSET_OPTIONS: \n";
1201  ss << "\nBITASSET_OPTIONS may be null\n";
1202  }
1203  else if (doxygenHelpString.empty())
1204  ss << "No help defined for method " << method << "\n";
1205 
1206  return ss.str();
1207 }
1208 
1209 bool wallet_api::load_wallet_file( string wallet_filename )
1210 {
1211  return my->load_wallet_file( wallet_filename );
1212 }
1213 
1215 {
1216  my->quit();
1217 }
1218 
1219 void wallet_api::save_wallet_file( string wallet_filename )
1220 {
1221  my->save_wallet_file( wallet_filename );
1222 }
1223 
1224 std::map<string,std::function<string(fc::variant,const fc::variants&)> >
1226 {
1227  return my->get_result_formatters();
1228 }
1229 
1231 {
1232  return my->is_locked();
1233 }
1235 {
1236  return my->_wallet.cipher_keys.size() == 0;
1237 }
1238 
1240 {
1241  my->encrypt_keys();
1242 }
1243 
1245 { try {
1246  FC_ASSERT( !is_locked() );
1247  encrypt_keys();
1248  for( auto key : my->_keys )
1249  key.second = key_to_wif(fc::ecc::private_key());
1250  my->_keys.clear();
1251  my->_checksum = fc::sha512();
1252  my->self.lock_changed(true);
1254 
1255 void wallet_api::unlock(string password)
1256 { try {
1257  FC_ASSERT(password.size() > 0);
1258  auto pw = fc::sha512::hash(password.c_str(), password.size());
1259  vector<char> decrypted = fc::aes_decrypt(pw, my->_wallet.cipher_keys);
1260  auto pk = fc::raw::unpack<plain_keys>(decrypted);
1261  FC_ASSERT(pk.checksum == pw);
1262  my->_keys = std::move(pk.keys);
1263  my->_checksum = pk.checksum;
1264  my->self.lock_changed(false);
1266 
1267 void wallet_api::set_password( string password )
1268 {
1269  if( !is_new() )
1270  FC_ASSERT( !is_locked(), "The wallet must be unlocked before the password can be set" );
1271  my->_checksum = fc::sha512::hash( password.c_str(), password.size() );
1272  lock();
1273 }
1274 
1275 vector< signed_transaction > wallet_api::import_balance(
1276  string name_or_id,
1277  const vector<string>& wif_keys,
1278  bool broadcast )
1279 {
1280  return my->import_balance( name_or_id, wif_keys, broadcast );
1281 }
1282 
1283 map<public_key_type, string> wallet_api::dump_private_keys()
1284 {
1285  FC_ASSERT(!is_locked());
1286  return my->_keys;
1287 }
1288 
1289 signed_transaction wallet_api::upgrade_account( string name, bool broadcast )
1290 {
1291  return my->upgrade_account(name,broadcast);
1292 }
1293 
1294 signed_transaction wallet_api::sell_asset(string seller_account,
1295  string amount_to_sell,
1296  string symbol_to_sell,
1297  string min_to_receive,
1298  string symbol_to_receive,
1299  uint32_t expiration,
1300  bool fill_or_kill,
1301  bool broadcast)
1302 {
1303  return my->sell_asset(seller_account, amount_to_sell, symbol_to_sell, min_to_receive,
1304  symbol_to_receive, expiration, fill_or_kill, broadcast);
1305 }
1306 
1307 signed_transaction wallet_api::borrow_asset(string seller_name, string amount_to_sell,
1308  string asset_symbol, string amount_of_collateral, bool broadcast)
1309 {
1310  FC_ASSERT(!is_locked());
1311  return my->borrow_asset(seller_name, amount_to_sell, asset_symbol, amount_of_collateral, broadcast);
1312 }
1313 
1314 signed_transaction wallet_api::borrow_asset_ext( string seller_name, string amount_to_sell,
1315  string asset_symbol, string amount_of_collateral,
1317  bool broadcast)
1318 {
1319  FC_ASSERT(!is_locked());
1320  return my->borrow_asset_ext(seller_name, amount_to_sell, asset_symbol,
1321  amount_of_collateral, extensions, broadcast);
1322 }
1323 
1324 signed_transaction wallet_api::cancel_order(object_id_type order_id, bool broadcast)
1325 {
1326  FC_ASSERT(!is_locked());
1327  return my->cancel_order(order_id, broadcast);
1328 }
1329 
1330 memo_data wallet_api::sign_memo(string from, string to, string memo)
1331 {
1332  FC_ASSERT(!is_locked());
1333  return my->sign_memo(from, to, memo);
1334 }
1335 
1336 string wallet_api::read_memo(const memo_data& memo)
1337 {
1338  FC_ASSERT(!is_locked());
1339  return my->read_memo(memo);
1340 }
1341 
1342 signed_message wallet_api::sign_message(string signer, string message)
1343 {
1344  FC_ASSERT(!is_locked());
1345  return my->sign_message(signer, message);
1346 }
1347 
1348 bool wallet_api::verify_message( string message, string account, int block, const string& time, compact_signature sig )
1349 {
1350  return my->verify_message( message, account, block, time, sig );
1351 }
1352 
1359 {
1360  return my->verify_signed_message( message );
1361 }
1362 
1369 {
1370  return my->verify_encapsulated_message( message );
1371 }
1372 
1373 
1374 string wallet_api::get_key_label( public_key_type key )const
1375 {
1376  auto key_itr = my->_wallet.labeled_keys.get<by_key>().find(key);
1377  if( key_itr != my->_wallet.labeled_keys.get<by_key>().end() )
1378  return key_itr->label;
1379  return string();
1380 }
1381 
1382 string wallet_api::get_private_key( public_key_type pubkey )const
1383 {
1384  return key_to_wif( my->get_private_key( pubkey ) );
1385 }
1386 
1387 public_key_type wallet_api::get_public_key( string label )const
1388 {
1389  try { return fc::variant(label, 1).as<public_key_type>( 1 ); } catch ( ... ){}
1390 
1391  auto key_itr = my->_wallet.labeled_keys.get<by_label>().find(label);
1392  if( key_itr != my->_wallet.labeled_keys.get<by_label>().end() )
1393  return key_itr->key;
1394  return public_key_type();
1395 }
1396 
1397 bool wallet_api::set_key_label( public_key_type key, string label )
1398 {
1399  auto result = my->_wallet.labeled_keys.insert( key_label{label,key} );
1400  if( result.second ) return true;
1401 
1402  auto key_itr = my->_wallet.labeled_keys.get<by_key>().find(key);
1403  auto label_itr = my->_wallet.labeled_keys.get<by_label>().find(label);
1404  if( label_itr == my->_wallet.labeled_keys.get<by_label>().end() )
1405  {
1406  if( key_itr != my->_wallet.labeled_keys.get<by_key>().end() )
1407  return my->_wallet.labeled_keys.get<by_key>().modify( key_itr, [&]( key_label& obj ){ obj.label = label; } );
1408  }
1409  return false;
1410 }
1411 map<string,public_key_type> wallet_api::get_blind_accounts()const
1412 {
1413  map<string,public_key_type> result;
1414  for( const auto& item : my->_wallet.labeled_keys )
1415  result[item.label] = item.key;
1416  return result;
1417 }
1418 map<string,public_key_type> wallet_api::get_my_blind_accounts()const
1419 {
1420  FC_ASSERT( !is_locked() );
1421  map<string,public_key_type> result;
1422  for( const auto& item : my->_wallet.labeled_keys )
1423  {
1424  if( my->_keys.find(item.key) != my->_keys.end() )
1425  result[item.label] = item.key;
1426  }
1427  return result;
1428 }
1429 
1430 public_key_type wallet_api::create_blind_account( string label, string brain_key )
1431 {
1432  FC_ASSERT( !is_locked() );
1433 
1434  auto label_itr = my->_wallet.labeled_keys.get<by_label>().find(label);
1435  if( label_itr != my->_wallet.labeled_keys.get<by_label>().end() )
1436  FC_ASSERT( !"Key with label already exists" );
1437  brain_key = fc::trim_and_normalize_spaces( brain_key );
1438  auto secret = fc::sha256::hash( brain_key.c_str(), brain_key.size() );
1439  auto priv_key = fc::ecc::private_key::regenerate( secret );
1440  public_key_type pub_key = priv_key.get_public_key();
1441 
1442  FC_ASSERT( set_key_label( pub_key, label ) );
1443 
1444  my->_keys[pub_key] = graphene::utilities::key_to_wif( priv_key );
1445 
1446  save_wallet_file();
1447  return pub_key;
1448 }
1449 
1450 vector<asset> wallet_api::get_blind_balances( string key_or_label )
1451 {
1452  vector<asset> result;
1453  map<asset_id_type, share_type> balances;
1454 
1455  vector<commitment_type> used;
1456 
1457  auto pub_key = get_public_key( key_or_label );
1458  auto& to_asset_used_idx = my->_wallet.blind_receipts.get<by_to_asset_used>();
1459  auto start = to_asset_used_idx.lower_bound( std::make_tuple(pub_key,asset_id_type(0),false) );
1460  auto end = to_asset_used_idx.lower_bound( std::make_tuple(pub_key,asset_id_type(uint32_t(0xffffffff)),true) );
1461  while( start != end )
1462  {
1463  if( !start->used )
1464  {
1465  auto answer = my->_remote_db->get_blinded_balances( {start->commitment()} );
1466  if( answer.size() )
1467  balances[start->amount.asset_id] += start->amount.amount;
1468  else
1469  used.push_back( start->commitment() );
1470  }
1471  ++start;
1472  }
1473  for( const auto& u : used )
1474  {
1475  auto itr = my->_wallet.blind_receipts.get<by_commitment>().find( u );
1476  my->_wallet.blind_receipts.modify( itr, []( blind_receipt& r ){ r.used = true; } );
1477  }
1478  for( auto item : balances )
1479  result.push_back( asset( item.second, item.first ) );
1480  return result;
1481 }
1482 
1483 blind_confirmation wallet_api::transfer_from_blind( string from_blind_account_key_or_label,
1484  string to_account_id_or_name,
1485  string amount_in,
1486  string symbol,
1487  bool broadcast )
1488 { try {
1489  transfer_from_blind_operation from_blind;
1490 
1491 
1492  auto fees = my->_remote_db->get_global_properties().parameters.get_current_fees();
1493  fc::optional<asset_object> asset_obj = get_asset(symbol);
1494  FC_ASSERT(asset_obj.valid(), "Could not find asset matching ${asset}", ("asset", symbol));
1495  auto amount = asset_obj->amount_from_string(amount_in);
1496 
1497  from_blind.fee = fees.calculate_fee( from_blind, asset_obj->options.core_exchange_rate );
1498 
1499  auto blind_in = asset_obj->amount_to_string( from_blind.fee + amount );
1500 
1501 
1502  auto conf = blind_transfer_help( from_blind_account_key_or_label,
1503  from_blind_account_key_or_label,
1504  blind_in, symbol, false, true/*to_temp*/ );
1505  FC_ASSERT( conf.outputs.size() > 0 );
1506 
1507  auto to_account = my->get_account( to_account_id_or_name );
1508  from_blind.to = to_account.id;
1509  from_blind.amount = amount;
1510  from_blind.blinding_factor = conf.outputs.back().decrypted_memo.blinding_factor;
1511  from_blind.inputs.push_back( {conf.outputs.back().decrypted_memo.commitment, authority() } );
1512  from_blind.fee = fees.calculate_fee( from_blind, asset_obj->options.core_exchange_rate );
1513 
1514  idump( (from_blind) );
1515  conf.trx.operations.push_back(from_blind);
1516  ilog( "about to validate" );
1517  conf.trx.validate();
1518 
1519  ilog( "about to broadcast" );
1520  conf.trx = sign_transaction( conf.trx, broadcast );
1521 
1522  if( broadcast && conf.outputs.size() == 2 ) {
1523 
1524  // Save the change
1525  blind_confirmation::output conf_output;
1526  blind_confirmation::output change_output = conf.outputs[0];
1527 
1528  // The wallet must have a private key for confirmation.to, this is used to decrypt the memo
1529  public_key_type from_key = get_public_key(from_blind_account_key_or_label);
1530  conf_output.confirmation.to = from_key;
1531  conf_output.confirmation.one_time_key = change_output.confirmation.one_time_key;
1532  conf_output.confirmation.encrypted_memo = change_output.confirmation.encrypted_memo;
1533  conf_output.confirmation_receipt = conf_output.confirmation;
1534  //try {
1536  from_blind_account_key_or_label,
1537  "@"+to_account.name );
1538  //} catch ( ... ){}
1539  }
1540 
1541  return conf;
1542 } FC_CAPTURE_AND_RETHROW( (from_blind_account_key_or_label)(to_account_id_or_name)(amount_in)(symbol) ) }
1543 
1545  string to_key_or_label,
1546  string amount_in,
1547  string symbol,
1548  bool broadcast )
1549 {
1550  return blind_transfer_help( from_key_or_label, to_key_or_label, amount_in, symbol, broadcast, false );
1551 }
1553  string to_key_or_label,
1554  string amount_in,
1555  string symbol,
1556  bool broadcast,
1557  bool to_temp )
1558 {
1559  blind_confirmation confirm;
1560  try {
1561 
1562  FC_ASSERT( !is_locked() );
1563  public_key_type from_key = get_public_key(from_key_or_label);
1564  public_key_type to_key = get_public_key(to_key_or_label);
1565 
1566  fc::optional<asset_object> asset_obj = get_asset(symbol);
1567  FC_ASSERT(asset_obj.valid(), "Could not find asset matching ${asset}", ("asset", symbol));
1568 
1569  blind_transfer_operation blind_tr;
1570  blind_tr.outputs.resize(2);
1571 
1572  auto fees = my->_remote_db->get_global_properties().parameters.get_current_fees();
1573 
1574  auto amount = asset_obj->amount_from_string(amount_in);
1575 
1576  asset total_amount = asset_obj->amount(0);
1577 
1578  vector<fc::sha256> blinding_factors;
1579 
1580  //auto from_priv_key = my->get_private_key( from_key );
1581 
1582  blind_tr.fee = fees.calculate_fee( blind_tr, asset_obj->options.core_exchange_rate );
1583 
1584  vector<commitment_type> used;
1585 
1586  auto& to_asset_used_idx = my->_wallet.blind_receipts.get<by_to_asset_used>();
1587  auto start = to_asset_used_idx.lower_bound( std::make_tuple(from_key,amount.asset_id,false) );
1588  auto end = to_asset_used_idx.lower_bound( std::make_tuple(from_key,amount.asset_id,true) );
1589  while( start != end )
1590  {
1591  auto result = my->_remote_db->get_blinded_balances( {start->commitment() } );
1592  if( result.size() == 0 )
1593  {
1594  used.push_back( start->commitment() );
1595  }
1596  else
1597  {
1598  blind_tr.inputs.push_back({start->commitment(), start->control_authority});
1599  blinding_factors.push_back( start->data.blinding_factor );
1600  total_amount += start->amount;
1601 
1602  if( total_amount >= amount + blind_tr.fee )
1603  break;
1604  }
1605  ++start;
1606  }
1607  for( const auto& u : used )
1608  {
1609  auto itr = my->_wallet.blind_receipts.get<by_commitment>().find( u );
1610  my->_wallet.blind_receipts.modify( itr, []( blind_receipt& r ){ r.used = true; } );
1611  }
1612 
1613  FC_ASSERT( total_amount >= amount+blind_tr.fee,
1614  "Insufficient Balance",
1615  ("available",total_amount)("amount",amount)("fee",blind_tr.fee) );
1616 
1617  auto one_time_key = fc::ecc::private_key::generate();
1618  auto secret = one_time_key.get_shared_secret( to_key );
1619  auto child = fc::sha256::hash( secret );
1620  auto nonce = fc::sha256::hash( one_time_key.get_secret() );
1621  auto blind_factor = fc::sha256::hash( child );
1622 
1623  auto from_secret = one_time_key.get_shared_secret( from_key );
1624  auto from_child = fc::sha256::hash( from_secret );
1625  auto from_nonce = fc::sha256::hash( nonce );
1626 
1627  auto change = total_amount - amount - blind_tr.fee;
1628  fc::sha256 change_blind_factor;
1629  fc::sha256 to_blind_factor;
1630  if( change.amount > 0 )
1631  {
1632  idump(("to_blind_factor")(blind_factor) );
1633  blinding_factors.push_back( blind_factor );
1634  change_blind_factor = fc::ecc::blind_sum( blinding_factors, blinding_factors.size() - 1 );
1635  wdump(("change_blind_factor")(change_blind_factor) );
1636  }
1637  else // change == 0
1638  {
1639  blind_tr.outputs.resize(1);
1640  blind_factor = fc::ecc::blind_sum( blinding_factors, blinding_factors.size() );
1641  idump(("to_sum_blind_factor")(blind_factor) );
1642  blinding_factors.push_back( blind_factor );
1643  idump(("nochange to_blind_factor")(blind_factor) );
1644  }
1645  fc::ecc::public_key from_pub_key = from_key;
1646  fc::ecc::public_key to_pub_key = to_key;
1647 
1648  blind_output to_out;
1649  to_out.owner = to_temp ? authority() : authority( 1, public_key_type( to_pub_key.child( child ) ), 1 );
1650  to_out.commitment = fc::ecc::blind( blind_factor, amount.amount.value );
1651  idump(("to_out.blind")(blind_factor)(to_out.commitment) );
1652 
1653 
1654  if( blind_tr.outputs.size() > 1 )
1655  {
1656  to_out.range_proof = fc::ecc::range_proof_sign( 0, to_out.commitment, blind_factor, nonce,
1657  0, RANGE_PROOF_MANTISSA, amount.amount.value );
1658 
1659  blind_output change_out;
1660  change_out.owner = authority( 1, public_key_type( from_pub_key.child( from_child ) ), 1 );
1661  change_out.commitment = fc::ecc::blind( change_blind_factor, change.amount.value );
1662  change_out.range_proof = fc::ecc::range_proof_sign( 0, change_out.commitment, change_blind_factor, from_nonce,
1663  0, RANGE_PROOF_MANTISSA, change.amount.value );
1664  blind_tr.outputs[1] = change_out;
1665 
1666 
1667  blind_confirmation::output conf_output;
1668  conf_output.label = from_key_or_label;
1669  conf_output.pub_key = from_key;
1670  conf_output.decrypted_memo.from = from_key;
1671  conf_output.decrypted_memo.amount = change;
1672  conf_output.decrypted_memo.blinding_factor = change_blind_factor;
1673  conf_output.decrypted_memo.commitment = change_out.commitment;
1674  conf_output.decrypted_memo.check = from_secret._hash[0].value();
1675  conf_output.confirmation.one_time_key = one_time_key.get_public_key();
1676  conf_output.confirmation.to = from_key;
1677  conf_output.confirmation.encrypted_memo =
1678  fc::aes_encrypt( from_secret, fc::raw::pack( conf_output.decrypted_memo ) );
1679  conf_output.auth = change_out.owner;
1680  conf_output.confirmation_receipt = conf_output.confirmation;
1681 
1682  confirm.outputs.push_back( conf_output );
1683  }
1684  blind_tr.outputs[0] = to_out;
1685 
1686  blind_confirmation::output conf_output;
1687  conf_output.label = to_key_or_label;
1688  conf_output.pub_key = to_key;
1689  conf_output.decrypted_memo.from = from_key;
1690  conf_output.decrypted_memo.amount = amount;
1691  conf_output.decrypted_memo.blinding_factor = blind_factor;
1692  conf_output.decrypted_memo.commitment = to_out.commitment;
1693  conf_output.decrypted_memo.check = secret._hash[0].value();
1694  conf_output.confirmation.one_time_key = one_time_key.get_public_key();
1695  conf_output.confirmation.to = to_key;
1696  conf_output.confirmation.encrypted_memo = fc::aes_encrypt( secret, fc::raw::pack( conf_output.decrypted_memo ) );
1697  conf_output.auth = to_out.owner;
1698  conf_output.confirmation_receipt = conf_output.confirmation;
1699 
1700  confirm.outputs.push_back( conf_output );
1701 
1703  std::sort( blind_tr.outputs.begin(), blind_tr.outputs.end(),
1704  [&]( const blind_output& a, const blind_output& b ){ return a.commitment < b.commitment; } );
1705  std::sort( blind_tr.inputs.begin(), blind_tr.inputs.end(),
1706  [&]( const blind_input& a, const blind_input& b ){ return a.commitment < b.commitment; } );
1707 
1708  confirm.trx.operations.emplace_back( std::move(blind_tr) );
1709  ilog( "validate before" );
1710  confirm.trx.validate();
1711  confirm.trx = sign_transaction(confirm.trx, broadcast);
1712 
1713  if( broadcast )
1714  {
1715  for( const auto& out : confirm.outputs )
1716  {
1717  try { receive_blind_transfer( out.confirmation_receipt, from_key_or_label, "" ); } catch ( ... ){}
1718  }
1719  }
1720 
1721  return confirm;
1722 } FC_CAPTURE_AND_RETHROW( (from_key_or_label)(to_key_or_label)(amount_in)(symbol)(broadcast)(confirm) ) }
1723 
1724 
1725 
1726 /*
1727  * Transfers a public balance from @from to one or more blinded balances using a
1728  * stealth transfer.
1729  */
1730 blind_confirmation wallet_api::transfer_to_blind( string from_account_id_or_name,
1731  string asset_symbol,
1732  /* map from key or label to amount */
1733  vector<pair<string, string>> to_amounts,
1734  bool broadcast )
1735 { try {
1736  FC_ASSERT( !is_locked() );
1737  idump((to_amounts));
1738 
1739  blind_confirmation confirm;
1740  account_object from_account = my->get_account(from_account_id_or_name);
1741 
1742  fc::optional<asset_object> asset_obj = get_asset(asset_symbol);
1743  FC_ASSERT(asset_obj, "Could not find asset matching ${asset}", ("asset", asset_symbol));
1744 
1746  bop.from = from_account.id;
1747 
1748  vector<fc::sha256> blinding_factors;
1749 
1750  asset total_amount = asset_obj->amount(0);
1751 
1752  for( auto item : to_amounts )
1753  {
1754  auto one_time_key = fc::ecc::private_key::generate();
1755  auto to_key = get_public_key( item.first );
1756  auto secret = one_time_key.get_shared_secret( to_key );
1757  auto child = fc::sha256::hash( secret );
1758  auto nonce = fc::sha256::hash( one_time_key.get_secret() );
1759  auto blind_factor = fc::sha256::hash( child );
1760 
1761  blinding_factors.push_back( blind_factor );
1762 
1763  auto amount = asset_obj->amount_from_string(item.second);
1764  total_amount += amount;
1765 
1766 
1767  fc::ecc::public_key to_pub_key = to_key;
1768  blind_output out;
1769  out.owner = authority( 1, public_key_type( to_pub_key.child( child ) ), 1 );
1770  out.commitment = fc::ecc::blind( blind_factor, amount.amount.value );
1771  if( to_amounts.size() > 1 )
1772  out.range_proof = fc::ecc::range_proof_sign( 0, out.commitment, blind_factor, nonce,
1773  0, RANGE_PROOF_MANTISSA, amount.amount.value );
1774 
1775  blind_confirmation::output conf_output;
1776  conf_output.label = item.first;
1777  conf_output.pub_key = to_key;
1778  conf_output.decrypted_memo.amount = amount;
1779  conf_output.decrypted_memo.blinding_factor = blind_factor;
1780  conf_output.decrypted_memo.commitment = out.commitment;
1781  conf_output.decrypted_memo.check = secret._hash[0].value();
1782  conf_output.confirmation.one_time_key = one_time_key.get_public_key();
1783  conf_output.confirmation.to = to_key;
1784  conf_output.confirmation.encrypted_memo =
1785  fc::aes_encrypt( secret, fc::raw::pack( conf_output.decrypted_memo ) );
1786  conf_output.confirmation_receipt = conf_output.confirmation;
1787 
1788  confirm.outputs.push_back( conf_output );
1789 
1790  bop.outputs.push_back(out);
1791  }
1792  bop.amount = total_amount;
1793  bop.blinding_factor = fc::ecc::blind_sum( blinding_factors, blinding_factors.size() );
1794 
1796  std::sort( bop.outputs.begin(), bop.outputs.end(),
1797  [&]( const blind_output& a, const blind_output& b ){ return a.commitment < b.commitment; } );
1798 
1799  confirm.trx.operations.push_back( bop );
1800  my->set_operation_fees( confirm.trx, my->_remote_db->get_global_properties().parameters.get_current_fees());
1801  confirm.trx.validate();
1802  confirm.trx = sign_transaction(confirm.trx, broadcast);
1803 
1804  if( broadcast )
1805  {
1806  for( const auto& out : confirm.outputs )
1807  {
1808  try {
1809  receive_blind_transfer( out.confirmation_receipt, "@"+from_account.name, "from @"+from_account.name );
1810  } catch ( ... ){}
1811  }
1812  }
1813 
1814  return confirm;
1815 } FC_CAPTURE_AND_RETHROW( (from_account_id_or_name)(asset_symbol)(to_amounts) ) }
1816 
1817 blind_receipt wallet_api::receive_blind_transfer( string confirmation_receipt, string opt_from, string opt_memo )
1818 {
1819  FC_ASSERT( !is_locked() );
1820  stealth_confirmation conf(confirmation_receipt);
1821  FC_ASSERT( conf.to );
1822 
1823  blind_receipt result;
1824  result.conf = conf;
1825 
1826  auto to_priv_key_itr = my->_keys.find( *conf.to );
1827  FC_ASSERT( to_priv_key_itr != my->_keys.end(), "No private key for receiver", ("conf",conf) );
1828 
1829 
1830  auto to_priv_key = wif_to_key( to_priv_key_itr->second );
1831  FC_ASSERT( to_priv_key );
1832 
1833  auto secret = to_priv_key->get_shared_secret( conf.one_time_key );
1834  auto child = fc::sha256::hash( secret );
1835 
1836  auto child_priv_key = to_priv_key->child( child );
1837  //auto blind_factor = fc::sha256::hash( child );
1838 
1839  auto plain_memo = fc::aes_decrypt( secret, conf.encrypted_memo );
1840  auto memo = fc::raw::unpack<stealth_confirmation::memo_data>( plain_memo );
1841 
1842  result.to_key = *conf.to;
1843  result.to_label = get_key_label( result.to_key );
1844  if( memo.from )
1845  {
1846  result.from_key = *memo.from;
1847  result.from_label = get_key_label( result.from_key );
1848  if( result.from_label == string() )
1849  {
1850  result.from_label = opt_from;
1851  set_key_label( result.from_key, result.from_label );
1852  }
1853  }
1854  else
1855  {
1856  result.from_label = opt_from;
1857  }
1858  result.amount = memo.amount;
1859  result.memo = opt_memo;
1860 
1861  // confirm the amount matches the commitment (verify the blinding factor)
1862  auto commtiment_test = fc::ecc::blind( memo.blinding_factor, memo.amount.amount.value );
1863  FC_ASSERT( fc::ecc::verify_sum( {commtiment_test}, {memo.commitment}, 0 ) );
1864 
1865  blind_balance bal;
1866  bal.amount = memo.amount;
1867  bal.to = *conf.to;
1868  if( memo.from ) bal.from = *memo.from;
1869  bal.one_time_key = conf.one_time_key;
1870  bal.blinding_factor = memo.blinding_factor;
1871  bal.commitment = memo.commitment;
1872  bal.used = false;
1873 
1874  auto child_pubkey = child_priv_key.get_public_key();
1875  auto owner = authority(1, public_key_type(child_pubkey), 1);
1876  result.control_authority = owner;
1877  result.data = memo;
1878 
1879  auto child_key_itr = owner.key_auths.find( child_pubkey );
1880  if( child_key_itr != owner.key_auths.end() )
1881  my->_keys[child_key_itr->first] = key_to_wif( child_priv_key );
1882 
1883  // my->_wallet.blinded_balances[memo.amount.asset_id][bal.to].push_back( bal );
1884 
1885  result.date = fc::time_point::now();
1886  my->_wallet.blind_receipts.insert( result );
1887  my->_keys[child_pubkey] = key_to_wif( child_priv_key );
1888 
1889  save_wallet_file();
1890 
1891  return result;
1892 }
1893 
1894 vector<blind_receipt> wallet_api::blind_history( string key_or_account )
1895 {
1896  vector<blind_receipt> result;
1897  auto pub_key = get_public_key( key_or_account );
1898 
1899  if( pub_key == public_key_type() )
1900  return vector<blind_receipt>();
1901 
1902  for( auto& r : my->_wallet.blind_receipts )
1903  {
1904  if( r.from_key == pub_key || r.to_key == pub_key )
1905  result.push_back( r );
1906  }
1907  std::sort( result.begin(), result.end(),
1908  [&]( const blind_receipt& a, const blind_receipt& b ){ return a.date > b.date; } );
1909  return result;
1910 }
1911 
1912 order_book wallet_api::get_order_book( const string& base, const string& quote, unsigned limit )
1913 {
1914  return( my->_remote_db->get_order_book( base, quote, limit ) );
1915 }
1916 
1917 // custom operations
1918 signed_transaction wallet_api::account_store_map(string account, string catalog, bool remove,
1919  flat_map<string, optional<string>> key_values, bool broadcast)
1920 {
1921  return my->account_store_map(account, catalog, remove, key_values, broadcast);
1922 }
1923 
1924 vector<account_storage_object> wallet_api::get_account_storage(string account, string catalog)
1925 { try {
1926  return my->_custom_operations->get_storage_info(account, catalog);
1927 } FC_CAPTURE_AND_RETHROW( (account)(catalog) ) }
1928 
1930  : signed_block( block )
1931 {
1932  block_id = id();
1933  signing_key = signee();
1934  transaction_ids.reserve( transactions.size() );
1935  for( const processed_transaction& tx : transactions )
1936  transaction_ids.push_back( tx.id() );
1937 }
1938 
1940  const vesting_balance_object& vbo,
1941  fc::time_point_sec now )
1942  : vesting_balance_object( vbo )
1943 {
1945  allowed_withdraw_time = now;
1946 }
1947 
1948 } } // graphene::wallet
1949 
1950 namespace fc {
1951  void to_variant( const account_multi_index_type& accts, variant& vo, uint32_t max_depth )
1952  {
1953  to_variant( std::vector<account_object>(accts.begin(), accts.end()), vo, max_depth );
1954  }
1955 
1956  void from_variant( const variant& var, account_multi_index_type& vo, uint32_t max_depth )
1957  {
1958  const std::vector<account_object>& v = var.as<std::vector<account_object>>( max_depth );
1959  vo = account_multi_index_type(v.begin(), v.end());
1960  }
1961 }
fc::ecc::private_key derive_private_key(const std::string &prefix_string, int sequence_number) const
Definition: wallet.cpp:755
string str() const
Definition: hash160.cpp:46
asset_id_type get_asset_id(string asset_name_or_id) const
Definition: wallet.cpp:593
bool exists(const path &p)
Definition: filesystem.cpp:209
struct graphene::chain::htlc_object::transfer_info transfer
future_extensions::flat_set_type extensions_type
Definition: base.hpp:141
signed_transaction update_asset(string symbol, optional< string > new_issuer, asset_options new_options, bool broadcast=false)
Definition: wallet.cpp:802
signed_transaction account_store_map(string account, string catalog, bool remove, flat_map< string, optional< string >> key_values, bool broadcast)
Definition: wallet.cpp:1918
void dbg_stream_json_objects(const std::string &filename)
Definition: wallet.cpp:1056
std::string get_approximate_relative_time_string(const time_point_sec &event_time, const time_point_sec &relative_to_time=fc::time_point::now(), const std::string &ago=" ago")
Definition: time.cpp:70
std::shared_ptr< detail::wallet_api_impl > my
Definition: wallet.hpp:1751
signed_transaction approve_proposal(const string &fee_paying_account, const string &proposal_id, const approval_delta &delta, bool broadcast)
Definition: wallet.cpp:1102
fc::ecc::commitment_type commitment
transaction_handle_type begin_builder_transaction()
Definition: wallet.cpp:498
string address_to_shorthash(const graphene::protocol::address &addr)
Definition: wallet_sign.cpp:36
signed_transaction global_settle_asset(string symbol, price settle_price, bool broadcast=false)
Definition: wallet.cpp:862
vector< limit_order_object > get_account_limit_orders(const string &name_or_id, const string &base, const string &quote, uint32_t limit=101, optional< limit_order_id_type > ostart_id=optional< limit_order_id_type >(), optional< price > ostart_price=optional< price >())
Fetch all orders relevant to the specified account sorted descendingly by price.
Definition: wallet.cpp:433
multi_index_container< account_object, indexed_by< ordered_unique< tag< by_id >, member< object, object_id_type,&object::id > >, ordered_unique< tag< by_name >, member< account_object, string,&account_object::name > > > > account_multi_index_type
unsigned aes_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, unsigned char *iv, unsigned char *ciphertext)
Definition: aes.cpp:181
signed_transaction fund_asset_fee_pool(string from, string symbol, string amount, bool broadcast=false)
Definition: wallet.cpp:839
struct graphene::chain::htlc_object::condition_info::time_lock_info time_lock
vector< account_object > list_my_accounts()
Definition: wallet.cpp:178
const uint32_t word_list_size
Definition: words.cpp:49776
operation get_prototype_operation(string operation_type)
Definition: wallet.cpp:1029
signed_transaction create_asset(string issuer, string symbol, uint8_t precision, asset_options common, fc::optional< bitasset_options > bitasset_opts, bool broadcast=false)
Definition: wallet.cpp:791
T as(uint32_t max_depth) const
Definition: variant.hpp:336
variant_object about() const
Definition: wallet.cpp:750
private_key_secret get_secret() const
vector< collateral_bid_object > get_collateral_bids(string asset, uint32_t limit=100, uint32_t start=0) const
Definition: wallet.cpp:459
Identifies a weighted set of keys and accounts that must approve operations.
Definition: authority.hpp:34
stealth_confirmation::memo_data decrypted_memo
void pack(Stream &s, const flat_set< T, A... > &value, uint32_t _max_depth)
Definition: flat.hpp:11
void flood_network(string prefix, uint32_t number_of_transactions)
Definition: wallet.cpp:1076
std::string uint128_amount_to_string(const fc::uint128_t &amount, const uint8_t precision)
Definition: util.cpp:42
static constexpr size_t data_size()
Definition: sha256.hpp:21
database object to store HTLCs
Definition: htlc_object.hpp:40
signed_transaction sign_transaction2(signed_transaction tx, const vector< public_key_type > &signing_keys=vector< public_key_type >(), bool broadcast=true)
Definition: wallet.cpp:1013
bool verify_encapsulated_message(string message)
Definition: wallet.cpp:1368
contains properties that only apply to bitassets (market issued assets)
transaction preview_builder_transaction(transaction_handle_type handle)
Definition: wallet.cpp:523
optional< signed_block_with_info > get_block(uint32_t num)
Definition: wallet.cpp:168
string trim_and_normalize_spaces(const string &s)
Definition: string.cpp:104
string get_private_key(public_key_type pubkey) const
Definition: wallet.cpp:1382
void set_password(string password)
Definition: wallet.cpp:1267
public_key_type to
the account this balance is logically associated with
vector< operation > operations
Definition: transaction.hpp:89
struct graphene::chain::htlc_object::condition_info conditions
bool verify_sum(const std::vector< commitment_type > &commits, const std::vector< commitment_type > &neg_commits, int64_t excess)
signed_transaction vote_for_witness(string voting_account, string witness, bool approve, bool broadcast=false)
Definition: wallet.cpp:979
void dbg_generate_blocks(std::string debug_wif_key, uint32_t count)
Definition: wallet.cpp:1051
string get_key_label(public_key_type key) const
Definition: wallet.cpp:1374
blind_confirmation blind_transfer_help(string from_key_or_label, string to_key_or_label, string amount, string symbol, bool broadcast=false, bool to_temp=false)
Definition: wallet.cpp:1552
vector< asset > get_blind_balances(string key_or_label)
Definition: wallet.cpp:1450
virtual void validate() const
Definition: transaction.cpp:58
vector< transaction_id_type > transaction_ids
This class represents an account on the object graphAccounts are the primary unit of authority on the...
Maintains global state information (committee_member list, current fees)This is an implementation det...
An order-perserving dictionary of variant&#39;s.
Definition: api.cpp:56
#define elog(FORMAT,...)
Definition: logger.hpp:129
global_property_object get_global_properties() const
Definition: wallet.cpp:1112
fc::optional< fc::ecc::private_key > wif_to_key(const std::string &wif_key)
full_account get_full_account(const string &name_or_id)
Fetch all objects relevant to the specified account.
Definition: wallet.cpp:418
signed_transaction htlc_extend(string htlc_id, string issuer, const uint32_t seconds_to_add, bool broadcast=false)
Definition: wallet.cpp:274
asset set_fees_on_builder_transaction(transaction_handle_type handle, string fee_asset=GRAPHENE_SYMBOL)
Definition: wallet.cpp:518
The asset_options struct contains options available on all assets in the network. ...
Definition: asset_ops.hpp:47
public_key_type get_public_key(string label) const
Definition: wallet.cpp:1387
asset get_allowed_withdraw(const time_point_sec &now) const
vector< account_storage_object > get_account_storage(string account, string catalog)
Definition: wallet.cpp:1924
extended_asset_object get_asset(string asset_name_or_id) const
Definition: wallet.cpp:574
void dbg_make_mia(string creator, string symbol)
Definition: wallet.cpp:1040
std::map< string, std::function< string(fc::variant, const fc::variants &)> > get_result_formatters() const
Definition: wallet.cpp:1225
Used to generate a useful error report when an exception is thrown.At each level in the stack where t...
Definition: exception.hpp:56
signed_transaction propose_builder_transaction(transaction_handle_type handle, time_point_sec expiration=time_point::now()+fc::minutes(1), uint32_t review_period_seconds=0, bool broadcast=true)
Definition: wallet.cpp:545
std::string to_detail_string(log_level ll=log_level::all) const
Definition: exception.cpp:183
string get_wallet_filename() const
Definition: wallet.cpp:493
signed_transaction cancel_order(object_id_type order_id, bool broadcast=false)
Definition: wallet.cpp:1324
void network_add_nodes(const vector< string > &nodes)
Definition: wallet.cpp:1066
bool valid() const
Definition: optional.hpp:186
signed_transaction reserve_asset(string from, string amount, string symbol, bool broadcast=false)
Definition: wallet.cpp:854
signed_transaction set_desired_witness_and_committee_member_count(string account_to_modify, uint16_t desired_number_of_witnesses, uint16_t desired_number_of_committee_members, bool broadcast=false)
Definition: wallet.cpp:994
vector< limit_order_object > get_limit_orders(string a, string b, uint32_t limit) const
Get limit orders in a given market.
Definition: wallet.cpp:444
signed_transaction settle_asset(string account_to_settle, string amount_to_settle, string symbol, bool broadcast=false)
Definition: wallet.cpp:869
vector< brain_key_info > derive_owner_keys_from_brain_key(string brain_key, int number_of_desired_keys=1) const
Definition: wallet.cpp:469
signed_transaction create_witness(string owner_account, string url, bool broadcast=false)
Definition: wallet.cpp:919
static sha512 hash(const char *d, uint32_t dlen)
Definition: sha512.cpp:34
#define FC_THROW(...)
Definition: exception.hpp:366
groups operations that should be applied atomically
Definition: transaction.hpp:68
memo_data sign_memo(string from, string to, string memo)
Definition: wallet.cpp:1330
vector< signed_transaction > import_balance(string account_name_or_id, const vector< string > &wif_keys, bool broadcast)
Definition: wallet.cpp:1275
fc::static_variant< transfer_operation, limit_order_create_operation, limit_order_cancel_operation, call_order_update_operation, fill_order_operation, account_create_operation, account_update_operation, account_whitelist_operation, account_upgrade_operation, account_transfer_operation, asset_create_operation, asset_update_operation, asset_update_bitasset_operation, asset_update_feed_producers_operation, asset_issue_operation, asset_reserve_operation, asset_fund_fee_pool_operation, asset_settle_operation, asset_global_settle_operation, asset_publish_feed_operation, witness_create_operation, witness_update_operation, proposal_create_operation, proposal_update_operation, proposal_delete_operation, withdraw_permission_create_operation, withdraw_permission_update_operation, withdraw_permission_claim_operation, withdraw_permission_delete_operation, committee_member_create_operation, committee_member_update_operation, committee_member_update_global_parameters_operation, vesting_balance_create_operation, vesting_balance_withdraw_operation, worker_create_operation, custom_operation, assert_operation, balance_claim_operation, override_transfer_operation, transfer_to_blind_operation, blind_transfer_operation, transfer_from_blind_operation, asset_settle_cancel_operation, asset_claim_fees_operation, fba_distribute_operation, bid_collateral_operation, execute_bid_operation, asset_claim_pool_operation, asset_update_issuer_operation, htlc_create_operation, htlc_redeem_operation, htlc_redeemed_operation, htlc_extend_operation, htlc_refund_operation, custom_authority_create_operation, custom_authority_update_operation, custom_authority_delete_operation, ticket_create_operation, ticket_update_operation, liquidity_pool_create_operation, liquidity_pool_delete_operation, liquidity_pool_deposit_operation, liquidity_pool_withdraw_operation, liquidity_pool_exchange_operation > operation
Definition: operations.hpp:118
vector< extended_asset_object > list_assets(const string &lowerbound, uint32_t limit) const
Definition: wallet.cpp:193
bool import_account_keys(string filename, string password, string src_account_name, string dest_account_name)
Definition: wallet.cpp:689
asset amount_from_string(string amount_string) const
signed_transaction sign_builder_transaction(transaction_handle_type transaction_handle, bool broadcast=true)
Definition: wallet.cpp:528
visitor::result_type visit(visitor &v)
map< string, committee_member_id_type > list_committee_members(const string &lowerbound, uint32_t limit)
Definition: wallet.cpp:904
const auto source
vector< operation_detail > get_relative_account_history(string name, uint32_t stop, int limit, uint32_t start) const
Definition: wallet.cpp:336
signed_transaction borrow_asset_ext(string borrower_name, string amount_to_borrow, string asset_symbol, string amount_of_collateral, call_order_update_operation::extensions_type extensions, bool broadcast=false)
Definition: wallet.cpp:1314
signed_transaction update_asset_issuer(string symbol, string new_issuer, bool broadcast=false)
Definition: wallet.cpp:810
bool copy_wallet_file(string destination_filename)
Definition: wallet.cpp:163
public_key get_public_key() const
blind_confirmation blind_transfer(string from_key_or_label, string to_key_or_label, string amount, string symbol, bool broadcast=false)
Definition: wallet.cpp:1544
vector< force_settlement_object > get_settle_orders(string a, uint32_t limit) const
Get forced settlement orders in a given asset.
Definition: wallet.cpp:454
signed_transaction sign_builder_transaction2(transaction_handle_type transaction_handle, const vector< public_key_type > &signing_keys=vector< public_key_type >(), bool broadcast=true)
Definition: wallet.cpp:533
static sha256 hash(const char *d, uint32_t dlen)
Definition: sha256.cpp:41
bool verify_signed_message(signed_message message)
Definition: wallet.cpp:1358
wallet_api(const wallet_data &initial_data, fc::api< login_api > rapi)
Definition: wallet.cpp:154
const const_char_ptr word_list[]
Definition: words.cpp:29
void add_operation_to_builder_transaction(transaction_handle_type transaction_handle, const operation &op)
Definition: wallet.cpp:503
std::string key_to_wif(const fc::sha256 &private_secret)
#define BRAIN_KEY_WORD_COUNT
Definition: wallet.cpp:81
string amount_to_string(share_type amount) const
Convert an asset to a textual representation, i.e. "123.45".
signed_transaction htlc_create(string source, string destination, string amount, string asset_symbol, string hash_algorithm, const std::string &preimage_hash, uint32_t preimage_size, const uint32_t claim_period_seconds, const std::string &memo, bool broadcast=false)
Definition: wallet.cpp:203
bool import_key(string account_name_or_id, string wif_key)
Definition: wallet.cpp:598
commitment_type blind(const blind_factor_type &blind, uint64_t value)
void unlock(string password)
Definition: wallet.cpp:1255
signed_transaction whitelist_account(string authorizing_account, string account_to_list, account_whitelist_operation::account_listing new_listing_status, bool broadcast=false)
Definition: wallet.cpp:885
account_id_type get_account_id(string account_name_or_id) const
Definition: wallet.cpp:588
fc::ecc::commitment_type commitment
map< string, public_key_type > get_my_blind_accounts() const
Definition: wallet.cpp:1418
bool verify_message(string message, string account, int block, const string &time, compact_signature sig)
Definition: wallet.cpp:1348
signed_transaction propose_builder_transaction2(transaction_handle_type handle, string account_name_or_id, time_point_sec expiration=time_point::now()+fc::minutes(1), uint32_t review_period_seconds=0, bool broadcast=true)
Definition: wallet.cpp:554
void save_wallet_file(string wallet_filename="")
Definition: wallet.cpp:1219
signed_transaction issue_asset(string to_account, string amount, string symbol, string memo, bool broadcast=false)
Definition: wallet.cpp:780
fc::ecc::private_key derive_private_key(const std::string &prefix_string, int sequence_number)
Definition: wallet_sign.cpp:54
fc::optional< memo_data > memo
Definition: htlc_object.hpp:62
bool load_wallet_file(string wallet_filename="")
Definition: wallet.cpp:1209
#define wdump(SEQ)
Definition: logger.hpp:174
int64_t to_int64() const
Definition: bigint.cpp:54
object_id_type id
Definition: object.hpp:69
asset_bitasset_data_object get_bitasset_data(string asset_name_or_id) const
Definition: wallet.cpp:581
char * data() const
Definition: sha256.cpp:29
static private_key generate()
blind_receipt receive_blind_transfer(string confirmation_receipt, string opt_from, string opt_memo)
Definition: wallet.cpp:1817
Defines data required to create a new blind commitmentThe blinded output that must be proven to be gr...
signed_transaction register_account(string name, public_key_type owner, public_key_type active, string registrar_account, string referrer_account, uint32_t referrer_percent, bool broadcast=false)
Definition: wallet.cpp:760
std::string str()
Definition: sstream.cpp:33
fc::ecc::commitment_type commitment
account_id_type get_id() const
contains only the public point of an elliptic curve key.
Definition: elliptic.hpp:35
Converts blinded/stealth balance to a public account balance.
string str() const
Definition: ripemd160.cpp:21
signed_transaction bid_collateral(string bidder_name, string debt_amount, string debt_symbol, string additional_collateral, bool broadcast=false)
Definition: wallet.cpp:877
bool set_key_label(public_key_type key, string label)
Definition: wallet.cpp:1397
brain_key_info suggest_brain_key() const
Definition: wallet.cpp:464
order_book get_order_book(const string &base, const string &quote, unsigned limit=50)
Definition: wallet.cpp:1912
asset amount(share_type a) const
Helper function to get an asset object with the given amount in this asset&#39;s type.
#define ilog(FORMAT,...)
Definition: logger.hpp:117
uint64_t get_account_count() const
Definition: wallet.cpp:173
stealth_confirmation::memo_data data
dynamic_global_property_object get_dynamic_global_properties() const
Definition: wallet.cpp:1117
#define idump(SEQ)
Definition: logger.hpp:166
signed_transaction update_bitasset(string symbol, bitasset_options new_options, bool broadcast=false)
Definition: wallet.cpp:817
vector< asset > list_account_balances(const string &id)
Definition: wallet.cpp:188
signed_transaction transfer(string from, string to, string amount, string asset_symbol, string memo, bool broadcast=false)
Definition: wallet.cpp:786
#define FC_CAPTURE_AND_RETHROW(...)
Definition: exception.hpp:478
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
string name
The account&#39;s name. This name must be unique among all account names on the graph. May not be empty.
void set_wallet_filename(string wallet_filename)
Definition: wallet.cpp:1003
vector< flat_set< account_id_type > > get_key_references(const vector< public_key_type > &keys) const
Definition: wallet.cpp:1024
void replace_operation_in_builder_transaction(transaction_handle_type handle, unsigned operation_index, const operation &new_op)
Definition: wallet.cpp:510
signed_block_with_info(const signed_block &block)
Definition: wallet.cpp:1929
string normalize_brain_key(string s) const
Definition: wallet.cpp:740
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object&#39;s.
Definition: variant.hpp:198
static string to_pretty_string(const variant &v, output_formatting format=stringify_large_ints_and_doubles, uint32_t max_depth=DEFAULT_MAX_RECURSION_DEPTH)
Definition: json.cpp:736
static private_key regenerate(const fc::sha256 &secret)
string normalize_brain_key(string s)
Definition: wallet_sign.cpp:62
void remove_builder_transaction(transaction_handle_type handle)
Definition: wallet.cpp:564
signed_transaction borrow_asset(string borrower_name, string amount_to_borrow, string asset_symbol, string amount_of_collateral, bool broadcast=false)
Definition: wallet.cpp:1307
string str() const
Definition: sha256.cpp:24
signed_transaction create_account_with_brain_key(string brain_key, string account_name, string registrar_account, string referrer_account, bool broadcast=false)
Definition: wallet.cpp:771
vector< public_key_type > get_keys() const
Definition: authority.hpp:85
signed_transaction update_asset_feed_producers(string symbol, flat_set< string > new_feed_producers, bool broadcast=false)
Definition: wallet.cpp:824
public_key_type from
the account this balance came from
signed_transaction upgrade_account(string name, bool broadcast)
Definition: wallet.cpp:1289
signed_transaction update_worker_votes(string account, worker_vote_delta delta, bool broadcast=false)
Definition: wallet.cpp:940
void dbg_update_object(fc::variant_object update)
Definition: wallet.cpp:1061
void dbg_make_uia(string creator, string symbol)
Definition: wallet.cpp:1034
witness_object get_witness(string owner_account)
Definition: wallet.cpp:909
string serialize_transaction(signed_transaction tx) const
Definition: wallet.cpp:483
map< string, public_key_type > get_blind_accounts() const
Definition: wallet.cpp:1411
object_restriction_predicate< operation > result_type
Definition: list_1.cpp:29
public_key_type one_time_key
used to derive the authority key and blinding factor
vesting_balance_object_with_info(const vesting_balance_object &vbo, fc::time_point_sec now)
Definition: wallet.cpp:1939
signed_transaction update_witness(string witness_name, string url, string block_signing_key, bool broadcast=false)
Definition: wallet.cpp:948
range_proof_type range_proof_sign(uint64_t min_value, const commitment_type &commit, const blind_factor_type &commit_blind, const blind_factor_type &nonce, int8_t base10_exp, uint8_t min_bits, uint64_t actual_value)
blind_factor_type blind_sum(const std::vector< blind_factor_type > &blinds, uint32_t non_neg)
void from_variant(const variant &var, flat_set< T, A... > &vo, uint32_t _max_depth)
Definition: flat.hpp:116
variant get_object(object_id_type id) const
Definition: wallet.cpp:488
signed_transaction create_worker(string owner_account, time_point_sec work_begin_date, time_point_sec work_end_date, share_type daily_pay, string name, string url, variant worker_settings, bool broadcast=false)
Definition: wallet.cpp:926
safe< int64_t > share_type
Definition: types.hpp:247
signed_transaction claim_asset_fee_pool(string symbol, string amount, bool broadcast=false)
Definition: wallet.cpp:847
uint16_t transaction_handle_type
map< string, account_id_type > list_accounts(const string &lowerbound, uint32_t limit)
Definition: wallet.cpp:183
signed_transaction set_voting_proxy(string account_to_modify, optional< string > voting_account, bool broadcast=false)
Definition: wallet.cpp:987
signed_transaction propose_fee_change(const string &proposing_account, fc::time_point_sec expiration_time, const variant_object &changed_values, bool broadcast=false)
Definition: wallet.cpp:1092
bool is_public_key_registered(string public_key) const
Definition: wallet.cpp:476
vector< operation_detail > get_account_history(string name, int limit) const
Definition: wallet.cpp:280
flat_set< public_key_type > get_transaction_signers(const signed_transaction &tx) const
Definition: wallet.cpp:1019
Definition: api.hpp:15
unsigned aes_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv, unsigned char *plaintext)
Definition: aes.cpp:230
signed_transaction withdraw_vesting(string witness_name, string amount, string asset_symbol, bool broadcast=false)
Definition: wallet.cpp:962
map< public_key_type, string > dump_private_keys()
Definition: wallet.cpp:1283
signed_message sign_message(string signer, string message)
Definition: wallet.cpp:1342
account_statistics_id_type statistics
signed_transaction publish_asset_feed(string publishing_account, string symbol, price_feed feed, bool broadcast=false)
Definition: wallet.cpp:831
vector< bucket_object > get_market_history(string symbol, string symbol2, uint32_t bucket, fc::time_point_sec start, fc::time_point_sec end) const
Get OHLCV data of a trading pair in a time range.
Definition: wallet.cpp:423
Maintains global state information (committee_member list, current fees)This is an implementation det...
fc::optional< fc::variant > get_htlc(string htlc_id) const
Definition: wallet.cpp:211
vector< vesting_balance_object_with_info > get_vesting_balances(string account_name)
Definition: wallet.cpp:957
map< string, witness_id_type > list_witnesses(const string &lowerbound, uint32_t limit)
Definition: wallet.cpp:899
account_history_operation_detail get_account_history_by_operations(string name, flat_set< uint16_t > operation_types, uint32_t start, int limit)
Definition: wallet.cpp:374
blind_confirmation transfer_from_blind(string from_blind_account_key_or_label, string to_account_id_or_name, string amount, string asset_symbol, bool broadcast=false)
Definition: wallet.cpp:1483
blind_confirmation transfer_to_blind(string from_account_id_or_name, string asset_symbol, vector< pair< string, string >> to_amounts, bool broadcast=false)
Definition: wallet.cpp:1730
static brain_key_info suggest_brain_key()
Definition: wallet.cpp:121
public_key_type create_blind_account(string label, string brain_key)
Definition: wallet.cpp:1430
pair< transaction_id_type, signed_transaction > broadcast_transaction(signed_transaction tx)
Definition: wallet.cpp:540
static vector< brain_key_info > derive_owner_keys_from_brain_key(string brain_key, int number_of_desired_keys=1)
Definition: wallet.cpp:99
fc::sha256 digest() const
Definition: wallet.cpp:88
vector< blind_receipt > blind_history(string key_or_account)
Definition: wallet.cpp:1894
struct graphene::chain::htlc_object::condition_info::hash_lock_info hash_lock
vector< call_order_object > get_call_orders(string a, uint32_t limit) const
Get call orders (aka margin positions) for a given asset.
Definition: wallet.cpp:449
signed_transaction propose_parameter_change(const string &proposing_account, fc::time_point_sec expiration_time, const variant_object &changed_values, bool broadcast=false)
Definition: wallet.cpp:1082
static time_point now()
Definition: time.cpp:13
signed_transaction create_committee_member(string owner_account, string url, bool broadcast=false)
Definition: wallet.cpp:893
signed_transaction add_transaction_signature(signed_transaction tx, bool broadcast=false)
Definition: wallet.cpp:1122
signed_transaction htlc_redeem(string htlc_id, string issuer, const std::string &preimage, bool broadcast=false)
Definition: wallet.cpp:267
public_key child(const fc::sha256 &offset) const
string read_memo(const memo_data &memo)
Definition: wallet.cpp:1336
an elliptic curve private key.
Definition: elliptic.hpp:89
string gethelp(const string &method) const
Definition: wallet.cpp:1146
zero_initialized_array< unsigned char, 65 > compact_signature
Definition: elliptic.hpp:27
signed_transaction vote_for_committee_member(string voting_account, string committee_member, bool approve, bool broadcast=false)
Definition: wallet.cpp:971
std::string to_hex(const char *d, uint32_t s)
Definition: hex.cpp:17
tracks information about a committee_member account.A committee_member is responsible for setting blo...
#define RANGE_PROOF_MANTISSA
Definition: wallet.cpp:82
Transfers from blind to blind.
captures the result of evaluating the operations contained in the transaction
map< string, bool > import_accounts(string filename, string password)
Definition: wallet.cpp:617
void dbg_push_blocks(std::string src_filename, uint32_t count)
Definition: wallet.cpp:1046
An order-perserving dictionary of variant&#39;s.
signed_transaction sell_asset(string seller_account, string amount_to_sell, string symbol_to_sell, string min_to_receive, string symbol_to_receive, uint32_t timeout_sec=0, bool fill_or_kill=false, bool broadcast=false)
Definition: wallet.cpp:1294
The bitasset_options struct contains configurable options available only to BitAssets.
Definition: asset_ops.hpp:109
Converts public account balance to a blinded or stealth balance.
vector< variant > network_get_connected_peers()
Definition: wallet.cpp:1071
signed_transaction sign_transaction(signed_transaction tx, bool broadcast=false)
Definition: wallet.cpp:1008
T value
Definition: safe.hpp:22
uint64_t get_asset_count() const
Definition: wallet.cpp:198
std::string str() const
Definition: sha1.cpp:18
Definition: api.hpp:120
account_object get_account(string account_name_or_id) const
Definition: wallet.cpp:569
committee_member_object get_committee_member(string owner_account)
Definition: wallet.cpp:914