BitShares-Core  6.1.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({object_id_type(id)}, {}).front();
132  return ob.template as<graphene::db::object_downcast_t<const 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 ) const;
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(const htlc_id_type& htlc_id) const;
171 
172  asset_id_type get_asset_id(const 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( const string& source, const string& destination,
301  const string& amount, const string& asset_symbol, const string& hash_algorithm,
302  const string& preimage_hash, uint32_t preimage_size,
303  uint32_t claim_period_seconds, const string& memo, bool broadcast = false);
304 
305  signed_transaction htlc_redeem( const htlc_id_type& htlc_id, const string& issuer,
306  const std::vector<char>& preimage, bool broadcast );
307 
308  signed_transaction htlc_extend( const htlc_id_type& htlc_id, const string& issuer,
309  uint32_t seconds_to_add, bool broadcast);
310 
311  signed_transaction account_store_map(string account, string catalog, bool remove,
312  flat_map<string, optional<string>> key_values, bool broadcast);
313 
314  vector< vesting_balance_object_with_info > get_vesting_balances( string account_name );
315 
316  signed_transaction withdraw_vesting( string witness_name, string amount, string asset_symbol,
317  bool broadcast = false );
318 
319  signed_transaction vote_for_committee_member(string voting_account, string committee_member,
320  bool approve, bool broadcast );
321 
322  signed_transaction vote_for_witness(string voting_account, string witness, bool approve,
323  bool broadcast );
324 
325  signed_transaction set_voting_proxy(string account_to_modify, optional<string> voting_account,
326  bool broadcast );
327 
328  signed_transaction set_desired_witness_and_committee_member_count(string account_to_modify,
329  uint16_t desired_number_of_witnesses, uint16_t desired_number_of_committee_members,
330  bool broadcast );
331 
332  signed_transaction sign_transaction(signed_transaction tx, bool broadcast = false);
333  signed_transaction sign_transaction2(signed_transaction tx,
334  const vector<public_key_type>& signing_keys = vector<public_key_type>(),
335  bool broadcast = false);
336 
337  flat_set<public_key_type> get_transaction_signers(const signed_transaction &tx) const;
338 
339  vector<flat_set<account_id_type>> get_key_references(const vector<public_key_type> &keys) const;
340 
341  memo_data sign_memo(string from, string to, string memo);
342 
343  string read_memo(const memo_data& md);
344 
345  signed_message sign_message(string signer, string message);
346 
347  bool verify_message( const string& message, const string& account, int32_t block, const string& msg_time,
348  const fc::ecc::compact_signature& sig );
349 
350  bool verify_signed_message( const signed_message& message );
351 
352  bool verify_encapsulated_message( const string& message );
353 
354  signed_transaction sell_asset(string seller_account, string amount_to_sell, string symbol_to_sell,
355  string min_to_receive, string symbol_to_receive, uint32_t timeout_sec = 0,
356  bool fill_or_kill = false, bool broadcast = false);
357 
358  signed_transaction borrow_asset_ext( string seller_name, string amount_to_borrow, string asset_symbol,
359  string amount_of_collateral, call_order_update_operation::extensions_type extensions,
360  bool broadcast = false);
361 
362  signed_transaction cancel_order(const limit_order_id_type& order_id, bool broadcast = false);
363 
364  signed_transaction transfer(string from, string to, string amount,
365  string asset_symbol, string memo, bool broadcast = false);
366 
367  signed_transaction issue_asset(string to_account, string amount, string symbol,
368  string memo, bool broadcast = false);
369 
370  std::map< string, std::function< string( const fc::variant&, const fc::variants& ) >, std::less<> >
371  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  static htlc_hash do_hash( const string& algorithm, const std::string& hash );
427 
428  void enable_umask_protection();
429 
430  void disable_umask_protection();
431 
432  // This function generates derived keys starting with index 0 and keeps incrementing
433  // the index until it finds a key that isn't registered in the block chain. To be
434  // safer, it continues checking for a few more keys to make sure there wasn't a short gap
435  // caused by a failed registration or the like.
436  int find_first_unused_derived_key_index(const fc::ecc::private_key& parent_key);
437 
438  void claim_registered_account(const graphene::chain::account_object& account);
439 
440  // after a witness registration succeeds, this saves the private key in the wallet permanently
441  //
442  void claim_registered_witness(const std::string& witness_name);
443 
444  fc::mutex _resync_mutex;
445  void resync();
446 
447  void init_prototype_ops();
448 
449  map<transaction_handle_type, signed_transaction> _builder_transactions;
450 
451  // if the user executes the same command twice in quick succession,
452  // we might generate the same transaction id, and cause the second
453  // transaction to be rejected. This can be avoided by altering the
454  // second transaction slightly (bumping up the expiration time by
455  // a second). Keep track of recent transaction ids we've generated
456  // so we can know if we need to do this
457  struct recently_generated_transaction_record
458  {
459  fc::time_point_sec generation_time;
461  };
462  struct timestamp_index{};
463  typedef boost::multi_index_container<
464  recently_generated_transaction_record,
465  boost::multi_index::indexed_by<
466  boost::multi_index::hashed_unique<
467  boost::multi_index::member<
468  recently_generated_transaction_record,
470  &recently_generated_transaction_record::transaction_id
471  >,
472  std::hash<graphene::chain::transaction_id_type>
473  >,
474  boost::multi_index::ordered_non_unique<
475  boost::multi_index::tag<timestamp_index>,
476  boost::multi_index::member<
477  recently_generated_transaction_record,
479  &recently_generated_transaction_record::generation_time
480  >
481  >
482  >
483  > recently_generated_transaction_set_type;
484  recently_generated_transaction_set_type _recently_generated_transactions;
485 
486 #ifdef __unix__
487  mode_t _old_umask;
488 #endif
489  const string _wallet_filename_extension = ".wallet";
490 };
491 
492 }}} // 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
fc::api< custom_operations_api > _custom_operations
#define GRAPHENE_MAX_NESTED_OBJECTS
Definition: config.hpp:33
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:48
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, samet_fund_create_operation, samet_fund_delete_operation, samet_fund_update_operation, samet_fund_borrow_operation, samet_fund_repay_operation, credit_offer_create_operation, credit_offer_delete_operation, credit_offer_update_operation, credit_offer_accept_operation, credit_deal_repay_operation, credit_deal_expired_operation >
groups operations that should be applied atomically
Definition: transaction.hpp:69
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
result_type operator()(const Type &op) const
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:108
T as(uint32_t max_depth) const
Definition: variant.hpp:337
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
graphene::db::object_downcast_t< const ID & > get_object(const ID &id) const
typename object_downcast< ObjectID >::type object_downcast_t
Definition: object_id.hpp:100
defines market parameters for margin positions
Definition: asset.hpp:160
map< public_key_type, string > _keys
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
uint32_t transaction_handle_type
fc::ripemd160 transaction_id_type
Definition: types.hpp:306
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