-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathmain.cpp
217 lines (151 loc) · 6.7 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#include "src/CmdLineOptions.h"
#include "src/tools.h"
#include "src/electrum-words.h"
#include "src/simple_account.h"
#include <iostream>
#include <string>
using namespace std;
using xmreg::operator<<;
namespace epee {
// without this it wont work. I'm not sure what it does.
// it has something to do with locking the blockchain and tx pool
// during certain operations to avoid deadlocks.
unsigned int g_test_dbg_lock_sleep = 0;
}
int main(int ac, const char* av[]) {
// get command line options
xmreg::CmdLineOptions opts {ac, av};
auto help_opt = opts.get_option<bool>("help");
// if help was chosen, display help text and finish
if (*help_opt)
{
return 0;
}
// default language for the mnemonic
// representation of the private spend key
string language {"English"};
// get 13 word mnemonic seed from MyMonero
auto mnemonic_opt = opts.get_option<string>("mnemonic");
auto wallet_file_opt = opts.get_option<string>("wallet-file");
auto password_opt = opts.get_option<string>("password");
// get the program command line options, or
// some default values for quick check
string mnemonic_str = mnemonic_opt
? *mnemonic_opt
: "slid otherwise jeers lurk swung tawny zodiac tusks twang cajun swagger peaches tawny";
// simplewallet wallet file name, e.g., mmwallet.bin
// actually we do not directy create this file. we
// create a file *.keys containing the address and the private keys
// the wallet file is going to be created by simplewallet after
// refresh to preserve the state of the wallet.
// we only need keys files to create the wallet.
string wallet_file = wallet_file_opt
? *wallet_file_opt
: xmreg::get_home_folder() + string("mmwallet.bin");
// name of the keys files
string keys_file_name = wallet_file + string(".keys");
string password = password_opt ? *password_opt : "password";
cout << "\n"
<< "Mnemonic seed : " << mnemonic_str << endl;
// change the MyMonero 13 word mnemonic seed
// to its 16 byte hexadecimal version
xmreg::secret_key16 hexadecimal_seed;
// use modified words_to_bytes function.
xmreg::ElectrumWords::words_to_bytes(mnemonic_str, hexadecimal_seed, language);
cout << "\n"
<< "Hexadecimal seed : " << hexadecimal_seed << endl;
// take the 16 byte hexadecimal_seed, and
// and perform Keccak hash on it. It will
// produce 32 byte hash.
crypto::hash hash_of_seed;
cn_fast_hash(hexadecimal_seed.data, sizeof(hexadecimal_seed.data), hash_of_seed);
cout << "\n"
<< "Hash of seed : " << hash_of_seed<< endl;
// having the hashed seed, we can proceed
// with generation of private and public spend keys.
// the keccak hash of the seed is used as a seed
// to generate the spend keys.
crypto::public_key public_spend_key;
crypto::secret_key private_spend_key;
crypto::generate_keys(public_spend_key, private_spend_key,
xmreg::get_key_from_hash<crypto::secret_key>(hash_of_seed),
true);
cout << "\n"
<< "Private spend key: " << private_spend_key << "\n"
<< "Public spend key : " << public_spend_key << endl;
// now we get private and public view keys.
// to do this, we keccak hash the hash_of_seed again
crypto::hash hash_of_hash;
cn_fast_hash(hash_of_seed.data, sizeof(hash_of_seed.data), hash_of_hash);
crypto::public_key public_view_key;
crypto::secret_key private_view_key;
crypto::generate_keys(public_view_key, private_view_key,
xmreg::get_key_from_hash<crypto::secret_key>(hash_of_hash),
true);
cout << "\n"
<< "Private view key : " << private_view_key << "\n"
<< "Public view key : " << public_view_key << endl;
// having all keys, we can get the corresponding monero address
cryptonote::account_public_address address {public_spend_key, public_view_key};
cout << "\n"
<< "Monero address : " << address << endl;
// Once we have all keys and address from the mnemonic seed
// we can proceed to generating wallet *.keys file
// that can be read by simplewallet
// we start this by creating instance of simple_account class
// and populate with the address, and private spend and view keys
// obtained in the previous steps
xmreg::simple_account account;
account.create_from_keys(address, private_spend_key, private_view_key);
std::string account_data;
if (!epee::serialization::store_t_to_binary(account, account_data))
{
cerr << "Something went wrong with serializing simple_account instance" << endl;
return 1;
}
rapidjson::Document json;
json.SetObject();
rapidjson::Value value(rapidjson::kStringType);
value.SetString(account_data.c_str(), account_data.length());
json.AddMember("key_data", value, json.GetAllocator());
tools::wallet2::keys_file_data keys_file_data
= boost::value_initialized<tools::wallet2::keys_file_data>();
// Serialize the JSON object
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
json.Accept(writer);
account_data = buffer.GetString();
// Encrypt the entire JSON object.
crypto::chacha8_key key;
crypto::generate_chacha8_key(password, key);
std::string cipher;
cipher.resize(account_data.size());
keys_file_data.iv = crypto::rand<crypto::chacha8_iv>();
crypto::chacha8(account_data.data(), account_data.size(),
key, keys_file_data.iv, &cipher[0]);
keys_file_data.account_data = cipher;
std::string buf;
// serialize key file data
if (!serialization::dump_binary(keys_file_data, buf))
{
cerr << "Something went wrong with serializing keys_file_data" << endl;
return 1;
}
// save serialized keys into the wallet file
if (!epee::file_io_utils::save_string_to_file(keys_file_name, buf))
{
cerr << "Something went wrong with writing file: " << keys_file_name << endl;
return 1;
}
cout << "\nKeys file \"" << keys_file_name << "\" created." << endl;
cout << "\nStart monero-wallet-cli using: \n"
<< "/opt/monero/monero-wallet-cli --wallet-file " << wallet_file
<< endl;
cout << "\nPassord given is: \"" << password <<"\"" << endl;
cout << "\nUse 'refresh' command in the monero-wallet-cli "
"to scan the blockchain "
"for your transactions. "
<< endl;
cout << "\nEnd of program." << endl;
return 0;
}