1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-03-09 15:40:10 +00:00

updated smartcontract code

updated lite-client and configuration smartcontract
updated tonlib code
This commit is contained in:
ton 2019-09-16 12:06:04 +04:00
parent 8e5bd938aa
commit bce33f588a
46 changed files with 677 additions and 299 deletions

View file

@ -132,6 +132,12 @@ TEST(Tonlib, TestGiver) {
vm::CellSlice(vm::NoVm(), res).print_rec(std::cerr);
CHECK(vm::std_boc_deserialize(wallet_query).move_as_ok()->get_hash() == res->get_hash());
}
TEST(Tonlib, PublicKey) {
block::PublicKey::parse("pubjns2gp7DGCnEH7EOWeCnb6Lw1akm538YYaz6sdLVHfRB2").ensure_error();
auto key = block::PublicKey::parse("Pubjns2gp7DGCnEH7EOWeCnb6Lw1akm538YYaz6sdLVHfRB2").move_as_ok();
CHECK(td::buffer_to_hex(key.key) == "3EE9DC0A7A0B6CA01770CE34698792BD8ECB53A6949BFD6C81B6E3CA475B74D7");
CHECK(key.serialize() == "Pubjns2gp7DGCnEH7EOWeCnb6Lw1akm538YYaz6sdLVHfRB2");
}
TEST(Tonlib, Address) {
auto a = block::StdAddress::parse("-1:538fa7cc24ff8eaa101d84a5f1ab7e832fe1d84b309cdfef4ee94373aac80f7d").move_as_ok();
@ -287,12 +293,14 @@ TEST(Tonlib, KeysApi) {
auto local_password = td::SecureString("local password");
auto mnemonic_password = td::SecureString("mnemonic password");
{
auto key = sync_send(client, make_object<tonlib_api::createNewKey>(local_password.copy(), td::SecureString{}))
auto key = sync_send(client, make_object<tonlib_api::createNewKey>(local_password.copy(), td::SecureString{},
td::SecureString{}))
.move_as_ok();
}
//createNewKey local_password:bytes mnemonic_password:bytes = Key;
auto key = sync_send(client, make_object<tonlib_api::createNewKey>(local_password.copy(), mnemonic_password.copy()))
auto key = sync_send(client, make_object<tonlib_api::createNewKey>(local_password.copy(), mnemonic_password.copy(),
td::SecureString{}))
.move_as_ok();
sync_send(client, make_object<tonlib_api::exportKey>(make_object<tonlib_api::inputKey>(

View file

@ -126,9 +126,9 @@ void transfer_grams(Client& client, std::string from, std::string to, td::int64
}
Wallet create_empty_wallet(Client& client) {
using tonlib_api::make_object;
auto key =
sync_send(client, make_object<tonlib_api::createNewKey>(td::SecureString("local"), td::SecureString("mnemonic")))
.move_as_ok();
auto key = sync_send(client, make_object<tonlib_api::createNewKey>(td::SecureString("local"),
td::SecureString("mnemonic"), td::SecureString()))
.move_as_ok();
Wallet wallet{"", {key->public_key_, std::move(key->secret_)}};
auto account_address =
@ -210,8 +210,8 @@ int main(int argc, char* argv[]) {
// init
sync_send(client, make_object<tonlib_api::init>(make_object<tonlib_api::options>(global_config_str, "."))).ensure();
auto key = sync_send(client,
make_object<tonlib_api::createNewKey>(td::SecureString("local"), td::SecureString("mnemonic")))
auto key = sync_send(client, make_object<tonlib_api::createNewKey>(
td::SecureString("local"), td::SecureString("mnemonic"), td::SecureString()))
.move_as_ok();
auto create_input_key = [&] {

View file

@ -63,9 +63,11 @@ td::Result<KeyStorage::Key> KeyStorage::save_key(const DecryptedKey &decrypted_k
return std::move(res);
}
td::Result<KeyStorage::Key> KeyStorage::create_new_key(td::Slice local_password, td::Slice mnemonic_password) {
td::Result<KeyStorage::Key> KeyStorage::create_new_key(td::Slice local_password, td::Slice mnemonic_password,
td::Slice entropy) {
Mnemonic::Options create_options;
create_options.password = td::SecureString(mnemonic_password);
create_options.entropy = td::SecureString(entropy);
TRY_RESULT(mnemonic, Mnemonic::create_new(std::move(create_options)));
return save_key(DecryptedKey(std::move(mnemonic)), local_password);

View file

@ -50,7 +50,7 @@ class KeyStorage {
td::Status set_directory(std::string directory);
td::Result<Key> create_new_key(td::Slice local_password, td::Slice key_password);
td::Result<Key> create_new_key(td::Slice local_password, td::Slice key_password, td::Slice entropy);
td::Result<ExportedKey> export_key(InputKey input_key);
td::Result<ExportedPemKey> export_pem_key(InputKey input_key, td::Slice key_password);

View file

@ -24,6 +24,7 @@
#include "tonlib/TestWallet.h"
#include "tonlib/TestGiver.h"
#include "tonlib/utils.h"
#include "tonlib/keys/Mnemonic.h"
#include "auto/tl/tonlib_api.hpp"
#include "block/block-auto.h"
@ -350,6 +351,7 @@ bool TonlibClient::is_static_request(td::int32 id) {
case tonlib_api::raw_getAccountAddress::ID:
case tonlib_api::testWallet_getAccountAddress::ID:
case tonlib_api::testGiver_getAccountAddress::ID:
case tonlib_api::getBip39Hints::ID:
return true;
default:
return false;
@ -405,6 +407,11 @@ tonlib_api::object_ptr<tonlib_api::Object> TonlibClient::do_static_request(
return tonlib_api::make_object<tonlib_api::accountAddress>(TestGiver::address().rserialize());
}
tonlib_api::object_ptr<tonlib_api::Object> TonlibClient::do_static_request(tonlib_api::getBip39Hints& request) {
return tonlib_api::make_object<tonlib_api::bip39Hints>(
td::transform(Mnemonic::word_hints(td::trim(td::to_lower_inplace(request.prefix_))), [](auto& x) { return x; }));
}
td::Status TonlibClient::do_request(const tonlib_api::init& request,
td::Promise<object_ptr<tonlib_api::ok>>&& promise) {
if (state_ != State::Uninited) {
@ -900,8 +907,8 @@ td::Status TonlibClient::do_request(tonlib_api::generic_sendGrams& request,
td::Status TonlibClient::do_request(const tonlib_api::createNewKey& request,
td::Promise<object_ptr<tonlib_api::key>>&& promise) {
TRY_RESULT(key,
key_storage_.create_new_key(std::move(request.local_password_), std::move(request.mnemonic_password_)));
TRY_RESULT(key, key_storage_.create_new_key(std::move(request.local_password_), std::move(request.mnemonic_password_),
std::move(request.random_extra_seed_)));
promise.set_value(tonlib_api::make_object<tonlib_api::key>(key.public_key.as_slice().str(), std::move(key.secret)));
return td::Status::OK();
}

View file

@ -79,6 +79,7 @@ class TonlibClient : public td::actor::Actor {
static object_ptr<tonlib_api::Object> do_static_request(const tonlib_api::raw_getAccountAddress& request);
static object_ptr<tonlib_api::Object> do_static_request(const tonlib_api::testWallet_getAccountAddress& request);
static object_ptr<tonlib_api::Object> do_static_request(const tonlib_api::testGiver_getAccountAddress& request);
static object_ptr<tonlib_api::Object> do_static_request(tonlib_api::getBip39Hints& request);
template <class T, class P>
td::Status do_request(const T& request, P&& promise) {
return td::Status::Error(400, "Function is unsupported");

View file

@ -28,9 +28,12 @@
#include "td/utils/Span.h"
#include "td/utils/misc.h"
#include "td/utils/optional.h"
#include "td/utils/Timer.h"
#include "crypto/Ed25519.h"
#include <algorithm>
namespace tonlib {
td::Result<Mnemonic> Mnemonic::create(td::SecureString words, td::SecureString password) {
return create_from_normalized(normalize_and_split(std::move(words)), std::move(password));
@ -133,7 +136,28 @@ td::SecureString Mnemonic::join(td::Span<td::SecureString> words) {
return res;
}
td::Span<std::string> Mnemonic::word_hints(td::Slice prefix) {
static std::vector<std::string> words = [] {
auto bip_words = Mnemonic::normalize_and_split(td::SecureString(bip39_english()));
std::vector<std::string> res;
for (auto &word : bip_words) {
res.push_back(word.as_slice().str());
}
return res;
}();
if (prefix.empty()) {
return words;
}
auto p = std::equal_range(words.begin(), words.end(), prefix, [&](td::Slice a, td::Slice b) {
return a.truncate(prefix.size()) < b.truncate(prefix.size());
});
return td::Span<std::string>(&*p.first, p.second - p.first);
}
td::Result<Mnemonic> Mnemonic::create_new(Options options) {
td::Timer timer;
if (options.words_count == 0) {
options.words_count = 24;
}
@ -146,14 +170,28 @@ td::Result<Mnemonic> Mnemonic::create_new(Options options) {
max_iterations *= 256;
}
td::Random::add_seed(options.entropy.as_slice());
SCOPE_EXIT {
td::Random::secure_cleanup();
};
auto bip_words = Mnemonic::normalize_and_split(td::SecureString(bip39_english()));
CHECK(bip_words.size() == 2048);
int A = 0, B = 0, C = 0;
for (int iteration = 0; iteration < max_iterations; iteration++) {
std::vector<td::SecureString> words;
td::SecureString rnd((options.words_count * 11 + 7) / 8);
td::Random::secure_bytes(rnd.as_mutable_slice());
for (int i = 0; i < options.words_count; i++) {
words.push_back(bip_words[td::Random::secure_int32() & 2047].copy());
size_t word_i = 0;
for (size_t j = 0; j < 11; j++) {
size_t offset = i * 11 + j;
if ((rnd[offset / 8] & (1 << (offset & 7))) != 0) {
word_i |= 1 << j;
}
}
words.push_back(bip_words[word_i].copy());
}
bool has_password = !options.password.empty();
@ -180,7 +218,7 @@ td::Result<Mnemonic> Mnemonic::create_new(Options options) {
continue;
}
LOG(INFO) << "Mnemonic generation debug stats: " << A << " " << B << " " << C;
LOG(INFO) << "Mnemonic generation debug stats: " << A << " " << B << " " << C << " " << timer;
return std::move(mnemonic);
}
return td::Status::Error("Failed to create a mnemonic (should not happen)");

View file

@ -36,6 +36,7 @@ class Mnemonic {
}
int words_count = 24;
td::SecureString password;
td::SecureString entropy;
};
static td::Result<Mnemonic> create_new(Options options = {});
@ -51,6 +52,7 @@ class Mnemonic {
std::vector<td::SecureString> get_words() const;
static std::vector<td::SecureString> normalize_and_split(td::SecureString words);
static td::Span<std::string> word_hints(td::Slice prefix);
private:
std::vector<td::SecureString> words_;

View file

@ -18,7 +18,8 @@
*/
#pragma once
#include "td/utils/Slice.h"
#include "td/utils/Span.h"
namespace tonlib {
td::CSlice bip39_english();
}
} // namespace tonlib

View file

@ -152,6 +152,8 @@ class TonlibCli : public td::actor::Actor {
auto to = parser.read_word();
auto grams = parser.read_word();
transfer(from, to, grams);
} else if (cmd == "hint") {
get_hints(parser.read_word());
}
}
@ -191,21 +193,27 @@ class TonlibCli : public td::actor::Actor {
};
}
void generate_key(std::string entropy = "") {
void generate_key(td::SecureString entropy = {}) {
if (entropy.size() < 20) {
td::TerminalIO::out() << "Enter some entropy";
cont_ = [this, entropy](td::Slice new_entropy) { generate_key(entropy + new_entropy.str()); };
cont_ = [this, entropy = std::move(entropy)](td::Slice new_entropy) {
td::SecureString res(entropy.size() + new_entropy.size());
res.as_mutable_slice().copy_from(entropy.as_slice());
res.as_mutable_slice().substr(entropy.size()).copy_from(new_entropy);
generate_key(std::move(res));
};
return;
}
td::TerminalIO::out() << "Enter password (could be empty)";
cont_ = [this, entropy](td::Slice password) { generate_key(std::move(entropy), td::SecureString(password)); };
cont_ = [this, entropy = std::move(entropy)](td::Slice password) mutable {
generate_key(std::move(entropy), td::SecureString(password));
};
}
void generate_key(std::string entropy, td::SecureString password) {
//TODO: use entropy
void generate_key(td::SecureString entropy, td::SecureString password) {
auto password_copy = password.copy();
send_query(tonlib_api::make_object<tonlib_api::createNewKey>(std::move(password_copy),
td::SecureString() /*mnemonic password*/),
send_query(tonlib_api::make_object<tonlib_api::createNewKey>(
std::move(password_copy), td::SecureString() /*mnemonic password*/, std::move(entropy)),
[this, password = std::move(password)](auto r_key) mutable {
if (r_key.is_error()) {
LOG(ERROR) << "Failed to create new key: " << r_key.error();
@ -542,6 +550,15 @@ class TonlibCli : public td::actor::Actor {
td::TerminalIO::out() << to_string(r_res.ok());
});
}
void get_hints(td::Slice prefix) {
using tonlib_api::make_object;
auto obj = tonlib::TonlibClient::static_request(make_object<tonlib_api::getBip39Hints>(prefix.str()));
if (obj->get_id() == tonlib_api::error::ID) {
return;
}
td::TerminalIO::out() << to_string(obj);
}
};
int main(int argc, char* argv[]) {