void Bip38ToolDialog::on_encryptKeyButton_ENC_clicked() { if (!model) return; QString qstrPassTNXase = ui->passTNXaseIn_ENC->text(); QString strInvalid; if (!isValidPassTNXase(qstrPassTNXase, strInvalid)) { ui->statusLabel_ENC->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_ENC->setText(tr("The entered passTNXase is invalid. ") + strInvalid + QString(" is not valid") + QString(" ") + tr("Allowed: 0-9,a-z,A-Z,") + specialChar); return; } if (!IsValidDestinationString(ui->addressIn_ENC->text().toStdString())) { ui->statusLabel_ENC->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_ENC->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again.")); return; } CTxDestination addr = DecodeDestination(ui->addressIn_ENC->text().toStdString()); CKeyID keyID = GetKeyForDestination(*pwalletMain, addr); if (keyID.IsNull()) { ui->addressIn_ENC->setValid(false); ui->statusLabel_ENC->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_ENC->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again.")); return; } WalletModel::UnlockContext ctx(model->requestUnlock(true)); if (!ctx.isValid()) { ui->statusLabel_ENC->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_ENC->setText(tr("Wallet unlock was cancelled.")); return; } CKey key; if (!pwalletMain->GetKey(keyID, key)) { ui->statusLabel_ENC->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_ENC->setText(tr("Private key for the entered address is not available.")); return; } std::string encryptedKey = BIP38_Encrypt(EncodeDestination(addr), qstrPassTNXase.toStdString(), key.GetPrivKey_256(), key.IsCompressed()); ui->encryptedKeyOut_ENC->setText(QString::fromStdString(encryptedKey)); }
// Retrieves a public key for an address from the given CKeyStore CPubKey AddrToPubKey(CKeyStore* const keystore, const std::string& addr_in) { CTxDestination dest = DecodeDestination(addr_in); if (!IsValidDestination(dest)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address: " + addr_in); } CKeyID key = GetKeyForDestination(*keystore, dest); if (key.IsNull()) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("%s does not refer to a key", addr_in)); } CPubKey vchPubKey; if (!keystore->GetPubKey(key, vchPubKey)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("no full public key for address %s", addr_in)); } if (!vchPubKey.IsFullyValid()) { throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet contains an invalid public key"); } return vchPubKey; }
bool CheckProRegTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state) { if (tx.nType != TRANSACTION_PROVIDER_REGISTER) { return state.DoS(100, false, REJECT_INVALID, "bad-protx-type"); } CProRegTx ptx; if (!GetTxPayload(tx, ptx)) { return state.DoS(100, false, REJECT_INVALID, "bad-protx-payload"); } if (ptx.nVersion == 0 || ptx.nVersion > CProRegTx::CURRENT_VERSION) { return state.DoS(100, false, REJECT_INVALID, "bad-protx-version"); } if (ptx.nType != 0) { return state.DoS(100, false, REJECT_INVALID, "bad-protx-type"); } if (ptx.nMode != 0) { return state.DoS(100, false, REJECT_INVALID, "bad-protx-mode"); } if (ptx.keyIDOwner.IsNull() || !ptx.pubKeyOperator.IsValid() || ptx.keyIDVoting.IsNull()) { return state.DoS(10, false, REJECT_INVALID, "bad-protx-key-null"); } if (!ptx.scriptPayout.IsPayToPublicKeyHash() && !ptx.scriptPayout.IsPayToScriptHash()) { return state.DoS(10, false, REJECT_INVALID, "bad-protx-payee"); } CTxDestination payoutDest; if (!ExtractDestination(ptx.scriptPayout, payoutDest)) { // should not happen as we checked script types before return state.DoS(10, false, REJECT_INVALID, "bad-protx-payee-dest"); } // don't allow reuse of payout key for other keys (don't allow people to put the payee key onto an online server) if (payoutDest == CTxDestination(ptx.keyIDOwner) || payoutDest == CTxDestination(ptx.keyIDVoting)) { return state.DoS(10, false, REJECT_INVALID, "bad-protx-payee-reuse"); } // It's allowed to set addr to 0, which will put the MN into PoSe-banned state and require a ProUpServTx to be issues later // If any of both is set, it must be valid however if (ptx.addr != CService() && !CheckService(tx.GetHash(), ptx, state)) { return false; } if (ptx.nOperatorReward > 10000) { return state.DoS(10, false, REJECT_INVALID, "bad-protx-operator-reward"); } CTxDestination collateralTxDest; CKeyID keyForPayloadSig; COutPoint collateralOutpoint; if (!ptx.collateralOutpoint.hash.IsNull()) { Coin coin; if (!GetUTXOCoin(ptx.collateralOutpoint, coin) || coin.out.nValue != 1000 * COIN) { return state.DoS(10, false, REJECT_INVALID, "bad-protx-collateral"); } if (!ExtractDestination(coin.out.scriptPubKey, collateralTxDest)) { return state.DoS(10, false, REJECT_INVALID, "bad-protx-collateral-dest"); } // Extract key from collateral. This only works for P2PK and P2PKH collaterals and will fail for P2SH. // Issuer of this ProRegTx must prove ownership with this key by signing the ProRegTx if (!CBitcoinAddress(collateralTxDest).GetKeyID(keyForPayloadSig)) { return state.DoS(10, false, REJECT_INVALID, "bad-protx-collateral-pkh"); } collateralOutpoint = ptx.collateralOutpoint; } else { if (ptx.collateralOutpoint.n >= tx.vout.size()) { return state.DoS(10, false, REJECT_INVALID, "bad-protx-collateral-index"); } if (tx.vout[ptx.collateralOutpoint.n].nValue != 1000 * COIN) { return state.DoS(10, false, REJECT_INVALID, "bad-protx-collateral"); } if (!ExtractDestination(tx.vout[ptx.collateralOutpoint.n].scriptPubKey, collateralTxDest)) { return state.DoS(10, false, REJECT_INVALID, "bad-protx-collateral-dest"); } collateralOutpoint = COutPoint(tx.GetHash(), ptx.collateralOutpoint.n); } // don't allow reuse of collateral key for other keys (don't allow people to put the collateral key onto an online server) // this check applies to internal and external collateral, but internal collaterals are not necessarely a P2PKH if (collateralTxDest == CTxDestination(ptx.keyIDOwner) || collateralTxDest == CTxDestination(ptx.keyIDVoting)) { return state.DoS(10, false, REJECT_INVALID, "bad-protx-collateral-reuse"); } if (pindexPrev) { auto mnList = deterministicMNManager->GetListForBlock(pindexPrev->GetBlockHash()); // only allow reusing of addresses when it's for the same collateral (which replaces the old MN) if (mnList.HasUniqueProperty(ptx.addr) && mnList.GetUniquePropertyMN(ptx.addr)->collateralOutpoint != collateralOutpoint) { return state.DoS(10, false, REJECT_DUPLICATE, "bad-protx-dup-addr"); } // never allow duplicate keys, even if this ProTx would replace an existing MN if (mnList.HasUniqueProperty(ptx.keyIDOwner) || mnList.HasUniqueProperty(ptx.pubKeyOperator)) { return state.DoS(10, false, REJECT_DUPLICATE, "bad-protx-dup-key"); } if (!deterministicMNManager->IsDIP3Enforced(pindexPrev->nHeight)) { if (ptx.keyIDOwner != ptx.keyIDVoting) { return state.DoS(10, false, REJECT_INVALID, "bad-protx-key-not-same"); } } } if (!CheckInputsHash(tx, ptx, state)) { return false; } if (!keyForPayloadSig.IsNull()) { // collateral is not part of this ProRegTx, so we must verify ownership of the collateral if (!CheckStringSig(ptx, keyForPayloadSig, state)) { return false; } } else { // collateral is part of this ProRegTx, so we know the collateral is owned by the issuer if (!ptx.vchSig.empty()) { return state.DoS(100, false, REJECT_INVALID, "bad-protx-sig"); } } return true; }
Value sendtoaddress(const Array& params, bool fHelp) { int size = params.size(); if (fHelp || (!(size == 2 || size == 3))) throw runtime_error( "sendtoaddress (\"Dacrsaddress\") \"receive address\" \"amount\"\n" "\nSend an amount to a given address. The amount is a real and is rounded to the nearest 0.00000001\n" + HelpRequiringPassphrase() + "\nArguments:\n" "1. \"Dacrsaddress\" (string, optional) The Honghuo address to send to.\n" "2. receive address (string, required) The Honghuo address to receive\n" "3.\"amount\" (string, required) \n" "\nResult:\n" "\"transactionid\" (string) The transaction id.\n" "\nExamples:\n" + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1") + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"") + HelpExampleRpc("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"" + HelpExampleCli("sendtoaddress", "\"0-6\" 10 ") + HelpExampleCli("sendtoaddress", "\"00000000000000000005\" 10 ") + HelpExampleCli("sendtoaddress", "\"0-6\" \"0-5\" 10 ") + HelpExampleCli("sendtoaddress", "\"00000000000000000005\" \"0-6\"10 "))); EnsureWalletIsUnlocked(); CKeyID sendKeyId; CKeyID RevKeyId; auto GetKeyId = [](string const &addr,CKeyID &KeyId) { if (!CRegID::GetKeyID(addr, KeyId)) { KeyId=CKeyID(addr); if (KeyId.IsEmpty()) return false; } return true; }; // Amount int64_t nAmount = 0; CRegID sendreg; //// from address to addreww if (size == 3) { if (!GetKeyId(params[0].get_str(), sendKeyId)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "FROM Invalid address"); } if (!GetKeyId(params[1].get_str(), RevKeyId)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "to Invalid address"); } nAmount = AmountToRawValue(params[2]); if (pAccountViewTip->GetRawBalance(sendKeyId) <= nAmount + SysCfg().GetTxFee()) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "FROM address not enough coins"); } } else { if (!GetKeyId(params[0].get_str(), RevKeyId)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "to address Invalid "); } nAmount = AmountToRawValue(params[1]); set<CKeyID> sKeyid; sKeyid.clear(); pwalletMain->GetKeys(sKeyid); //get addrs if(sKeyid.empty()) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No Key In wallet \n"); } for (auto &te : sKeyid) { if (pAccountViewTip->GetRawBalance(te) >= nAmount + SysCfg().GetTxFee()) { if (pAccountViewTip->GetRegId(CUserID(te), sendreg)) { sendKeyId = te; break; } } } if (sendKeyId.IsNull()) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "not find enough moeny account "); } } CRegID revreg; CUserID rev; if (!pAccountViewTip->GetRegId(CUserID(sendKeyId), sendreg)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); } if (pAccountViewTip->GetRegId(CUserID(RevKeyId), revreg)) { rev = revreg; } else { rev = RevKeyId; } CTransaction tx(sendreg, rev, SysCfg().GetTxFee(), nAmount, chainActive.Height()); if (!pwalletMain->Sign(sendKeyId, tx.SignatureHash(), tx.signature)) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Sign failed"); } std::tuple<bool,string> ret = pwalletMain->CommitTransaction((CBaseTransaction *) &tx); if(!std::get<0>(ret)) throw JSONRPCError(RPC_INVALID_PARAMETER, std::get<1>(ret)); Object obj; obj.push_back(Pair("hash" , std::get<1>(ret))); return obj; }
Value sendtoaddresswithfee(const Array& params, bool fHelp) { int size = params.size(); if (fHelp || (!(size == 3 || size == 4))) throw runtime_error( "sendtoaddresswithfee (\"sendaddress\") \"recvaddress\" \"amount\" (fee)\n" "\nSend an amount to a given address with fee. The amount is a real and is rounded to the nearest 0.00000001\n" "\nArguments:\n" "1. \"sendaddress\" (string, optional) The Honghuo address to send to.\n" "2. \"recvaddress\" (string, required) The Honghuo address to receive.\n" "3.\"amount\" (string,required) \n" "4.\"fee\" (string,required) \n" "\nResult:\n" "\"transactionid\" (string) The transaction id.\n" "\nExamples:\n" + HelpExampleCli("sendtoaddresswithfee", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 10000000 1000") + HelpExampleCli("sendtoaddresswithfee", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"") + HelpExampleRpc("sendtoaddresswithfee", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"" + HelpExampleCli("sendtoaddresswithfee", "\"0-6\" 10 ") + HelpExampleCli("sendtoaddresswithfee", "\"00000000000000000005\" 10 ") + HelpExampleCli("sendtoaddresswithfee", "\"0-6\" \"0-5\" 10 ") + HelpExampleCli("sendtoaddresswithfee", "\"00000000000000000005\" \"0-6\"10 "))); EnsureWalletIsUnlocked(); CKeyID sendKeyId; CKeyID RevKeyId; auto GetKeyId = [](string const &addr,CKeyID &KeyId) { if (!CRegID::GetKeyID(addr, KeyId)) { KeyId=CKeyID(addr); if (KeyId.IsEmpty()) return false; } return true; }; // Amount int64_t nAmount = 0; int64_t nFee = 0; //// from address to addreww if (size == 4) { if (!GetKeyId(params[0].get_str(), sendKeyId)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "FROM Invalid address"); } if (!GetKeyId(params[1].get_str(), RevKeyId)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "to Invalid address"); } nAmount = AmountToRawValue(params[2]); if (pAccountViewTip->GetRawBalance(sendKeyId) <= nAmount + SysCfg().GetTxFee()) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "FROM address not enough coins"); } nFee = AmountToRawValue(params[3]); } else { if (!GetKeyId(params[0].get_str(), RevKeyId)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "to address Invalid "); } nAmount = AmountToRawValue(params[1]); set<CKeyID> sKeyid; sKeyid.clear(); pwalletMain->GetKeys(sKeyid); if (sKeyid.empty()) //get addrs { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No Key In wallet \n"); } nFee = AmountToRawValue(params[2]); for (auto &te : sKeyid) { if (pAccountViewTip->GetRawBalance(te) >= nAmount + SysCfg().GetTxFee()) { sendKeyId = te; break; } } if (sendKeyId.IsNull()) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "not find enough moeny account "); } } auto SendMoney = [&](const CRegID &send, const CUserID &rsv, int64_t nValue, int64_t nFee) { CTransaction tx; tx.srcRegId = send; tx.desUserId = rsv; tx.llValues = nValue; if (0 == nFee) { tx.llFees = SysCfg().GetTxFee(); } else tx.llFees = nFee; tx.nValidHeight = chainActive.Tip()->nHeight; CKeyID keID; if(!pAccountViewTip->GetKeyId(send,keID)) { return std::make_tuple (false,"key or keID failed"); } if (!pwalletMain->Sign(keID,tx.SignatureHash(), tx.signature)) { return std::make_tuple (false,"Sign failed"); } std::tuple<bool,string> ret = pwalletMain->CommitTransaction((CBaseTransaction *) &tx); bool falg = std::get<0>(ret); string te = std::get<1>(ret); if(falg == true) te = tx.GetHash().ToString(); return std::make_tuple (falg,te.c_str()); }; CRegID sendreg; CRegID revreg; if (!pAccountViewTip->GetRegId(CUserID(sendKeyId), sendreg)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); } std::tuple<bool,string> ret; if (pAccountViewTip->GetRegId(CUserID(RevKeyId), revreg)) { ret = SendMoney(sendreg, revreg, nAmount, nFee); } else { ret = SendMoney(sendreg, CUserID(RevKeyId), nAmount, nFee); } Object obj; obj.push_back(Pair(std::get<0>(ret) ? "hash" : "error code", std::get<1>(ret))); return obj; }