mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
change encryption state of crypto_keys
This commit is contained in:
parent
155f394500
commit
5862a61d59
@ -1,6 +1,6 @@
|
||||
CREATE TABLE `crypto_keys` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
`private_key` binary(80) NOT NULL,
|
||||
`private_key` varbinary(80) NOT NULL,
|
||||
`public_key` binary(32) NOT NULL,
|
||||
`crypto_key_type_id` int NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`),
|
||||
|
||||
@ -184,6 +184,7 @@ MemoryBin* KeyPairHedera::getCryptedPrivKey(const Poco::AutoPtr<SecretKeyCryptog
|
||||
|
||||
}
|
||||
|
||||
|
||||
MemoryBin* KeyPairHedera::getPrivateKeyCopy() const
|
||||
{
|
||||
if (!mPrivateKey) return nullptr;
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
#include "sodium.h"
|
||||
#include "SecretKeyCryptography.h"
|
||||
#include "iroha-ed25519/include/ed25519/ed25519.h"
|
||||
#include "../lib/DataTypeConverter.h"
|
||||
|
||||
class KeyPairHedera : public IKeyPair
|
||||
{
|
||||
@ -38,6 +39,7 @@ public:
|
||||
|
||||
inline const unsigned char* getPublicKey() const { return mPublicKey; }
|
||||
MemoryBin* getPublicKeyCopy() const;
|
||||
inline std::string getPublicKeyHex() const { return DataTypeConverter::binToHex(mPublicKey, getPublicKeySize()); }
|
||||
const static size_t getPublicKeySize() {return ed25519_pubkey_SIZE;}
|
||||
|
||||
inline bool isTheSame(const KeyPairHedera& b) const {
|
||||
@ -68,6 +70,7 @@ public:
|
||||
//! \brief
|
||||
MemoryBin* getCryptedPrivKey(const Poco::AutoPtr<SecretKeyCryptography> password) const;
|
||||
MemoryBin* getPrivateKeyCopy() const;
|
||||
inline std::string getPrivateKeyHex(const Poco::AutoPtr<SecretKeyCryptography> password) const { if (!mPrivateKey) return "0x0"; return DataTypeConverter::binToHex(mPrivateKey); }
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
@ -51,40 +51,58 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request
|
||||
Poco::URI uri(request.getURI());
|
||||
auto uri_query = uri.getQueryParameters();
|
||||
std::string action = "";
|
||||
std::string account_id_from_query;
|
||||
Poco::AutoPtr<controller::HederaAccount> query_hedera_account;
|
||||
|
||||
// parsing get query params
|
||||
if(uri_query.size() >= 2) {
|
||||
if(uri_query[0].first == "action") {
|
||||
action = uri_query[0].second;
|
||||
}
|
||||
if(uri_query[1].first == "account_id") {
|
||||
std::string account_id_from_query;
|
||||
int account_id = 0;
|
||||
account_id_from_query = uri_query[1].second;
|
||||
}
|
||||
}
|
||||
if(action == "updateBalance") {
|
||||
int account_id = 0;
|
||||
if(DataTypeConverter::strToInt(account_id_from_query, account_id) != DataTypeConverter::NUMBER_PARSE_OKAY) {
|
||||
addError(new Error("Int Convert Error", "Error converting account_id_from_query to int"));
|
||||
} else {
|
||||
auto hedera_account = controller::HederaAccount::load("id", account_id);
|
||||
if(!hedera_account.size() || hedera_account[0].isNull()) {
|
||||
addError(new Error("Action Update Balance", "hedera id not found"));
|
||||
if(DataTypeConverter::strToInt(account_id_from_query, account_id) != DataTypeConverter::NUMBER_PARSE_OKAY) {
|
||||
addError(new Error("Int Convert Error", "Error converting account_id_from_query to int"));
|
||||
} else {
|
||||
hedera_time.reset();
|
||||
hedera_account[0]->hederaAccountGetBalance(user, this);
|
||||
addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string()));
|
||||
auto hedera_accounts = controller::HederaAccount::load("id", account_id);
|
||||
if(!hedera_accounts.size() || hedera_accounts[0].isNull()) {
|
||||
addError(new Error("Action", "hedera account not found"));
|
||||
} else {
|
||||
query_hedera_account = hedera_accounts[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// add
|
||||
else if(!form.empty()) {
|
||||
// actions
|
||||
if(!query_hedera_account.isNull())
|
||||
{
|
||||
if(action == "updateBalance")
|
||||
{
|
||||
hedera_time.reset();
|
||||
query_hedera_account->hederaAccountGetBalance(user);
|
||||
addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string()));
|
||||
}
|
||||
else if(action == "changeEncryption")
|
||||
{
|
||||
if(query_hedera_account->changeEncryption(user)) {
|
||||
addNotification(new Success("Hedera Account", "success in changing encryption"));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(!form.empty()) // add
|
||||
{
|
||||
// collect
|
||||
auto shardNumString = form.get("account-shard-num", "0");
|
||||
auto realmNumString = form.get("account-realm-num", "0");
|
||||
auto numString = form.get("account-num", "0");
|
||||
auto privateKeyString = form.get("account-private-key", "");
|
||||
auto privateKeyEncryptedString = form.get("account-private-key-encrypted", "false");
|
||||
auto publicKeyString = form.get("account-public-key", "");
|
||||
auto networkTypeString = form.get("account-network-type", "0");
|
||||
|
||||
//printf("private key encrypted: %s\n", privateKeyEncryptedString.data());
|
||||
|
||||
int shardNum = 0;
|
||||
int realmNum = 0;
|
||||
int num = 0;
|
||||
@ -144,7 +162,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request
|
||||
auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE);
|
||||
|
||||
if(crypto_key.isNull()) {
|
||||
crypto_key = controller::CryptoKey::create(&key_pair, user);
|
||||
crypto_key = controller::CryptoKey::create(&key_pair, user, privateKeyEncryptedString == "true");
|
||||
if(!crypto_key->getModel()->insertIntoDB(true)) {
|
||||
addError(new Error("DB Error", "Error saving crypto key in DB"));
|
||||
}
|
||||
@ -152,15 +170,26 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request
|
||||
printf("crypto key found in db\n");
|
||||
}
|
||||
if(0 == errorCount()) {
|
||||
auto hedera_account = controller::HederaAccount::create(
|
||||
user->getModel()->getID(),
|
||||
hedera_id->getModel()->getID(),
|
||||
crypto_key->getModel()->getID(),
|
||||
0,
|
||||
(model::table::HederaNetworkType)networkType
|
||||
);
|
||||
if(!hedera_account->getModel()->insertIntoDB(false)) {
|
||||
addError(new Error("DB Error", "Error saving hedera account into DB"));
|
||||
|
||||
if(hedera_id->isExistInDB()) {
|
||||
auto hedera_account = controller::HederaAccount::load(hedera_id);
|
||||
if(hedera_account.isNull()) {
|
||||
addError(new Error("DB Error", "Couldn't load hedera account from db, but it should exist"));
|
||||
} else {
|
||||
addError(new Error("Hedera Account", "Account already exist (same account id"));
|
||||
}
|
||||
|
||||
} else {
|
||||
auto hedera_account = controller::HederaAccount::create(
|
||||
user->getModel()->getID(),
|
||||
hedera_id->getModel()->getID(),
|
||||
crypto_key->getModel()->getID(),
|
||||
0,
|
||||
(model::table::HederaNetworkType)networkType
|
||||
);
|
||||
if(!hedera_account->getModel()->insertIntoDB(false)) {
|
||||
addError(new Error("DB Error", "Error saving hedera account into DB"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -169,7 +198,9 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(!query_hedera_account.isNull()) {
|
||||
getErrors(query_hedera_account);
|
||||
}
|
||||
// list accounts
|
||||
auto hedera_accounts = controller::HederaAccount::load("user_id", user->getModel()->getID());
|
||||
|
||||
@ -231,7 +262,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request
|
||||
responseStream << "\t\t<div class=\"content\">";
|
||||
// end include header_large.cpsp
|
||||
responseStream << "\n";
|
||||
#line 156 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
#line 187 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
responseStream << ( getErrorsHtml() );
|
||||
responseStream << "\n";
|
||||
responseStream << "<div class=\"center-form-container\">\n";
|
||||
@ -244,41 +275,63 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request
|
||||
responseStream << "\t\t\t\t<div class=\"cell header-cell c2\">Hedera Id</div>\t\t\t\n";
|
||||
responseStream << "\t\t\t\t<div class=\"cell header-cell c3\">Balance</div>\n";
|
||||
responseStream << "\t\t\t\t<div class=\"cell header-cell c2\">Server Type</div>\n";
|
||||
responseStream << "\t\t\t\t<div class=\"cell header-cell c3\">Verschlüsselt?</div>\n";
|
||||
responseStream << "\t\t\t\t<div class=\"cell header-cell c3\">Last Updated</div>\n";
|
||||
responseStream << "\t\t\t\t<div class=\"cell header-cell c5\">Aktionen</div>\n";
|
||||
responseStream << "\t\t\t</div>\n";
|
||||
responseStream << "\t\t\t";
|
||||
#line 171 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
#line 203 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) {
|
||||
auto hedera_account_model = (*it)->getModel();
|
||||
auto updateUrl = ServerConfig::g_serverPath + "/hedera_account?action=updateBalance&account_id=" + std::to_string(hedera_account_model->getID());
|
||||
std::string changeEncryption("");
|
||||
if(hedera_account_model->getUserId() == user->getModel()->getID()) {
|
||||
changeEncryption = ServerConfig::g_serverPath + "/hedera_account?action=changeEncryption&account_id=" + std::to_string(hedera_account_model->getID());
|
||||
}
|
||||
//printf("change encryption: %s\n", changeEncryption.data());
|
||||
responseStream << "\n";
|
||||
responseStream << "\t\t\t\t<div class=\"row\">\n";
|
||||
responseStream << "\t\t\t\t\t<div class=\"cell c2\">";
|
||||
#line 176 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
#line 213 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
responseStream << ( (*it)->getHederaId()->getModel()->toString() );
|
||||
responseStream << "</div>\n";
|
||||
responseStream << "\t\t\t\t\t<div class=\"cell c3\">";
|
||||
#line 177 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
#line 214 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
responseStream << ( hedera_account_model->getBalanceDouble() );
|
||||
responseStream << " hbar</div>\n";
|
||||
responseStream << "\t\t\t\t\t<div class=\"cell c2\">";
|
||||
#line 178 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
#line 215 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
responseStream << ( model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) );
|
||||
responseStream << "</div>\n";
|
||||
responseStream << "\t\t\t\t\t<div class=\"cell c3\">";
|
||||
#line 179 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
#line 216 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
responseStream << ( (*it)->getCryptoKey()->getModel()->isEncrypted() ? "Ja": "Nein" );
|
||||
responseStream << "</div>\n";
|
||||
responseStream << "\t\t\t\t\t<div class=\"cell c3\">";
|
||||
#line 217 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
responseStream << ( hedera_account_model->getUpdatedString() );
|
||||
responseStream << "</div>\n";
|
||||
responseStream << "\t\t\t\t\t<button class=\"form-button\" title=\"Anfrage an Hedera, kostet etwas\" onclick=\"window.location.href='";
|
||||
#line 180 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
responseStream << "\t\t\t\t\t<button class=\"form-button\" title=\"Anfrage an Hedera, aktuell kostenlos\" onclick=\"window.location.href='";
|
||||
#line 218 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
responseStream << ( updateUrl );
|
||||
responseStream << "'\" >\n";
|
||||
responseStream << "\t\t\t\t\t\tUpdate Balance\n";
|
||||
responseStream << "\t\t\t\t\t</button>\n";
|
||||
responseStream << "\t\t\t\t\t";
|
||||
#line 221 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
if(changeEncryption != "") { responseStream << "\n";
|
||||
responseStream << "\t\t\t\t\t\t<button class=\"form-button\" title=\"Ändere den Verschlüsselungsstatus des Private Keys in der Datenbank\" onclick=\"window.location.href='";
|
||||
#line 222 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
responseStream << ( changeEncryption );
|
||||
responseStream << "'\">\n";
|
||||
responseStream << "\t\t\t\t\t\t\tChange Encryption\n";
|
||||
responseStream << "\t\t\t\t\t\t</button>\n";
|
||||
responseStream << "\t\t\t\t\t";
|
||||
#line 225 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
} responseStream << "\n";
|
||||
responseStream << "\t\t\t\t</div>\n";
|
||||
responseStream << "\t\t\t";
|
||||
#line 184 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
#line 227 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
} responseStream << "\n";
|
||||
responseStream << "\t\t</div>\n";
|
||||
responseStream << "\t</div>\n";
|
||||
@ -287,7 +340,7 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request
|
||||
responseStream << "\t</div>\n";
|
||||
responseStream << "\t<div class=\"center-form-form\">\n";
|
||||
responseStream << "\t\t<form method=\"POST\" action=\"";
|
||||
#line 191 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
#line 234 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
responseStream << ( ServerConfig::g_serverPath );
|
||||
responseStream << "/hedera_account\">\n";
|
||||
responseStream << "\t\t\t<label class=\"form-label\">Hedera Account ID</label>\n";
|
||||
@ -296,26 +349,28 @@ void AdminHederaAccountPage::handleRequest(Poco::Net::HTTPServerRequest& request
|
||||
responseStream << "\t\t\t<input class=\"form-control\" id=\"account-num\" placeholder=\"num\" type=\"number\" name=\"account-num\"/>\n";
|
||||
responseStream << "\t\t\t<label class=\"form-label\" for=\"account-private-key\">Private Key</label>\n";
|
||||
responseStream << "\t\t\t<input class=\"form-control\" id=\"account-private-key\" type=\"text\" name=\"account-private-key\"/>\n";
|
||||
responseStream << "\t\t\t<label class=\"form-label\" for=\"account-private-key-encrypted\" title=\"Wenn er verschlüsselt ist, kannst nur du Hedera Transaktionen damit bezahlen, wenn er nicht verschlüsselt ist kann er für alle Hedera Transaktionen automatisch verwendet werden. Ich empfehle dafür ein separates Konto mit wenigen Hashbars anzulegen.\">Private Key verschlüsseln?</label>\n";
|
||||
responseStream << "\t\t\t<input class=\"form-control\" id=\"account-private-key-encrypted\" type=\"checkbox\" name=\"account-private-key-encrypted\" value=\"true\"/>\n";
|
||||
responseStream << "\t\t\t<label class=\"form-label\" for=\"account-public-key\">Public Key</label>\n";
|
||||
responseStream << "\t\t\t<input class=\"form-control\" id=\"account-public-key\" type=\"text\" name=\"account-public-key\"/>\n";
|
||||
responseStream << "\t\t\t<label class=\"form-label\" for=\"account-network-type\">Network Type</label>\n";
|
||||
responseStream << "\t\t\t<select class=\"form-control\" name=\"account-network-type\" id=\"account-network-type\">\n";
|
||||
responseStream << "\t\t\t";
|
||||
#line 202 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
#line 247 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
for(int i = 0; i < model::table::HEDERA_NET_COUNT; i++) { responseStream << "\n";
|
||||
responseStream << "\t\t\t\t<option value=\"";
|
||||
#line 203 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
#line 248 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
responseStream << ( i );
|
||||
responseStream << "\">";
|
||||
#line 203 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
#line 248 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
responseStream << ( model::table::HederaAccount::hederaNetworkTypeToString((model::table::HederaNetworkType)i) );
|
||||
responseStream << "</option>\n";
|
||||
responseStream << "\t\t\t";
|
||||
#line 204 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
#line 249 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
} responseStream << "\n";
|
||||
responseStream << "\t\t\t</select>\n";
|
||||
responseStream << "\t\t\t<input class=\"center-form-submit form-button\" type=\"submit\" name=\"submit\" value=\"";
|
||||
#line 206 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
#line 251 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminHederaAccount.cpsp"
|
||||
responseStream << ( gettext("Add Account") );
|
||||
responseStream << "\">\n";
|
||||
responseStream << "\t\t</form>\n";
|
||||
|
||||
@ -113,8 +113,38 @@ namespace controller {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
return std::make_unique<KeyPairHedera>(model->getPrivateKey(), model->getPublicKey(), model->getPublicKeySize());
|
||||
}
|
||||
|
||||
bool CryptoKey::changeEncryption(Poco::AutoPtr<controller::User> user)
|
||||
{
|
||||
auto key_pair = getKeyPair(user);
|
||||
if (!key_pair || !key_pair->hasPrivateKey()) {
|
||||
addError(new Error("Crypto Key", "key pair or private key was null"));
|
||||
return false;
|
||||
}
|
||||
auto model = getModel();
|
||||
auto mm = MemoryManager::getInstance();
|
||||
// update key type
|
||||
model->changeKeyTypeToggleEncrypted();
|
||||
MemoryBin* private_key = nullptr;
|
||||
if (model->isEncrypted()) {
|
||||
private_key = key_pair->getCryptedPrivKey(user->getPassword());
|
||||
}
|
||||
else {
|
||||
private_key = key_pair->getPrivateKeyCopy();
|
||||
}
|
||||
if (!private_key) {
|
||||
addError(new Error("Crypto Key", " private_key not get"));
|
||||
return false;
|
||||
}
|
||||
model->setPrivateKey(private_key);
|
||||
// save changes into db
|
||||
model->updatePrivkeyAndKeyType();
|
||||
|
||||
mm->releaseMemory(private_key);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -9,9 +9,15 @@
|
||||
#include "TableControllerBase.h"
|
||||
#include "User.h"
|
||||
|
||||
|
||||
|
||||
namespace controller {
|
||||
class CryptoKey : public TableControllerBase
|
||||
|
||||
class HederaAccount;
|
||||
|
||||
class CryptoKey : public TableControllerBase, public NotificationList
|
||||
{
|
||||
friend HederaAccount;
|
||||
public:
|
||||
|
||||
~CryptoKey();
|
||||
@ -31,8 +37,11 @@ namespace controller {
|
||||
std::unique_ptr<KeyPairHedera> getKeyPair(Poco::AutoPtr<controller::User> user) const;
|
||||
std::unique_ptr<KeyPairHedera> getKeyPair() const;
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
bool changeEncryption(Poco::AutoPtr<controller::User> user);
|
||||
CryptoKey(model::table::CryptoKey* dbModel);
|
||||
|
||||
};
|
||||
|
||||
@ -40,6 +40,20 @@ namespace controller {
|
||||
return resultVector;
|
||||
}
|
||||
|
||||
Poco::AutoPtr<HederaAccount> HederaAccount::load(Poco::AutoPtr<controller::HederaId> hederaId)
|
||||
{
|
||||
if (!hederaId->isExistInDB()) return nullptr;
|
||||
|
||||
auto db = new model::table::HederaAccount();
|
||||
auto result_count = db->loadFromDB("account_hedera_id", hederaId->getModel()->getID());
|
||||
if (1 == result_count) {
|
||||
return new HederaAccount(db);
|
||||
}
|
||||
// maybe change later to using error manager and send email
|
||||
printf("[HederaAccount::load] result_count not expected: %d\n", result_count);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<Poco::AutoPtr<HederaAccount>> HederaAccount::listAll()
|
||||
{
|
||||
auto db = new model::table::HederaAccount();
|
||||
@ -73,7 +87,13 @@ namespace controller {
|
||||
return resultVector;
|
||||
}
|
||||
|
||||
bool HederaAccount::hederaAccountGetBalance(Poco::AutoPtr<controller::User> user, NotificationList* errorReceiver/* = nullptr*/)
|
||||
Poco::AutoPtr<controller::CryptoKey> HederaAccount::getCryptoKey() const
|
||||
{
|
||||
auto model = getModel();
|
||||
return controller::CryptoKey::load(model->getCryptoKeyId());
|
||||
}
|
||||
|
||||
bool HederaAccount::hederaAccountGetBalance(Poco::AutoPtr<controller::User> user)
|
||||
{
|
||||
static const char* functionName = "HederaAccount::updateBalanceFromHedera";
|
||||
|
||||
@ -86,13 +106,13 @@ namespace controller {
|
||||
auto hedera_node = NodeServer::pick(account_model->networkTypeToNodeServerType(account_model->getNetworkType()));
|
||||
auto crypto_key = controller::CryptoKey::load(account_model->getCryptoKeyId());
|
||||
if (crypto_key.isNull()) {
|
||||
if (errorReceiver) { errorReceiver->addError(new Error("Keys", "could not found crypto key for account"));}
|
||||
else { printf("[%s] error, crypto key with id: %d not found\n", functionName, account_model->getCryptoKeyId()); }
|
||||
addError(new Error("Keys", "could not found crypto key for account"));
|
||||
printf("[%s] error, crypto key with id: %d not found\n", functionName, account_model->getCryptoKeyId());
|
||||
return false;
|
||||
}
|
||||
auto hedera_key_pair = crypto_key->getKeyPair(user);
|
||||
if (!hedera_key_pair) {
|
||||
if (errorReceiver) { errorReceiver->addError(new Error("Keys", "error decrypting private key"));}
|
||||
addError(new Error("Keys", "error decrypting private key"));
|
||||
printf("[%s] error decrypting private key with id: %d, with user: %d\n", functionName, account_model->getCryptoKeyId(), user->getModel()->getID());
|
||||
return false;
|
||||
}
|
||||
@ -111,13 +131,8 @@ namespace controller {
|
||||
account_model->updateIntoDB("balance", response.getAccountBalance());
|
||||
}
|
||||
else {
|
||||
if (errorReceiver) {
|
||||
errorReceiver->addError(new Error("Hedera", "Hedera request failed"));
|
||||
errorReceiver->addError(new ParamError("Hedera", "Hedera Response Code", proto::ResponseCodeEnum_Name(response.getResponseCode())));
|
||||
}
|
||||
else {
|
||||
printf("[%s] hedera response code: %s\n", functionName, proto::ResponseCodeEnum_Name(response.getResponseCode()).data());
|
||||
}
|
||||
addError(new Error("Hedera", "Hedera request failed"));
|
||||
addError(new ParamError("Hedera", "Hedera Response Code", proto::ResponseCodeEnum_Name(response.getResponseCode())));
|
||||
}
|
||||
//request.requestViaPHPRelay(query);
|
||||
}
|
||||
@ -125,13 +140,32 @@ namespace controller {
|
||||
printf("[HederaAccount::updateBalanceFromHedera] exception calling hedera request: %s\n", ex.displayText().data());
|
||||
}
|
||||
|
||||
if (errorReceiver) {
|
||||
errorReceiver->getErrors(&request);
|
||||
}
|
||||
getErrors(&request);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HederaAccount::changeEncryption(Poco::AutoPtr<controller::User> user)
|
||||
{
|
||||
assert(!user.isNull() && user->getModel());
|
||||
auto model = getModel();
|
||||
assert(!model.isNull());
|
||||
|
||||
if (user->getModel()->getID() != model->getUserId()) {
|
||||
addError(new Error("Hedera Account", "wrong user"));
|
||||
return false;
|
||||
}
|
||||
auto crypto_key = controller::CryptoKey::load(model->getCryptoKeyId());
|
||||
if (crypto_key.isNull()) {
|
||||
addError(new Error("Hedera Account", "couldn't find crypto key"));
|
||||
return false;
|
||||
}
|
||||
bool result = crypto_key->changeEncryption(user);
|
||||
getErrors(crypto_key);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
std::string HederaAccount::toShortSelectOptionName()
|
||||
{
|
||||
|
||||
@ -8,9 +8,10 @@
|
||||
#include "Poco/SharedPtr.h"
|
||||
|
||||
#include "TableControllerBase.h"
|
||||
#include "CryptoKey.h"
|
||||
|
||||
namespace controller {
|
||||
class HederaAccount : public TableControllerBase
|
||||
class HederaAccount : public TableControllerBase, public NotificationList
|
||||
{
|
||||
public:
|
||||
~HederaAccount();
|
||||
@ -18,6 +19,7 @@ namespace controller {
|
||||
static Poco::AutoPtr<HederaAccount> create(int user_id, int account_hedera_id, int account_key_id, Poco::UInt64 balance = 0, model::table::HederaNetworkType type = model::table::HEDERA_MAINNET);
|
||||
|
||||
static std::vector<Poco::AutoPtr<HederaAccount>> load(const std::string& fieldName, int fieldValue);
|
||||
static Poco::AutoPtr<HederaAccount> load(Poco::AutoPtr<controller::HederaId> hederaId);
|
||||
static std::vector<Poco::AutoPtr<HederaAccount>> listAll();
|
||||
|
||||
inline bool deleteFromDB() { return mDBModel->deleteFromDB(); }
|
||||
@ -25,11 +27,15 @@ namespace controller {
|
||||
std::string HederaAccount::toShortSelectOptionName();
|
||||
|
||||
inline Poco::AutoPtr<model::table::HederaAccount> getModel() { return _getModel<model::table::HederaAccount>(); }
|
||||
inline const model::table::HederaAccount* getModel() const { return _getModel<model::table::HederaAccount>(); }
|
||||
|
||||
inline void setHederaId(Poco::AutoPtr<controller::HederaId> hederaId) { mHederaID = hederaId; }
|
||||
inline Poco::AutoPtr<controller::HederaId> getHederaId() { return mHederaID; }
|
||||
|
||||
bool hederaAccountGetBalance(Poco::AutoPtr<controller::User> user, NotificationList* errorReceiver = nullptr);
|
||||
Poco::AutoPtr<controller::CryptoKey> getCryptoKey() const;
|
||||
|
||||
bool hederaAccountGetBalance(Poco::AutoPtr<controller::User> user);
|
||||
bool changeEncryption(Poco::AutoPtr<controller::User> user);
|
||||
|
||||
protected:
|
||||
HederaAccount(model::table::HederaAccount* dbModel);
|
||||
|
||||
@ -37,4 +37,14 @@ namespace controller {
|
||||
protoAccountId->set_realmnum(model->getRealmNum());
|
||||
protoAccountId->set_accountnum(model->getNum());
|
||||
}
|
||||
|
||||
bool HederaId::isExistInDB()
|
||||
{
|
||||
auto model = getModel();
|
||||
if (model->getID() > 0) return true;
|
||||
//std::vector<Tuple> loadFromDB(const std::vector<std::string>& fieldNames, const std::vector<WhereFieldType>& fieldValues, MysqlConditionType conditionType = MYSQL_CONDITION_AND, int expectedResults = 0);
|
||||
model->isExistInDB();
|
||||
return model->getID() != 0;
|
||||
|
||||
}
|
||||
}
|
||||
@ -20,6 +20,8 @@ namespace controller {
|
||||
|
||||
static Poco::AutoPtr<HederaId> load(int id);
|
||||
|
||||
bool isExistInDB();
|
||||
|
||||
inline bool deleteFromDB() { return mDBModel->deleteFromDB(); }
|
||||
|
||||
inline Poco::AutoPtr<model::table::HederaId> getModel() { return _getModel<model::table::HederaId>(); }
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#include "CryptoKey.h"
|
||||
#include "../../lib/DataTypeConverter.h"
|
||||
|
||||
using namespace Poco::Data::Keywords;
|
||||
|
||||
namespace model {
|
||||
@ -51,6 +51,8 @@ namespace model {
|
||||
return "<unknown type>";
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CryptoKey::hasPrivateKeyEncrypted() const
|
||||
{
|
||||
const KeyType type = (KeyType)(mKeyType);
|
||||
@ -70,6 +72,39 @@ namespace model {
|
||||
return false;
|
||||
}
|
||||
|
||||
void CryptoKey::setPrivateKey(const MemoryBin* privateKey)
|
||||
{
|
||||
if (!privateKey) {
|
||||
mPrivateKey = Poco::Nullable<Poco::Data::BLOB>();
|
||||
}
|
||||
else {
|
||||
mPrivateKey = Poco::Nullable<Poco::Data::BLOB>(Poco::Data::BLOB(*privateKey, privateKey->size()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool CryptoKey::changeKeyTypeToggleEncrypted()
|
||||
{
|
||||
const KeyType type = (KeyType)(mKeyType);
|
||||
if (type == KEY_TYPE_ED25519_SODIUM_ENCRYPTED) {
|
||||
mKeyType = KEY_TYPE_ED25519_SODIUM_CLEAR;
|
||||
return true;
|
||||
}
|
||||
if (type == KEY_TYPE_ED25519_HEDERA_ENCRYPTED) {
|
||||
mKeyType = KEY_TYPE_ED25519_HEDERA_CLEAR;
|
||||
return true;
|
||||
}
|
||||
if (type == KEY_TYPE_ED25519_SODIUM_CLEAR) {
|
||||
mKeyType = KEY_TYPE_ED25519_SODIUM_ENCRYPTED;
|
||||
return true;
|
||||
}
|
||||
if (type == KEY_TYPE_ED25519_HEDERA_CLEAR) {
|
||||
mKeyType = KEY_TYPE_ED25519_HEDERA_ENCRYPTED;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Poco::Data::Statement CryptoKey::_loadFromDB(Poco::Data::Session session, const std::string& fieldName)
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
@ -103,5 +138,33 @@ namespace model {
|
||||
unlock();
|
||||
return insert;
|
||||
}
|
||||
|
||||
size_t CryptoKey::updatePrivkeyAndKeyType()
|
||||
{
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
if (mPrivateKey.isNull() || !mID) {
|
||||
return 0;
|
||||
}
|
||||
auto cm = ConnectionManager::getInstance();
|
||||
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
||||
|
||||
Poco::Data::Statement update(session);
|
||||
|
||||
update << "UPDATE " << getTableName() << " SET private_key = ?, crypto_key_type_id = ? where id = ?;",
|
||||
use(mPrivateKey), use(mKeyType), use(mID);
|
||||
|
||||
|
||||
size_t resultCount = 0;
|
||||
try {
|
||||
return update.execute();
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
addError(new ParamError(getTableName(), "[updatePrivkeyAndKeyType] mysql error by update", ex.displayText().data()));
|
||||
addError(new ParamError(getTableName(), "data set: \n", toString().data()));
|
||||
}
|
||||
//printf("data valid: %s\n", toString().data());
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
#include "ModelBase.h"
|
||||
#include "Poco/Types.h"
|
||||
#include "../../lib/DataTypeConverter.h"
|
||||
|
||||
namespace model {
|
||||
namespace table {
|
||||
@ -27,13 +28,21 @@ namespace model {
|
||||
std::string toString();
|
||||
|
||||
inline const unsigned char* getPublicKey() const { if (mPublicKey.isNull()) return nullptr; return mPublicKey.value().content().data(); }
|
||||
inline std::string getPublicKeyHexString() const { return DataTypeConverter::binToHex(mPublicKey); };
|
||||
size_t getPublicKeySize() const { if (mPublicKey.isNull()) return 0; return mPublicKey.value().content().size(); }
|
||||
|
||||
bool hasPrivateKeyEncrypted() const;
|
||||
bool isEncrypted() const;
|
||||
bool changeKeyTypeToggleEncrypted();
|
||||
inline bool hasPrivateKey() const { return !mPrivateKey.isNull(); }
|
||||
inline const std::vector<unsigned char>& getPrivateKey() const { return mPrivateKey.value().content(); }
|
||||
|
||||
size_t updatePrivkeyAndKeyType();
|
||||
|
||||
//! \brief set encrypted private key
|
||||
//! \param privateKey copy data, didn't move memory bin
|
||||
void setPrivateKey(const MemoryBin* privateKey);
|
||||
|
||||
static const char* typeToString(KeyType type);
|
||||
protected:
|
||||
Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName);
|
||||
|
||||
@ -35,6 +35,7 @@ namespace model {
|
||||
|
||||
inline int getAccountHederaId() const { return mAccountHederaId; }
|
||||
inline int getCryptoKeyId() const { return mAccountKeyId; }
|
||||
inline int getUserId() const { return mUserId; }
|
||||
|
||||
inline Poco::UInt64 getBalance() { return mBalance; }
|
||||
inline double getBalanceDouble() { return (double)mBalance / 100000000.0; }
|
||||
|
||||
@ -55,6 +55,7 @@ namespace model {
|
||||
return mID;
|
||||
}
|
||||
|
||||
|
||||
Poco::Data::Statement HederaId::_loadFromDB(Poco::Data::Session session, const std::string& fieldName)
|
||||
{
|
||||
|
||||
|
||||
@ -78,6 +78,24 @@ namespace model {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ModelBase::isExistInDB()
|
||||
{
|
||||
auto cm = ConnectionManager::getInstance();
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
||||
|
||||
Poco::Data::Statement select = _loadIdFromDB(session);
|
||||
try {
|
||||
select.executeAsync();
|
||||
return select.wait() == 1;
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
addError(new ParamError(getTableName(), "mysql error by select id, check if exist in db", ex.displayText().data()));
|
||||
addError(new ParamError(getTableName(), "data set: ", toString().data()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ModelBase::deleteFromDB()
|
||||
{
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
|
||||
@ -40,6 +40,7 @@ namespace model {
|
||||
size_t loadFromDB(const std::string& fieldName, const T& fieldValue);
|
||||
template<class T>
|
||||
bool isExistInDB(const std::string& fieldName, const T& fieldValue);
|
||||
bool isExistInDB();
|
||||
template<class WhereFieldType, class Tuple>
|
||||
std::vector<Tuple> loadFromDB(const std::string& fieldName, const WhereFieldType& fieldValue, int expectedResults = 0);
|
||||
template<class Tuple>
|
||||
|
||||
@ -30,40 +30,58 @@
|
||||
Poco::URI uri(request.getURI());
|
||||
auto uri_query = uri.getQueryParameters();
|
||||
std::string action = "";
|
||||
std::string account_id_from_query;
|
||||
Poco::AutoPtr<controller::HederaAccount> query_hedera_account;
|
||||
|
||||
// parsing get query params
|
||||
if(uri_query.size() >= 2) {
|
||||
if(uri_query[0].first == "action") {
|
||||
action = uri_query[0].second;
|
||||
}
|
||||
if(uri_query[1].first == "account_id") {
|
||||
std::string account_id_from_query;
|
||||
int account_id = 0;
|
||||
account_id_from_query = uri_query[1].second;
|
||||
}
|
||||
}
|
||||
if(action == "updateBalance") {
|
||||
int account_id = 0;
|
||||
if(DataTypeConverter::strToInt(account_id_from_query, account_id) != DataTypeConverter::NUMBER_PARSE_OKAY) {
|
||||
addError(new Error("Int Convert Error", "Error converting account_id_from_query to int"));
|
||||
} else {
|
||||
auto hedera_account = controller::HederaAccount::load("id", account_id);
|
||||
if(!hedera_account.size() || hedera_account[0].isNull()) {
|
||||
addError(new Error("Action Update Balance", "hedera id not found"));
|
||||
if(DataTypeConverter::strToInt(account_id_from_query, account_id) != DataTypeConverter::NUMBER_PARSE_OKAY) {
|
||||
addError(new Error("Int Convert Error", "Error converting account_id_from_query to int"));
|
||||
} else {
|
||||
hedera_time.reset();
|
||||
hedera_account[0]->hederaAccountGetBalance(user, this);
|
||||
addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string()));
|
||||
auto hedera_accounts = controller::HederaAccount::load("id", account_id);
|
||||
if(!hedera_accounts.size() || hedera_accounts[0].isNull()) {
|
||||
addError(new Error("Action", "hedera account not found"));
|
||||
} else {
|
||||
query_hedera_account = hedera_accounts[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// add
|
||||
else if(!form.empty()) {
|
||||
// actions
|
||||
if(!query_hedera_account.isNull())
|
||||
{
|
||||
if(action == "updateBalance")
|
||||
{
|
||||
hedera_time.reset();
|
||||
query_hedera_account->hederaAccountGetBalance(user);
|
||||
addNotification(new ParamSuccess("Hedera", "crypto get balance success in ", hedera_time.string()));
|
||||
}
|
||||
else if(action == "changeEncryption")
|
||||
{
|
||||
if(query_hedera_account->changeEncryption(user)) {
|
||||
addNotification(new Success("Hedera Account", "success in changing encryption"));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(!form.empty()) // add
|
||||
{
|
||||
// collect
|
||||
auto shardNumString = form.get("account-shard-num", "0");
|
||||
auto realmNumString = form.get("account-realm-num", "0");
|
||||
auto numString = form.get("account-num", "0");
|
||||
auto privateKeyString = form.get("account-private-key", "");
|
||||
auto privateKeyEncryptedString = form.get("account-private-key-encrypted", "false");
|
||||
auto publicKeyString = form.get("account-public-key", "");
|
||||
auto networkTypeString = form.get("account-network-type", "0");
|
||||
|
||||
//printf("private key encrypted: %s\n", privateKeyEncryptedString.data());
|
||||
|
||||
int shardNum = 0;
|
||||
int realmNum = 0;
|
||||
int num = 0;
|
||||
@ -123,7 +141,7 @@
|
||||
auto crypto_key = controller::CryptoKey::load(key_pair.getPublicKey(), ed25519_pubkey_SIZE);
|
||||
|
||||
if(crypto_key.isNull()) {
|
||||
crypto_key = controller::CryptoKey::create(&key_pair, user);
|
||||
crypto_key = controller::CryptoKey::create(&key_pair, user, privateKeyEncryptedString == "true");
|
||||
if(!crypto_key->getModel()->insertIntoDB(true)) {
|
||||
addError(new Error("DB Error", "Error saving crypto key in DB"));
|
||||
}
|
||||
@ -131,15 +149,26 @@
|
||||
printf("crypto key found in db\n");
|
||||
}
|
||||
if(0 == errorCount()) {
|
||||
auto hedera_account = controller::HederaAccount::create(
|
||||
user->getModel()->getID(),
|
||||
hedera_id->getModel()->getID(),
|
||||
crypto_key->getModel()->getID(),
|
||||
0,
|
||||
(model::table::HederaNetworkType)networkType
|
||||
);
|
||||
if(!hedera_account->getModel()->insertIntoDB(false)) {
|
||||
addError(new Error("DB Error", "Error saving hedera account into DB"));
|
||||
|
||||
if(hedera_id->isExistInDB()) {
|
||||
auto hedera_account = controller::HederaAccount::load(hedera_id);
|
||||
if(hedera_account.isNull()) {
|
||||
addError(new Error("DB Error", "Couldn't load hedera account from db, but it should exist"));
|
||||
} else {
|
||||
addError(new Error("Hedera Account", "Account already exist (same account id"));
|
||||
}
|
||||
|
||||
} else {
|
||||
auto hedera_account = controller::HederaAccount::create(
|
||||
user->getModel()->getID(),
|
||||
hedera_id->getModel()->getID(),
|
||||
crypto_key->getModel()->getID(),
|
||||
0,
|
||||
(model::table::HederaNetworkType)networkType
|
||||
);
|
||||
if(!hedera_account->getModel()->insertIntoDB(false)) {
|
||||
addError(new Error("DB Error", "Error saving hedera account into DB"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,7 +177,9 @@
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(!query_hedera_account.isNull()) {
|
||||
getErrors(query_hedera_account);
|
||||
}
|
||||
// list accounts
|
||||
auto hedera_accounts = controller::HederaAccount::load("user_id", user->getModel()->getID());
|
||||
|
||||
@ -165,21 +196,33 @@
|
||||
<div class="cell header-cell c2">Hedera Id</div>
|
||||
<div class="cell header-cell c3">Balance</div>
|
||||
<div class="cell header-cell c2">Server Type</div>
|
||||
<div class="cell header-cell c3">Verschlüsselt?</div>
|
||||
<div class="cell header-cell c3">Last Updated</div>
|
||||
<div class="cell header-cell c5">Aktionen</div>
|
||||
</div>
|
||||
<% for(auto it = hedera_accounts.begin(); it != hedera_accounts.end(); it++) {
|
||||
auto hedera_account_model = (*it)->getModel();
|
||||
auto updateUrl = ServerConfig::g_serverPath + "/hedera_account?action=updateBalance&account_id=" + std::to_string(hedera_account_model->getID());
|
||||
std::string changeEncryption("");
|
||||
if(hedera_account_model->getUserId() == user->getModel()->getID()) {
|
||||
changeEncryption = ServerConfig::g_serverPath + "/hedera_account?action=changeEncryption&account_id=" + std::to_string(hedera_account_model->getID());
|
||||
}
|
||||
//printf("change encryption: %s\n", changeEncryption.data());
|
||||
%>
|
||||
<div class="row">
|
||||
<div class="cell c2"><%= (*it)->getHederaId()->getModel()->toString() %></div>
|
||||
<div class="cell c3"><%= hedera_account_model->getBalanceDouble() %> hbar</div>
|
||||
<div class="cell c2"><%= model::table::HederaAccount::hederaNetworkTypeToString(hedera_account_model->getNetworkType()) %></div>
|
||||
<div class="cell c3"><%= (*it)->getCryptoKey()->getModel()->isEncrypted() ? "Ja": "Nein" %></div>
|
||||
<div class="cell c3"><%= hedera_account_model->getUpdatedString() %></div>
|
||||
<button class="form-button" title="Anfrage an Hedera, kostet etwas" onclick="window.location.href='<%= updateUrl %>'" >
|
||||
<button class="form-button" title="Anfrage an Hedera, aktuell kostenlos" onclick="window.location.href='<%= updateUrl %>'" >
|
||||
Update Balance
|
||||
</button>
|
||||
<% if(changeEncryption != "") { %>
|
||||
<button class="form-button" title="Ändere den Verschlüsselungsstatus des Private Keys in der Datenbank" onclick="window.location.href='<%= changeEncryption %>'">
|
||||
Change Encryption
|
||||
</button>
|
||||
<% } %>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
@ -195,6 +238,8 @@
|
||||
<input class="form-control" id="account-num" placeholder="num" type="number" name="account-num"/>
|
||||
<label class="form-label" for="account-private-key">Private Key</label>
|
||||
<input class="form-control" id="account-private-key" type="text" name="account-private-key"/>
|
||||
<label class="form-label" for="account-private-key-encrypted" title="Wenn er verschlüsselt ist, kannst nur du Hedera Transaktionen damit bezahlen, wenn er nicht verschlüsselt ist kann er für alle Hedera Transaktionen automatisch verwendet werden. Ich empfehle dafür ein separates Konto mit wenigen Hashbars anzulegen.">Private Key verschlüsseln?</label>
|
||||
<input class="form-control" id="account-private-key-encrypted" type="checkbox" name="account-private-key-encrypted" value="true"/>
|
||||
<label class="form-label" for="account-public-key">Public Key</label>
|
||||
<input class="form-control" id="account-public-key" type="text" name="account-public-key"/>
|
||||
<label class="form-label" for="account-network-type">Network Type</label>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user