34 namespace graphene {
namespace wallet {
namespace detail {
39 static const char hd[] =
"0123456789abcdef";
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];
64 size_t i = 0, n = s.length();
69 bool preceded_by_whitespace =
false;
70 bool non_empty =
false;
76 case ' ':
case '\t':
case '\r':
case '\n':
case '\v':
case '\f':
77 preceded_by_whitespace =
true;
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;
110 if( preceded_by_whitespace && non_empty )
111 result.push_back(
' ');
113 preceded_by_whitespace =
false;
146 md.
from =
self.get_public_key( from );
158 md.
to =
self.get_public_key( to );
166 std::swap( md.
from, md.
to );
168 std::swap( md.
from, md.
to );
176 std::string clear_text;
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 ) {
186 FC_ASSERT(my_key,
"Unable to recover private key to decrypt memo. Wallet may be corrupted.");
190 FC_ASSERT(my_key,
"Unable to recover private key to decrypt memo. Wallet may be corrupted.");
211 msg.
meta.
block = dynamic_props.head_block_number;
212 msg.
meta.
time = dynamic_props.time.to_iso_string() +
"Z";
235 if( !message.
signature.valid() )
return false;
240 if( !( message.
meta.
memo_key == signer ) )
return false;
242 "Message was signed by contained key, but it doesn't belong to the contained account!" );
249 static string meta_extract(
const string& meta,
const string& key )
251 FC_ASSERT( meta.size() > key.size(),
"Key '${k}' not found!", (
"k",key) );
253 if( meta.substr( 0, key.size() ) == key && meta[key.size()] ==
'=' )
257 start = meta.find(
"\n" + key +
"=" );
258 FC_ASSERT( start != string::npos,
"Key '${k}' not found!", (
"k",key) );
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 );
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?!" );
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 );
286 msg.
meta.
account = meta_extract( meta,
"account" );
288 msg.
meta.
block = boost::lexical_cast<uint32_t>( meta_extract( meta,
"block" ) );
289 msg.
meta.
time = meta_extract( meta,
"timestamp" );
308 tx.
set_expiration( now + parameters.maximum_time_until_expiration );
321 elog(
"Caught exception while broadcasting tx ${id}: ${e}",
323 FC_THROW(
"Caught exception while broadcasting tx" );
336 const vector<public_key_type>& signing_keys,
bool broadcast)
342 approving_key_set.insert(explicit_key);
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);
358 uint32_t expiration_time_offset = 0;
368 auto iter = _recently_generated_transactions.find(this_transaction_id);
369 if (iter == _recently_generated_transactions.end())
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);
380 ++expiration_time_offset;
391 elog(
"Caught exception while broadcasting tx ${id}: ${e}",
402 auto it =
_keys.find(
id);
413 if (active_keys.size() != 1)
414 FC_THROW(
"Expecting a simple authority with one active key");
425 if (!optional_private_key)
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()));
441 _keys[wif_pub_key] = wif_key;
447 return all_keys_for_account.find(wif_pub_key) != all_keys_for_account.end();
466 bool erase_existing_sigs )
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() ),
477 if ( erase_existing_sigs )
480 return _remote_db->get_required_signatures( tx, owned_keys );
virtual const transaction_id_type & id() const
bool import_key(string account_name_or_id, string wif_key)
boost::endian::little_uint32_buf_t _hash[5]
set< public_key_type > get_owned_required_keys(signed_transaction &tx, bool erase_existing_sigs=true)
memo_data sign_memo(string from, string to, string memo)
string address_to_shorthash(const graphene::protocol::address &addr)
dynamic_global_property_object get_dynamic_global_properties() const
unsigned aes_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, unsigned char *iv, unsigned char *ciphertext)
chain_parameters parameters
signed_transaction sign_transaction2(signed_transaction tx, const vector< public_key_type > &signing_keys=vector< public_key_type >(), bool broadcast=false)
microseconds minutes(int64_t m)
fc::time_point_sec expiration
void set_operation_fees(signed_transaction &tx, const fee_schedule &s) const
void pack(Stream &s, const flat_set< T, A... > &value, uint32_t _max_depth)
vector< operation > operations
public_key get_public_key() const
This class represents an account on the object graphAccounts are the primary unit of authority on the...
bool verify_message(const string &message, const string &account, int32_t block, const string &msg_time, const fc::ecc::compact_signature &sig)
signed_transaction add_transaction_signature(signed_transaction tx, bool broadcast)
fc::optional< fc::ecc::private_key > wif_to_key(const std::string &wif_key)
string read_memo(const memo_data &md)
flat_set< public_key_type > get_transaction_signers(const signed_transaction &tx) const
vector< string > key_approvals_to_remove
Used to generate a useful error report when an exception is thrown.At each level in the stack where t...
fc::optional< fc::ecc::compact_signature > signature
static sha512 hash(const char *d, uint32_t dlen)
std::string get_message(const fc::ecc::private_key &priv, const fc::ecc::public_key &pub) const
fc::ecc::private_key get_private_key_for_account(const account_object &account) const
void set_reference_block(const block_id_type &reference_block)
compact_signature sign_compact(const fc::sha256 &digest, bool require_canonical=true) const
fc::api< network_broadcast_api > _remote_net_broadcast
static sha256 hash(const char *d, uint32_t dlen)
provides stack-based nullable value similar to boost::optional
vector< string > owner_approvals_to_remove
fc::sha256 digest() const
vector< string > active_approvals_to_add
flat_set< public_key_type > key_approvals_to_remove
vector< string > active_approvals_to_remove
fc::ecc::private_key derive_private_key(const std::string &prefix_string, int sequence_number)
void set_expiration(fc::time_point_sec expiration_time)
signed_transaction approve_proposal(const string &fee_paying_account, const string &proposal_id, const approval_delta &delta, bool broadcast=false)
object_id< SpaceID, TypeID > get_id() const
fc::api< database_api > _remote_db
vector< public_key_type > get_keys() const
uint32_t ref_block_prefix
flat_set< account_id_type > active_approvals_to_remove
contains only the public point of an elliptic curve key.
microseconds seconds(int64_t s)
bool update_account(const account_object &acct)
flat_set< account_id_type > owner_approvals_to_remove
signed_transaction sign_transaction(signed_transaction tx, bool broadcast=false)
global_property_object get_global_properties() const
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.
account_id_type fee_paying_account
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
string name
The account's name. This name must be unique among all account names on the graph. May not be empty.
T as(uint32_t max_depth) const
adds a signature to a transaction
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
static private_key regenerate(const fc::sha256 &secret)
string normalize_brain_key(string s)
flat_set< public_key_type > key_approvals_to_add
std::string to_detail_string(log_level ll=log_level::all) const
graphene::db::object_downcast_t< const ID & > get_object(const ID &id) const
proposal_id_type proposal
std::string to_string(double)
void set_message(const fc::ecc::private_key &priv, const fc::ecc::public_key &pub, const string &msg, uint64_t custom_nonce=0)
The proposal_update_operation updates an existing transaction proposalThis operation allows accounts ...
virtual void validate() const
map< public_key_type, string > _keys
vector< char > cipher_keys
vector< string > owner_approvals_to_add
a 160 bit hash of a public key
signed_message sign_message(string signer, string message)
vector< string > key_approvals_to_add
void copy(const path &from, const path &to)
flat_set< account_id_type > owner_approvals_to_add
an elliptic curve private key.
map< account_id_type, set< public_key_type > > extra_keys
account_object get_account(account_id_type id) const
bool verify_encapsulated_message(const string &message)
const signature_type & sign(const private_key_type &key, const chain_id_type &chain_id)
fc::ecc::private_key get_private_key(const public_key_type &id) const
flat_set< account_id_type > active_approvals_to_add
bool verify_signed_message(const signed_message &message)
vector< signature_type > signatures
map< public_key_type, string > keys
defines the keys used to derive the shared secret