BitShares-Core  5.0.0
BitShares blockchain implementation and command-line interface software
wallet_api_impl.hpp
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 #pragma once
25 
26 #include <fc/thread/mutex.hpp>
27 
28 #include <graphene/app/api.hpp>
29 
33 
34 namespace graphene { namespace wallet {
35 
36 class wallet_api;
37 
38 namespace detail {
39 
40 using namespace graphene::protocol;
41 using namespace graphene::chain;
42 using namespace graphene::app;
43 
44 static const string ENC_HEADER( "-----BEGIN BITSHARES SIGNED MESSAGE-----\n" );
45 static const string ENC_META( "-----BEGIN META-----\n" );
46 static const string ENC_SIG( "-----BEGIN SIGNATURE-----\n" );
47 static const string ENC_FOOTER( "-----END BITSHARES SIGNED MESSAGE-----" );
48 
49 template<class T>
50 fc::optional<T> maybe_id( const string& name_or_id )
51 {
52  if( std::isdigit( name_or_id.front() ) )
53  {
54  try
55  {
56  return fc::variant(name_or_id, 1).as<T>(1);
57  }
58  catch (const fc::exception&)
59  { // not an ID
60  }
61  }
62  return fc::optional<T>();
63 }
64 
66 
67 fc::ecc::private_key derive_private_key( const std::string& prefix_string, int sequence_number );
68 
69 string normalize_brain_key( string s );
70 
72 {
73  typedef void result_type;
74 
75  int t = 0;
76  flat_map< std::string, graphene::protocol::operation >& name2op;
77 
79  int _t,
80  flat_map< std::string, graphene::protocol::operation >& _prototype_ops
81  ):t(_t), name2op(_prototype_ops) {}
82 
83  template<typename Type>
84  result_type operator()( const Type& op )const
85  {
86  string name = fc::get_typename<Type>::name();
87  size_t p = name.rfind(':');
88  if( p != string::npos )
89  name = name.substr( p+1 );
90  name2op[ name ] = Type();
91  }
92 };
93 
95 {
96 public:
98  wallet_api& self;
99 
100  wallet_api_impl( wallet_api& s, const wallet_data& initial_data, fc::api<login_api> rapi );
101 
102  virtual ~wallet_api_impl();
103 
104  /***
105  * @brief encrypt the keys
106  * This is normally done before saving the wallet file
107  */
108  void encrypt_keys();
109 
110  /***
111  * @brief called when a block is applied
112  */
113  void on_block_applied( const variant& block_id );
114 
121  bool copy_wallet_file( string destination_filename );
122 
123  /***
124  * @brief returns true if the wallet is unlocked
125  */
126  bool is_locked()const;
127 
128  template<typename ID>
130  {
131  auto ob = _remote_db->get_objects({id}, {}).front();
132  return ob.template as<graphene::db::object_downcast_t<ID>>( GRAPHENE_MAX_NESTED_OBJECTS );
133  }
134 
135  /***
136  * @brief set fees for each operation in a transaction
137  * @param tx the transaction
138  * @param s the fee schedule
139  */
140  void set_operation_fees( signed_transaction& tx, const fee_schedule& s );
141 
142  /***
143  * @brief return basic info about the chain
144  */
145  variant info() const;
146 
147  /***
148  * @brief return basic information about this program
149  */
150  variant_object about() const;
151 
152  chain_property_object get_chain_properties() const;
153  global_property_object get_global_properties() const;
154  dynamic_global_property_object get_dynamic_global_properties() const;
155 
156  account_object get_account(account_id_type id) const;
157  account_object get_account(string account_name_or_id) const;
158  account_id_type get_account_id(string account_name_or_id) const;
159 
160  std::string asset_id_to_string(asset_id_type id) const;
161 
162  optional<extended_asset_object> find_asset(asset_id_type id)const;
163 
164  optional<extended_asset_object> find_asset(string asset_symbol_or_id)const;
165 
166  extended_asset_object get_asset(asset_id_type id)const;
167 
168  extended_asset_object get_asset(string asset_symbol_or_id)const;
169 
170  fc::optional<htlc_object> get_htlc(string htlc_id) const;
171 
172  asset_id_type get_asset_id(string asset_symbol_or_id) const;
173 
174  string get_wallet_filename() const;
175 
176  fc::ecc::private_key get_private_key(const public_key_type& id)const;
177 
178  fc::ecc::private_key get_private_key_for_account(const account_object& account)const;
179 
180  // imports the private key into the wallet, and associate it in some way (?) with the
181  // given account name.
182  // @returns true if the key matches a current active/owner/memo key for the named
183  // account, false otherwise (but it is stored either way)
184  bool import_key(string account_name_or_id, string wif_key);
185 
186  vector< signed_transaction > import_balance( string name_or_id, const vector<string>& wif_keys, bool broadcast );
187 
188  bool load_wallet_file(string wallet_filename = "");
189 
205  set<public_key_type> get_owned_required_keys( signed_transaction &tx,
206  bool erase_existing_sigs = true);
207 
208  signed_transaction add_transaction_signature( signed_transaction tx,
209  bool broadcast );
210 
211  void quit();
212 
213  void save_wallet_file(string wallet_filename = "");
214 
215  transaction_handle_type begin_builder_transaction();
216  void add_operation_to_builder_transaction(transaction_handle_type transaction_handle, const operation& op);
217  void replace_operation_in_builder_transaction(transaction_handle_type handle,
218  uint32_t operation_index, const operation& new_op);
219  asset set_fees_on_builder_transaction(transaction_handle_type handle, string fee_asset = GRAPHENE_SYMBOL);
220  transaction preview_builder_transaction(transaction_handle_type handle);
221  signed_transaction sign_builder_transaction(transaction_handle_type transaction_handle, bool broadcast = true);
222  signed_transaction sign_builder_transaction2(transaction_handle_type transaction_handle,
223  const vector<public_key_type>& signing_keys = vector<public_key_type>(), bool broadcast = true);
224 
225  pair<transaction_id_type,signed_transaction> broadcast_transaction(signed_transaction tx);
226 
227  signed_transaction propose_builder_transaction( transaction_handle_type handle,
228  time_point_sec expiration = time_point::now() + fc::minutes(1),
229  uint32_t review_period_seconds = 0, bool broadcast = true);
230 
231  signed_transaction propose_builder_transaction2( transaction_handle_type handle,
232  string account_name_or_id, time_point_sec expiration = time_point::now() + fc::minutes(1),
233  uint32_t review_period_seconds = 0, bool broadcast = true);
234 
235  void remove_builder_transaction(transaction_handle_type handle);
236 
237  signed_transaction register_account(string name, public_key_type owner, public_key_type active,
238  string registrar_account, string referrer_account, uint32_t referrer_percent,
239  bool broadcast = false);
240 
241  signed_transaction upgrade_account(string name, bool broadcast);
242 
243  signed_transaction create_account_with_private_key(fc::ecc::private_key owner_privkey,
244  string account_name, string registrar_account, string referrer_account,
245  bool broadcast = false, bool save_wallet = true);
246 
247  signed_transaction create_account_with_brain_key(string brain_key, string account_name, string registrar_account,
248  string referrer_account, bool broadcast = false, bool save_wallet = true);
249 
250  signed_transaction create_asset(string issuer, string symbol, uint8_t precision, asset_options common,
251  fc::optional<bitasset_options> bitasset_opts, bool broadcast = false);
252 
253  signed_transaction update_asset(string symbol, optional<string> new_issuer, asset_options new_options,
254  bool broadcast );
255 
256  signed_transaction update_asset_issuer(string symbol, string new_issuer, bool broadcast );
257 
258  signed_transaction update_bitasset(string symbol, bitasset_options new_options, bool broadcast );
259 
260  signed_transaction update_asset_feed_producers(string symbol, flat_set<string> new_feed_producers,
261  bool broadcast );
262 
263  signed_transaction publish_asset_feed(string publishing_account, string symbol, price_feed feed,
264  bool broadcast );
265 
266  signed_transaction fund_asset_fee_pool(string from, string symbol, string amount, bool broadcast );
267 
268  signed_transaction claim_asset_fee_pool(string symbol, string amount, bool broadcast );
269 
270  signed_transaction reserve_asset(string from, string amount, string symbol, bool broadcast );
271 
272  signed_transaction global_settle_asset(string symbol, price settle_price, bool broadcast );
273 
274  signed_transaction settle_asset(string account_to_settle, string amount_to_settle, string symbol,
275  bool broadcast );
276 
277  signed_transaction bid_collateral(string bidder_name, string debt_amount, string debt_symbol,
278  string additional_collateral, bool broadcast );
279 
280  signed_transaction whitelist_account(string authorizing_account, string account_to_list,
281  account_whitelist_operation::account_listing new_listing_status, bool broadcast );
282 
283  signed_transaction create_committee_member(string owner_account, string url, bool broadcast );
284 
285  witness_object get_witness( string owner_account );
286 
287  committee_member_object get_committee_member( string owner_account );
288 
289  signed_transaction create_witness(string owner_account, string url, bool broadcast );
290 
291  signed_transaction update_witness(string witness_name, string url, string block_signing_key,
292  bool broadcast );
293 
294  signed_transaction create_worker( string owner_account, time_point_sec work_begin_date,
295  time_point_sec work_end_date, share_type daily_pay, string name, string url,
296  variant worker_settings, bool broadcast );
297 
298  signed_transaction update_worker_votes( string account, worker_vote_delta delta, bool broadcast );
299 
300  signed_transaction htlc_create( string source, string destination, string amount, string asset_symbol,
301  string hash_algorithm, const std::string& preimage_hash, uint32_t preimage_size,
302  const uint32_t claim_period_seconds, const std::string& memo, bool broadcast = false );
303 
304  signed_transaction htlc_redeem( string htlc_id, string issuer, const std::vector<char>& preimage,
305  bool broadcast );
306 
307  signed_transaction htlc_extend ( string htlc_id, string issuer, const uint32_t seconds_to_add, bool broadcast);
308 
309  signed_transaction account_store_map(string account, string catalog, bool remove,
310  flat_map<string, optional<string>> key_values, bool broadcast);
311 
312  vector< vesting_balance_object_with_info > get_vesting_balances( string account_name );
313 
314  signed_transaction withdraw_vesting( string witness_name, string amount, string asset_symbol,
315  bool broadcast = false );
316 
317  signed_transaction vote_for_committee_member(string voting_account, string committee_member,
318  bool approve, bool broadcast );
319 
320  signed_transaction vote_for_witness(string voting_account, string witness, bool approve,
321  bool broadcast );
322 
323  signed_transaction set_voting_proxy(string account_to_modify, optional<string> voting_account,
324  bool broadcast );
325 
326  signed_transaction set_desired_witness_and_committee_member_count(string account_to_modify,
327  uint16_t desired_number_of_witnesses, uint16_t desired_number_of_committee_members,
328  bool broadcast );
329 
330  signed_transaction sign_transaction(signed_transaction tx, bool broadcast = false);
331  signed_transaction sign_transaction2(signed_transaction tx,
332  const vector<public_key_type>& signing_keys = vector<public_key_type>(),
333  bool broadcast = false);
334 
335  flat_set<public_key_type> get_transaction_signers(const signed_transaction &tx) const;
336 
337  vector<flat_set<account_id_type>> get_key_references(const vector<public_key_type> &keys) const;
338 
339  memo_data sign_memo(string from, string to, string memo);
340 
341  string read_memo(const memo_data& md);
342 
343  signed_message sign_message(string signer, string message);
344 
345  bool verify_message( const string& message, const string& account, int block, const string& time,
346  const compact_signature& sig );
347 
348  bool verify_signed_message( const signed_message& message );
349 
350  bool verify_encapsulated_message( const string& message );
351 
352  signed_transaction sell_asset(string seller_account, string amount_to_sell, string symbol_to_sell,
353  string min_to_receive, string symbol_to_receive, uint32_t timeout_sec = 0,
354  bool fill_or_kill = false, bool broadcast = false);
355 
356  signed_transaction borrow_asset(string seller_name, string amount_to_borrow, string asset_symbol,
357  string amount_of_collateral, bool broadcast = false);
358 
359  signed_transaction borrow_asset_ext( string seller_name, string amount_to_borrow, string asset_symbol,
360  string amount_of_collateral, call_order_update_operation::extensions_type extensions,
361  bool broadcast = false);
362 
363  signed_transaction cancel_order(limit_order_id_type order_id, bool broadcast = false);
364 
365  signed_transaction transfer(string from, string to, string amount,
366  string asset_symbol, string memo, bool broadcast = false);
367 
368  signed_transaction issue_asset(string to_account, string amount, string symbol,
369  string memo, bool broadcast = false);
370 
371  std::map<string,std::function<string(fc::variant,const fc::variants&)>> get_result_formatters() const;
372 
373  signed_transaction propose_parameter_change( const string& proposing_account, fc::time_point_sec expiration_time,
374  const variant_object& changed_values, bool broadcast = false);
375 
376  signed_transaction propose_fee_change( const string& proposing_account, fc::time_point_sec expiration_time,
377  const variant_object& changed_fees, bool broadcast = false);
378 
379  signed_transaction approve_proposal( const string& fee_paying_account, const string& proposal_id,
380  const approval_delta& delta, bool broadcast = false);
381 
382  void dbg_make_uia(string creator, string symbol);
383 
384  void dbg_make_mia(string creator, string symbol);
385 
386  void dbg_push_blocks( const std::string& src_filename, uint32_t count );
387 
388  void dbg_generate_blocks( const std::string& debug_wif_key, uint32_t count );
389 
390  void dbg_stream_json_objects( const std::string& filename );
391 
392  void dbg_update_object( const fc::variant_object& update );
393 
394  void use_network_node_api();
395 
396  void use_debug_api();
397 
398  void network_add_nodes( const vector<string>& nodes );
399 
400  vector< variant > network_get_connected_peers();
401 
402  void flood_network(string prefix, uint32_t number_of_transactions);
403 
404  operation get_prototype_operation( string operation_name );
405 
408 
409  map<public_key_type,string> _keys;
411 
418  optional< fc::api<network_node_api> > _remote_net_node;
419  optional< fc::api<graphene::debug_witness::debug_api> > _remote_debug;
420 
421  flat_map<string, operation> _prototype_ops;
422 
423  static_variant_map _operation_which_map = create_static_variant_map< operation >();
424 
425 private:
426  std::string account_id_to_string(account_id_type id) const;
427 
428  static htlc_hash do_hash( const string& algorithm, const std::string& hash );
429 
430  void enable_umask_protection();
431 
432  void disable_umask_protection();
433 
434  // This function generates derived keys starting with index 0 and keeps incrementing
435  // the index until it finds a key that isn't registered in the block chain. To be
436  // safer, it continues checking for a few more keys to make sure there wasn't a short gap
437  // caused by a failed registration or the like.
438  int find_first_unused_derived_key_index(const fc::ecc::private_key& parent_key);
439 
440  void claim_registered_account(const graphene::chain::account_object& account);
441 
442  // after a witness registration succeeds, this saves the private key in the wallet permanently
443  //
444  void claim_registered_witness(const std::string& witness_name);
445 
446  fc::mutex _resync_mutex;
447  void resync();
448 
449  void init_prototype_ops();
450 
451  map<transaction_handle_type, signed_transaction> _builder_transactions;
452 
453  // if the user executes the same command twice in quick succession,
454  // we might generate the same transaction id, and cause the second
455  // transaction to be rejected. This can be avoided by altering the
456  // second transaction slightly (bumping up the expiration time by
457  // a second). Keep track of recent transaction ids we've generated
458  // so we can know if we need to do this
459  struct recently_generated_transaction_record
460  {
461  fc::time_point_sec generation_time;
463  };
464  struct timestamp_index{};
465  typedef boost::multi_index_container<
466  recently_generated_transaction_record,
467  boost::multi_index::indexed_by<
468  boost::multi_index::hashed_unique<
469  boost::multi_index::member<
470  recently_generated_transaction_record,
472  &recently_generated_transaction_record::transaction_id
473  >,
474  std::hash<graphene::chain::transaction_id_type>
475  >,
476  boost::multi_index::ordered_non_unique<
477  boost::multi_index::tag<timestamp_index>,
478  boost::multi_index::member<
479  recently_generated_transaction_record,
481  &recently_generated_transaction_record::generation_time
482  >
483  >
484  >
485  > recently_generated_transaction_set_type;
486  recently_generated_transaction_set_type _recently_generated_transactions;
487 
488 #ifdef __unix__
489  mode_t _old_umask;
490 #endif
491  const string _wallet_filename_extension = ".wallet";
492 };
493 
494 }}} // namespace graphene::wallet::detail
fc::optional< T > maybe_id(const string &name_or_id)
flat_map< std::string, graphene::protocol::operation > & name2op
string address_to_shorthash(const graphene::protocol::address &addr)
Definition: wallet_sign.cpp:36
microseconds minutes(int64_t m)
Definition: time.hpp:36
T as(uint32_t max_depth) const
Definition: variant.hpp:336
fc::api< custom_operations_api > _custom_operations
#define GRAPHENE_MAX_NESTED_OBJECTS
Definition: config.hpp:31
contains all of the parameters necessary to calculate the fee for any operation
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
The asset_options struct contains options available on all assets in the network. ...
Definition: asset_ops.hpp:47
Used to generate a useful error report when an exception is thrown.At each level in the stack where t...
Definition: exception.hpp:56
flat_map< string, operation > _prototype_ops
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 >
groups operations that should be applied atomically
Definition: transaction.hpp:68
const auto source
fc::api< network_broadcast_api > _remote_net_broadcast
provides stack-based nullable value similar to boost::optional
Definition: optional.hpp:20
optional< fc::api< network_node_api > > _remote_net_node
mutex
Definition: mutex.hpp:91
fc::ecc::private_key derive_private_key(const std::string &prefix_string, int sequence_number)
Definition: wallet_sign.cpp:54
The price struct stores asset prices in the BitShares system.
Definition: asset.hpp:114
adds a signature to a transaction
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object&#39;s.
Definition: variant.hpp:198
string normalize_brain_key(string s)
Definition: wallet_sign.cpp:62
typename object_downcast< ObjectID >::type object_downcast_t
Definition: object_id.hpp:105
defines market parameters for margin positions
Definition: asset.hpp:164
uint16_t transaction_handle_type
graphene::db::object_downcast_t< ID > get_object(ID id) const
map< public_key_type, string > _keys
result_type operator()(const Type &op) const
Maintains global state information (committee_member list, current fees)This is an implementation det...
a 160 bit hash of a public key
Definition: address.hpp:44
optional< fc::api< graphene::debug_witness::debug_api > > _remote_debug
#define GRAPHENE_SYMBOL
Definition: config.hpp:26
static time_point now()
Definition: time.cpp:13
an elliptic curve private key.
Definition: elliptic.hpp:89
fc::ripemd160 transaction_id_type
Definition: types.hpp:244
zero_initialized_array< unsigned char, 65 > compact_signature
Definition: elliptic.hpp:27
tracks information about a committee_member account.A committee_member is responsible for setting blo...
op_prototype_visitor(int _t, flat_map< std::string, graphene::protocol::operation > &_prototype_ops)
The bitasset_options struct contains configurable options available only to BitAssets.
Definition: asset_ops.hpp:109
defines the keys used to derive the shared secret
Definition: memo.hpp:40
Definition: api.hpp:120