BitShares-Core  7.0.2
BitShares blockchain node software and command-line wallet software
wallet_sign.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 
25 #include <fc/crypto/aes.hpp>
26 
27 #include "wallet_api_impl.hpp"
29 
30 /***
31  * These methods handle signing and keys
32  */
33 
34 namespace graphene { namespace wallet { namespace detail {
35 
37  {
38  uint32_t x = addr.addr._hash[0].value();
39  static const char hd[] = "0123456789abcdef";
40  string result;
41 
42  result += hd[(x >> 0x1c) & 0x0f];
43  result += hd[(x >> 0x18) & 0x0f];
44  result += hd[(x >> 0x14) & 0x0f];
45  result += hd[(x >> 0x10) & 0x0f];
46  result += hd[(x >> 0x0c) & 0x0f];
47  result += hd[(x >> 0x08) & 0x0f];
48  result += hd[(x >> 0x04) & 0x0f];
49  result += hd[(x ) & 0x0f];
50 
51  return result;
52  }
53 
54  fc::ecc::private_key derive_private_key( const std::string& prefix_string, int sequence_number )
55  {
56  std::string sequence_string = std::to_string(sequence_number);
57  fc::sha512 h = fc::sha512::hash(prefix_string + " " + sequence_string);
59  return derived_key;
60  }
61 
62  string normalize_brain_key( string s )
63  {
64  size_t i = 0, n = s.length();
65  std::string result;
66  char c;
67  result.reserve( n );
68 
69  bool preceded_by_whitespace = false;
70  bool non_empty = false;
71  while( i < n )
72  {
73  c = s[i++];
74  switch( c )
75  {
76  case ' ': case '\t': case '\r': case '\n': case '\v': case '\f':
77  preceded_by_whitespace = true;
78  continue;
79 
80  case 'a': c = 'A'; break;
81  case 'b': c = 'B'; break;
82  case 'c': c = 'C'; break;
83  case 'd': c = 'D'; break;
84  case 'e': c = 'E'; break;
85  case 'f': c = 'F'; break;
86  case 'g': c = 'G'; break;
87  case 'h': c = 'H'; break;
88  case 'i': c = 'I'; break;
89  case 'j': c = 'J'; break;
90  case 'k': c = 'K'; break;
91  case 'l': c = 'L'; break;
92  case 'm': c = 'M'; break;
93  case 'n': c = 'N'; break;
94  case 'o': c = 'O'; break;
95  case 'p': c = 'P'; break;
96  case 'q': c = 'Q'; break;
97  case 'r': c = 'R'; break;
98  case 's': c = 'S'; break;
99  case 't': c = 'T'; break;
100  case 'u': c = 'U'; break;
101  case 'v': c = 'V'; break;
102  case 'w': c = 'W'; break;
103  case 'x': c = 'X'; break;
104  case 'y': c = 'Y'; break;
105  case 'z': c = 'Z'; break;
106 
107  default:
108  break;
109  }
110  if( preceded_by_whitespace && non_empty )
111  result.push_back(' ');
112  result.push_back(c);
113  preceded_by_whitespace = false;
114  non_empty = true;
115  }
116  return result;
117  }
118 
120  {
121  if( !is_locked() )
122  {
123  plain_keys data;
124  data.keys = _keys;
125  data.checksum = _checksum;
126  auto plain_txt = fc::raw::pack(data);
127  _wallet.cipher_keys = fc::aes_encrypt( data.checksum, plain_txt );
128  }
129  }
130 
131  memo_data wallet_api_impl::sign_memo(string from, string to, string memo)
132  {
133  FC_ASSERT( !self.is_locked() );
134 
135  memo_data md = memo_data();
136 
137  // get account memo key, if that fails, try a pubkey
138  try {
139  account_object from_account = get_account(from);
140  md.from = from_account.options.memo_key;
141  } catch (const fc::exception&) {
142  // check if the string itself is a pubkey, if not, consider it as a label
143  try {
144  md.from = public_key_type( from );
145  } catch (const fc::exception&) {
146  md.from = self.get_public_key( from );
147  }
148  }
149  // same as above, for destination key
150  try {
151  account_object to_account = get_account(to);
152  md.to = to_account.options.memo_key;
153  } catch (const fc::exception&) {
154  // check if the string itself is a pubkey, if not, consider it as a label
155  try {
156  md.to = public_key_type( to );
157  } catch (const fc::exception&) {
158  md.to = self.get_public_key( to );
159  }
160  }
161 
162  // try to get private key of from and sign, if that fails, try to sign with to
163  try {
164  md.set_message(get_private_key(md.from), md.to, memo);
165  } catch (const fc::exception&) {
166  std::swap( md.from, md.to );
167  md.set_message(get_private_key(md.from), md.to, memo);
168  std::swap( md.from, md.to );
169  }
170  return md;
171  }
172 
173  string wallet_api_impl::read_memo(const memo_data& md)
174  {
175  FC_ASSERT(!is_locked());
176  std::string clear_text;
177 
178  const memo_data *memo = &md;
179 
180  try {
181  FC_ASSERT( _keys.count(memo->to) > 0 || _keys.count(memo->from) > 0,
182  "Memo is encrypted to a key ${to} or ${from} not in this wallet.",
183  ("to", memo->to)("from",memo->from) );
184  if( _keys.count(memo->to) > 0 ) {
185  auto my_key = wif_to_key(_keys.at(memo->to));
186  FC_ASSERT(my_key, "Unable to recover private key to decrypt memo. Wallet may be corrupted.");
187  clear_text = memo->get_message(*my_key, memo->from);
188  } else {
189  auto my_key = wif_to_key(_keys.at(memo->from));
190  FC_ASSERT(my_key, "Unable to recover private key to decrypt memo. Wallet may be corrupted.");
191  clear_text = memo->get_message(*my_key, memo->to);
192  }
193  } catch (const fc::exception& e) {
194  elog("Error when decrypting memo: ${e}", ("e", e.to_detail_string()));
195  }
196 
197  return clear_text;
198  }
199 
200  signed_message wallet_api_impl::sign_message(string signer, string message)
201  {
202  FC_ASSERT( !self.is_locked() );
203 
204  const account_object from_account = get_account(signer);
205  auto dynamic_props = get_dynamic_global_properties();
206 
207  signed_message msg;
208  msg.message = message;
209  msg.meta.account = from_account.name;
210  msg.meta.memo_key = from_account.options.memo_key;
211  msg.meta.block = dynamic_props.head_block_number;
212  msg.meta.time = dynamic_props.time.to_iso_string() + "Z";
213  msg.signature = get_private_key( from_account.options.memo_key ).sign_compact( msg.digest() );
214  return msg;
215  }
216 
217  bool wallet_api_impl::verify_message( const string& message, const string& account, int32_t block,
218  const string& msg_time, const fc::ecc::compact_signature& sig )
219  {
220  const account_object from_account = get_account( account );
221 
222  signed_message msg;
224  msg.meta.account = from_account.name;
225  msg.meta.memo_key = from_account.options.memo_key;
226  msg.meta.block = block;
227  msg.meta.time = msg_time;
228  msg.signature = sig;
229 
230  return verify_signed_message( msg );
231  }
232 
234  {
235  if( !message.signature.valid() ) return false;
236 
237  const account_object from_account = get_account( message.meta.account );
238 
239  const fc::ecc::public_key signer( *message.signature, message.digest() );
240  if( !( message.meta.memo_key == signer ) ) return false;
241  FC_ASSERT( from_account.options.memo_key == signer,
242  "Message was signed by contained key, but it doesn't belong to the contained account!" );
243 
244  return true;
245  }
246 
247  /* meta contains lines of the form "key=value".
248  * Returns the value for the corresponding key, throws if key is not present. */
249  static string meta_extract( const string& meta, const string& key )
250  {
251  FC_ASSERT( meta.size() > key.size(), "Key '${k}' not found!", ("k",key) );
252  size_t start;
253  if( meta.substr( 0, key.size() ) == key && meta[key.size()] == '=' )
254  start = 0;
255  else
256  {
257  start = meta.find( "\n" + key + "=" );
258  FC_ASSERT( start != string::npos, "Key '${k}' not found!", ("k",key) );
259  ++start;
260  }
261  start += key.size() + 1;
262  size_t lf = meta.find( "\n", start );
263  if( lf == string::npos ) lf = meta.size();
264  return meta.substr( start, lf - start );
265  }
266 
268  {
269  signed_message msg;
270  size_t begin_p = message.find( ENC_HEADER );
271  FC_ASSERT( begin_p != string::npos, "BEGIN MESSAGE line not found!" );
272  size_t meta_p = message.find( ENC_META, begin_p );
273  FC_ASSERT( meta_p != string::npos, "BEGIN META line not found!" );
274  FC_ASSERT( meta_p >= begin_p + ENC_HEADER.size() + 1, "Missing message!?" );
275  size_t sig_p = message.find( ENC_SIG, meta_p );
276  FC_ASSERT( sig_p != string::npos, "BEGIN SIGNATURE line not found!" );
277  FC_ASSERT( sig_p >= meta_p + ENC_META.size(), "Missing metadata?!" );
278  size_t end_p = message.find( ENC_FOOTER, meta_p );
279  FC_ASSERT( end_p != string::npos, "END MESSAGE line not found!" );
280  FC_ASSERT( end_p >= sig_p + ENC_SIG.size() + 1, "Missing signature?!" );
281 
282  msg.message = message.substr( begin_p + ENC_HEADER.size(), meta_p - begin_p - ENC_HEADER.size() - 1 );
283  const string meta = message.substr( meta_p + ENC_META.size(), sig_p - meta_p - ENC_META.size() );
284  const string sig = message.substr( sig_p + ENC_SIG.size(), end_p - sig_p - ENC_SIG.size() - 1 );
285 
286  msg.meta.account = meta_extract( meta, "account" );
287  msg.meta.memo_key = public_key_type( meta_extract( meta, "memokey" ) );
288  msg.meta.block = boost::lexical_cast<uint32_t>( meta_extract( meta, "block" ) );
289  msg.meta.time = meta_extract( meta, "timestamp" );
290  msg.signature = variant(sig).as< fc::ecc::compact_signature >( 5 );
291 
292  return verify_signed_message( msg );
293  }
294 
296  bool broadcast )
297  {
298  set<public_key_type> approving_key_set = get_owned_required_keys(tx, false);
299 
300  if ( ( ( tx.ref_block_num == 0 && tx.ref_block_prefix == 0 ) ||
302  tx.signatures.empty() )
303  {
304  auto dyn_props = get_dynamic_global_properties();
305  auto parameters = get_global_properties().parameters;
306  fc::time_point_sec now = dyn_props.time;
307  tx.set_reference_block( dyn_props.head_block_id );
308  tx.set_expiration( now + parameters.maximum_time_until_expiration );
309  }
310  for ( const public_key_type &key : approving_key_set )
311  tx.sign( get_private_key( key ), _chain_id );
312 
313  if ( broadcast )
314  {
315  try
316  {
317  _remote_net_broadcast->broadcast_transaction( tx );
318  }
319  catch ( const fc::exception &e )
320  {
321  elog( "Caught exception while broadcasting tx ${id}: ${e}",
322  ( "id", tx.id().str() )( "e", e.to_detail_string() ) );
323  FC_THROW( "Caught exception while broadcasting tx" );
324  }
325  }
326 
327  return tx;
328  }
329 
331  {
332  return sign_transaction2(tx, {}, broadcast);
333  }
334 
336  const vector<public_key_type>& signing_keys, bool broadcast)
337  {
338  set<public_key_type> approving_key_set = get_owned_required_keys(tx);
339 
340  // Add any explicit keys to the approving_key_set
341  for (const public_key_type& explicit_key : signing_keys) {
342  approving_key_set.insert(explicit_key);
343  }
344 
345  auto dyn_props = get_dynamic_global_properties();
346  tx.set_reference_block( dyn_props.head_block_id );
347 
348  // first, some bookkeeping, expire old items from _recently_generated_transactions
349  // since transactions include the head block id, we just need the index for keeping transactions unique
350  // when there are multiple transactions in the same block. choose a time period that should be at
351  // least one block long, even in the worst case. 2 minutes ought to be plenty.
352  fc::time_point_sec oldest_transaction_ids_to_track(dyn_props.time - fc::minutes(2));
353  auto oldest_transaction_record_iter =
354  _recently_generated_transactions.get<timestamp_index>().lower_bound(oldest_transaction_ids_to_track);
355  auto begin_iter = _recently_generated_transactions.get<timestamp_index>().begin();
356  _recently_generated_transactions.get<timestamp_index>().erase(begin_iter, oldest_transaction_record_iter);
357 
358  uint32_t expiration_time_offset = 0;
359  for (;;)
360  {
361  tx.set_expiration( dyn_props.time + fc::seconds(30 + expiration_time_offset) );
362  tx.clear_signatures();
363 
364  for( const public_key_type& key : approving_key_set )
365  tx.sign( get_private_key(key), _chain_id );
366 
367  graphene::chain::transaction_id_type this_transaction_id = tx.id();
368  auto iter = _recently_generated_transactions.find(this_transaction_id);
369  if (iter == _recently_generated_transactions.end())
370  {
371  // we haven't generated this transaction before, the usual case
372  recently_generated_transaction_record this_transaction_record;
373  this_transaction_record.generation_time = dyn_props.time;
374  this_transaction_record.transaction_id = this_transaction_id;
375  _recently_generated_transactions.insert(this_transaction_record);
376  break;
377  }
378 
379  // else we've generated a dupe, increment expiration time and re-sign it
380  ++expiration_time_offset;
381  }
382 
383  if( broadcast )
384  {
385  try
386  {
387  _remote_net_broadcast->broadcast_transaction( tx );
388  }
389  catch (const fc::exception& e)
390  {
391  elog("Caught exception while broadcasting tx ${id}: ${e}",
392  ("id", tx.id().str())("e", e.to_detail_string()) );
393  throw;
394  }
395  }
396 
397  return tx;
398  }
399 
401  {
402  auto it = _keys.find(id);
403  FC_ASSERT( it != _keys.end() );
404 
405  fc::optional< fc::ecc::private_key > privkey = wif_to_key( it->second );
406  FC_ASSERT( privkey );
407  return *privkey;
408  }
409 
411  {
412  vector<public_key_type> active_keys = account.active.get_keys();
413  if (active_keys.size() != 1)
414  FC_THROW("Expecting a simple authority with one active key");
415  return get_private_key(active_keys.front());
416  }
417 
418  // imports the private key into the wallet, and associate it in some way (?) with the
419  // given account name.
420  // @returns true if the key matches a current active/owner/memo key for the named
421  // account, false otherwise (but it is stored either way)
422  bool wallet_api_impl::import_key(string account_name_or_id, string wif_key)
423  {
424  fc::optional<fc::ecc::private_key> optional_private_key = wif_to_key(wif_key);
425  if (!optional_private_key)
426  FC_THROW("Invalid private key");
427  graphene::chain::public_key_type wif_pub_key = optional_private_key->get_public_key();
428 
429  account_object account = get_account( account_name_or_id );
430 
431  // make a list of all current public keys for the named account
432  flat_set<public_key_type> all_keys_for_account;
433  std::vector<public_key_type> active_keys = account.active.get_keys();
434  std::vector<public_key_type> owner_keys = account.owner.get_keys();
435  std::copy(active_keys.begin(), active_keys.end(),
436  std::inserter(all_keys_for_account, all_keys_for_account.end()));
437  std::copy(owner_keys.begin(), owner_keys.end(),
438  std::inserter(all_keys_for_account, all_keys_for_account.end()));
439  all_keys_for_account.insert(account.options.memo_key);
440 
441  _keys[wif_pub_key] = wif_key;
442 
443  _wallet.update_account(account);
444 
445  _wallet.extra_keys[account.get_id()].insert(wif_pub_key);
446 
447  return all_keys_for_account.find(wif_pub_key) != all_keys_for_account.end();
448  }
449 
466  bool erase_existing_sigs )
467  {
468  set<public_key_type> pks = _remote_db->get_potential_signatures( tx );
469  flat_set<public_key_type> owned_keys;
470  owned_keys.reserve( pks.size() );
471  std::copy_if( pks.begin(), pks.end(),
472  std::inserter( owned_keys, owned_keys.end() ),
473  [this]( const public_key_type &pk ) {
474  return _keys.find( pk ) != _keys.end();
475  } );
476 
477  if ( erase_existing_sigs )
478  tx.signatures.clear();
479 
480  return _remote_db->get_required_signatures( tx, owned_keys );
481  }
482 
483  flat_set<public_key_type> wallet_api_impl::get_transaction_signers(const signed_transaction &tx) const
484  {
485  return tx.get_signature_keys(_chain_id);
486  }
487 
488  signed_transaction wallet_api_impl::approve_proposal( const string& fee_paying_account, const string& proposal_id,
489  const approval_delta& delta, bool broadcast )
490  {
491  proposal_update_operation update_op;
492 
493  update_op.fee_paying_account = get_account(fee_paying_account).id;
494  update_op.proposal = fc::variant(proposal_id, 1).as<proposal_id_type>( 1 );
495  // make sure the proposal exists
496  get_object( update_op.proposal );
497 
498  for( const std::string& name : delta.active_approvals_to_add )
499  update_op.active_approvals_to_add.insert( get_account( name ).get_id() );
500  for( const std::string& name : delta.active_approvals_to_remove )
501  update_op.active_approvals_to_remove.insert( get_account( name ).get_id() );
502  for( const std::string& name : delta.owner_approvals_to_add )
503  update_op.owner_approvals_to_add.insert( get_account( name ).get_id() );
504  for( const std::string& name : delta.owner_approvals_to_remove )
505  update_op.owner_approvals_to_remove.insert( get_account( name ).get_id() );
506  for( const std::string& k : delta.key_approvals_to_add )
507  update_op.key_approvals_to_add.insert( public_key_type( k ) );
508  for( const std::string& k : delta.key_approvals_to_remove )
509  update_op.key_approvals_to_remove.insert( public_key_type( k ) );
510 
512  tx.operations.push_back(update_op);
513  set_operation_fees(tx, get_global_properties().parameters.get_current_fees());
514  tx.validate();
515  return sign_transaction(tx, broadcast);
516  }
517 
518 }}} // namespace graphene::wallet::detail
graphene::wallet::detail::wallet_api_impl::verify_signed_message
bool verify_signed_message(const signed_message &message)
Definition: wallet_sign.cpp:239
graphene::wallet::detail::normalize_brain_key
string normalize_brain_key(string s)
Definition: wallet_sign.cpp:68
graphene::wallet::signed_message_meta::time
string time
Definition: wallet_structs.hpp:257
graphene::protocol::transaction::operations
vector< operation > operations
Definition: transaction.hpp:89
fc::copy
void copy(const path &from, const path &to)
Definition: filesystem.cpp:241
graphene::protocol::proposal_update_operation
The proposal_update_operation updates an existing transaction proposal.
Definition: proposal.hpp:119
graphene::wallet::detail::wallet_api_impl::approve_proposal
signed_transaction approve_proposal(const string &fee_paying_account, const string &proposal_id, const approval_delta &delta, bool broadcast=false)
Definition: wallet_sign.cpp:494
graphene::protocol::proposal_update_operation::key_approvals_to_remove
flat_set< public_key_type > key_approvals_to_remove
Definition: proposal.hpp:134
graphene::db::object::id
object_id_type id
Definition: object.hpp:69
fc::exception
Used to generate a useful error report when an exception is thrown.
Definition: exception.hpp:56
graphene::wallet::detail::wallet_api_impl::get_private_key_for_account
fc::ecc::private_key get_private_key_for_account(const account_object &account) const
Definition: wallet_sign.cpp:416
graphene::wallet::detail::wallet_api_impl::_checksum
fc::sha512 _checksum
Definition: wallet_api_impl.hpp:410
fc::to_string
std::string to_string(double)
Definition: string.cpp:73
graphene::protocol::transaction::id
virtual const transaction_id_type & id() const
Definition: transaction.cpp:70
graphene::wallet::detail::wallet_api_impl::sign_message
signed_message sign_message(string signer, string message)
Definition: wallet_sign.cpp:206
graphene::protocol::proposal_update_operation::fee_paying_account
account_id_type fee_paying_account
Definition: proposal.hpp:126
graphene::protocol::signed_transaction::clear_signatures
void clear_signatures()
Definition: transaction.hpp:223
graphene::utilities::wif_to_key
fc::optional< fc::ecc::private_key > wif_to_key(const std::string &wif_key)
Definition: key_conversion.cpp:47
graphene::wallet::detail::derive_private_key
fc::ecc::private_key derive_private_key(const std::string &prefix_string, int sequence_number)
Definition: wallet_sign.cpp:60
graphene::protocol::signed_transaction::sign
const signature_type & sign(const private_key_type &key, const chain_id_type &chain_id)
Definition: transaction.cpp:77
graphene::wallet::detail::wallet_api_impl::get_private_key
fc::ecc::private_key get_private_key(const public_key_type &id) const
Definition: wallet_sign.cpp:406
graphene::chain::account_object::active
authority active
Definition: account_object.hpp:220
graphene::chain::global_property_object::parameters
chain_parameters parameters
Definition: global_property_object.hpp:44
FC_THROW
#define FC_THROW( ...)
Definition: exception.hpp:366
graphene::wallet::detail::wallet_api_impl::_remote_db
fc::api< database_api > _remote_db
Definition: wallet_api_impl.hpp:414
graphene::protocol::memo_data::get_message
std::string get_message(const fc::ecc::private_key &priv, const fc::ecc::public_key &pub) const
Definition: memo.cpp:61
graphene::net::message
Definition: message.hpp:58
graphene::protocol::transaction::set_reference_block
void set_reference_block(const block_id_type &reference_block)
Definition: transaction.cpp:97
graphene::wallet::detail::wallet_api_impl::encrypt_keys
void encrypt_keys()
Definition: wallet_sign.cpp:125
graphene::wallet::approval_delta::active_approvals_to_add
vector< string > active_approvals_to_add
Definition: wallet_structs.hpp:214
graphene::protocol::transaction::expiration
fc::time_point_sec expiration
Definition: transaction.hpp:87
graphene::wallet::detail::wallet_api_impl::read_memo
string read_memo(const memo_data &md)
Definition: wallet_sign.cpp:179
graphene::wallet::detail::wallet_api_impl::sign_transaction
signed_transaction sign_transaction(signed_transaction tx, bool broadcast=false)
Definition: wallet_sign.cpp:336
graphene::wallet::detail::wallet_api_impl::set_operation_fees
void set_operation_fees(signed_transaction &tx, const fee_schedule &s) const
Definition: wallet_api_impl.cpp:197
fc::zero_initialized_array
Definition: zeroed_array.hpp:30
fc::ecc::public_key
contains only the public point of an elliptic curve key.
Definition: elliptic.hpp:35
wallet_api_impl.hpp
graphene::protocol::proposal_update_operation::owner_approvals_to_add
flat_set< account_id_type > owner_approvals_to_add
Definition: proposal.hpp:131
graphene::protocol::transaction::set_expiration
void set_expiration(fc::time_point_sec expiration_time)
Definition: transaction.cpp:92
graphene::protocol::public_key_type
Definition: types.hpp:312
fc::seconds
microseconds seconds(int64_t s)
Definition: time.hpp:34
fc::ripemd160::_hash
boost::endian::little_uint32_buf_t _hash[5]
Definition: ripemd160.hpp:71
graphene::wallet::detail::wallet_api_impl::get_account
account_object get_account(account_id_type id) const
Definition: wallet_account.cpp:193
graphene::wallet::approval_delta::key_approvals_to_add
vector< string > key_approvals_to_add
Definition: wallet_structs.hpp:218
graphene::protocol::memo_data::to
public_key_type to
Definition: memo.hpp:43
graphene::protocol::proposal_update_operation::key_approvals_to_add
flat_set< public_key_type > key_approvals_to_add
Definition: proposal.hpp:133
fc::ecc::private_key
an elliptic curve private key.
Definition: elliptic.hpp:89
graphene::protocol::signed_transaction
adds a signature to a transaction
Definition: transaction.hpp:134
fc::sha512
Definition: sha512.hpp:9
graphene::wallet::detail::wallet_api_impl::_chain_id
chain_id_type _chain_id
Definition: wallet_api_impl.hpp:412
graphene::wallet::approval_delta
Definition: wallet_structs.hpp:212
graphene::protocol::signed_transaction::get_signature_keys
virtual const flat_set< public_key_type > & get_signature_keys(const chain_id_type &chain_id) const
Extract public keys from signatures with given chain ID.
Definition: transaction.cpp:350
graphene::wallet::signed_message_meta::block
uint32_t block
Definition: wallet_structs.hpp:256
graphene::chain::account_object::options
account_options options
Definition: account_object.hpp:222
graphene::wallet::signed_message::digest
fc::sha256 digest() const
Definition: wallet.cpp:88
fc::ecc::private_key::sign_compact
compact_signature sign_compact(const fc::sha256 &digest, bool require_canonical=true) const
Definition: elliptic_impl_priv.cpp:89
graphene::wallet::detail::wallet_api_impl::get_owned_required_keys
set< public_key_type > get_owned_required_keys(signed_transaction &tx, bool erase_existing_sigs=true)
Definition: wallet_sign.cpp:471
wallet.hpp
graphene::wallet::signed_message::signature
fc::optional< fc::ecc::compact_signature > signature
Definition: wallet_structs.hpp:264
fc::sha512::hash
static sha512 hash(const char *d, uint32_t dlen)
Definition: sha512.cpp:34
graphene::chain::account_object
This class represents an account on the object graph.
Definition: account_object.hpp:180
graphene::wallet::signed_message::meta
signed_message_meta meta
Definition: wallet_structs.hpp:263
fc::time_point_sec
Definition: time.hpp:74
graphene::protocol::account_options::memo_key
public_key_type memo_key
Definition: account.hpp:44
graphene::wallet::wallet_data::update_account
bool update_account(const account_object &acct)
Definition: wallet_structs.hpp:166
fc::variant::as
T as(uint32_t max_depth) const
Definition: variant.hpp:337
fc::ripemd160
Definition: ripemd160.hpp:11
graphene::protocol::authority::get_keys
vector< public_key_type > get_keys() const
Definition: authority.hpp:85
graphene::chain::account_object::owner
authority owner
Definition: account_object.hpp:217
graphene::wallet::detail::wallet_api_impl::get_dynamic_global_properties
dynamic_global_property_object get_dynamic_global_properties() const
Definition: wallet_api_impl.cpp:187
graphene::protocol::transaction::ref_block_num
uint16_t ref_block_num
Definition: transaction.hpp:76
fc::ripemd160::str
string str() const
Definition: ripemd160.cpp:21
graphene::wallet::detail::wallet_api_impl::import_key
bool import_key(string account_name_or_id, string wif_key)
Definition: wallet_sign.cpp:428
fc::minutes
microseconds minutes(int64_t m)
Definition: time.hpp:36
fc::exception::to_detail_string
std::string to_detail_string(log_level ll=log_level::all) const
Definition: exception.cpp:183
graphene::wallet::detail::wallet_api_impl::sign_transaction2
signed_transaction sign_transaction2(signed_transaction tx, const vector< public_key_type > &signing_keys=vector< public_key_type >(), bool broadcast=false)
Definition: wallet_sign.cpp:341
graphene::protocol::transaction::ref_block_prefix
uint32_t ref_block_prefix
Definition: transaction.hpp:82
graphene::wallet::approval_delta::key_approvals_to_remove
vector< string > key_approvals_to_remove
Definition: wallet_structs.hpp:219
graphene::protocol::proposal_update_operation::active_approvals_to_add
flat_set< account_id_type > active_approvals_to_add
Definition: proposal.hpp:129
fc::ecc::private_key::get_public_key
public_key get_public_key() const
Definition: elliptic_impl_priv.cpp:70
graphene::wallet::detail::wallet_api_impl::_keys
map< public_key_type, string > _keys
Definition: wallet_api_impl.hpp:409
graphene::wallet::approval_delta::owner_approvals_to_add
vector< string > owner_approvals_to_add
Definition: wallet_structs.hpp:216
graphene::wallet::detail::wallet_api_impl::_wallet
wallet_data _wallet
Definition: wallet_api_impl.hpp:407
graphene::wallet::detail::wallet_api_impl::verify_message
bool verify_message(const string &message, const string &account, int32_t block, const string &msg_time, const fc::ecc::compact_signature &sig)
Definition: wallet_sign.cpp:223
graphene::wallet::signed_message_meta::memo_key
public_key_type memo_key
Definition: wallet_structs.hpp:255
FC_ASSERT
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
graphene::wallet::detail::wallet_api_impl::get_transaction_signers
flat_set< public_key_type > get_transaction_signers(const signed_transaction &tx) const
Definition: wallet_sign.cpp:489
graphene::protocol::memo_data::set_message
void set_message(const fc::ecc::private_key &priv, const fc::ecc::public_key &pub, const string &msg, uint64_t custom_nonce=0)
Definition: memo.cpp:31
graphene::protocol::signed_transaction::signatures
vector< signature_type > signatures
Definition: transaction.hpp:217
graphene::chain::account_object::name
string name
The account's name. This name must be unique among all account names on the graph....
Definition: account_object.hpp:209
graphene::protocol::address::addr
fc::ripemd160 addr
Definition: address.hpp:58
graphene::protocol::transaction::validate
virtual void validate() const
Definition: transaction.cpp:58
fc::variant
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
Definition: variant.hpp:198
graphene::wallet::detail::wallet_api_impl::_remote_net_broadcast
fc::api< network_broadcast_api > _remote_net_broadcast
Definition: wallet_api_impl.hpp:415
graphene::protocol::proposal_update_operation::owner_approvals_to_remove
flat_set< account_id_type > owner_approvals_to_remove
Definition: proposal.hpp:132
graphene::wallet::wallet_data::cipher_keys
vector< char > cipher_keys
Definition: wallet_structs.hpp:181
graphene::wallet::detail::address_to_shorthash
string address_to_shorthash(const graphene::protocol::address &addr)
Definition: wallet_sign.cpp:42
graphene::wallet::detail::wallet_api_impl::sign_memo
memo_data sign_memo(string from, string to, string memo)
Definition: wallet_sign.cpp:137
graphene::wallet::detail::wallet_api_impl::get_object
graphene::db::object_downcast_t< const ID & > get_object(const ID &id) const
Definition: wallet_api_impl.hpp:129
graphene::wallet::approval_delta::owner_approvals_to_remove
vector< string > owner_approvals_to_remove
Definition: wallet_structs.hpp:217
graphene::protocol::proposal_update_operation::active_approvals_to_remove
flat_set< account_id_type > active_approvals_to_remove
Definition: proposal.hpp:130
graphene::protocol::memo_data
defines the keys used to derive the shared secret
Definition: memo.hpp:40
graphene::wallet::detail::wallet_api_impl::is_locked
bool is_locked() const
Definition: wallet_api_impl.cpp:304
graphene::db::abstract_object::get_id
object_id< SpaceID, TypeID > get_id() const
Definition: object.hpp:113
graphene::wallet::signed_message_meta::account
string account
Definition: wallet_structs.hpp:254
aes.hpp
fc::optional
provides stack-based nullable value similar to boost::optional
Definition: optional.hpp:20
graphene::protocol::proposal_update_operation::proposal
proposal_id_type proposal
Definition: proposal.hpp:128
graphene::wallet::detail::wallet_api_impl::verify_encapsulated_message
bool verify_encapsulated_message(const string &message)
Definition: wallet_sign.cpp:273
graphene::protocol::memo_data::from
public_key_type from
Definition: memo.hpp:42
graphene::wallet::signed_message
Definition: wallet_structs.hpp:260
graphene::wallet::approval_delta::active_approvals_to_remove
vector< string > active_approvals_to_remove
Definition: wallet_structs.hpp:215
fc::ecc::private_key::regenerate
static private_key regenerate(const fc::sha256 &secret)
Definition: elliptic_impl_priv.cpp:52
graphene::wallet::signed_message::message
string message
Definition: wallet_structs.hpp:262
graphene::wallet::wallet_data::extra_keys
map< account_id_type, set< public_key_type > > extra_keys
Definition: wallet_structs.hpp:184
fc::sha256::hash
static sha256 hash(const char *d, uint32_t dlen)
Definition: sha256.cpp:41
graphene
Definition: api.cpp:48
graphene::wallet::detail::wallet_api_impl::add_transaction_signature
signed_transaction add_transaction_signature(signed_transaction tx, bool broadcast)
Definition: wallet_sign.cpp:301
fc::aes_encrypt
unsigned aes_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, unsigned char *iv, unsigned char *ciphertext)
Definition: aes.cpp:181
graphene::protocol::address
a 160 bit hash of a public key
Definition: address.hpp:44
graphene::wallet::detail::wallet_api_impl::get_global_properties
global_property_object get_global_properties() const
Definition: wallet_api_impl.cpp:183
fc::raw::pack
void pack(Stream &s, const flat_set< T, A... > &value, uint32_t _max_depth)
Definition: flat.hpp:11
elog
#define elog(FORMAT,...)
Definition: logger.hpp:129