Committing updates.

This commit is contained in:
Преподобный Ален
2021-09-17 15:04:26 +03:00
parent e758e8d8dc
commit f4f4d104cf
136 changed files with 46883 additions and 79 deletions

1441
src/app/Bitcoin.cpp Normal file

File diff suppressed because it is too large Load Diff

733
src/app/Bitcoin.hpp Normal file
View File

@@ -0,0 +1,733 @@
/*++
Module Name:
Bitcoin.hpp
Notices:
Bitcoin library
Author:
Copyright (c) Prepodobny Alen
mailto: alienufo@inbox.ru
mailto: ufocomp@gmail.com
--*/
#ifndef APOSTOL_BITCOIN_HPP
#define APOSTOL_BITCOIN_HPP
#ifdef BITCOIN_VERSION_4
//#include <bitcoin/system.hpp>
#include <bitcoin/system/formats/base_10.hpp>
#include <bitcoin/system/formats/base_16.hpp>
#include <bitcoin/system/formats/base_32.hpp>
#include <bitcoin/system/formats/base_58.hpp>
#include <bitcoin/system/formats/base_64.hpp>
#include <bitcoin/system/formats/base_85.hpp>
#include <bitcoin/system/config/base16.hpp>
#include <bitcoin/system/wallet/message.hpp>
#include <bitcoin/system/wallet/payment_address.hpp>
#include <bitcoin/system/wallet/witness_address.hpp>
#include <bitcoin/system/wallet/ek_token.hpp>
#include <bitcoin/system/wallet/ek_public.hpp>
#include <bitcoin/system/wallet/encrypted_keys.hpp>
#include <bitcoin/system/config/script.hpp>
#include <bitcoin/client/history.hpp>
#include <bitcoin/client/stealth.hpp>
using namespace bc;
using namespace bc::system;
using namespace bc::system::config;
using namespace bc::system::wallet;
using namespace bc::client;
#else
#ifdef BITCOIN_VERSION_3_7_x
#include <bitcoin/system.hpp>
#else
#include <bitcoin/bitcoin.hpp>
#endif
#include <bitcoin/protocol.hpp>
#include <bitcoin/client/define.hpp>
#include <bitcoin/client/obelisk_client.hpp>
#include <bitcoin/client/version.hpp>
using namespace bc;
using namespace bc::chain;
using namespace bc::machine;
using namespace bc::config;
using namespace bc::wallet;
using namespace bc::client;
#endif
//----------------------------------------------------------------------------------------------------------------------
#define BX_EK_PUBLIC_TO_EC_INVALID_PASSPHRASE \
"The passphrase is incorrect."
#define BX_EK_ADDRESS_SHORT_SEED \
"The seed is less than 192 bits long."
#define BX_TOKEN_NEW_SHORT_SALT \
"The salt is less than 32 bits long."
#define BX_TOKEN_NEW_REQUIRES_ICU \
"The command requires an ICU build."
#define BX_CONNECTION_FAILURE \
"Could not connect to server: %1%"
#define BX_HD_NEW_SHORT_SEED \
"The seed is less than 128 bits long."
#define BX_HD_NEW_INVALID_KEY \
"The seed produced an invalid key."
//----------------------------------------------------------------------------------------------------------------------
#define BX_NO_TRANSFERS_FOUND "No transfers found on account: %s."
#define BX_INVALID_SECRET_KEY_COUNT "Invalid count of secret keys (2 or 3 expected)."
#define BX_INSUFFICIENT_FUNDS "Insufficient funds on account: %s."
#define BX_INSUFFICIENT_FEE "Insufficient transaction fee on account: %s."
//----------------------------------------------------------------------------------------------------------------------
/**
* The minimum safe length of a seed in bits (multiple of 8).
*/
BC_CONSTEXPR size_t minimum_seed_bits = 128;
/**
* The minimum safe length of a seed in bytes (16).
*/
BC_CONSTEXPR size_t minimum_seed_size = minimum_seed_bits / bc::byte_bits;
//----------------------------------------------------------------------------------------------------------------------
extern "C++" {
namespace Apostol {
namespace Bech32
{
/** Encode a Bech32 string. Returns the empty string in case of failure. */
std::string encode(const std::string& hrp, const std::vector<uint8_t>& values);
/** Decode a Bech32 string. Returns (hrp, data). Empty hrp means failure. */
std::pair<std::string, std::vector<uint8_t> > decode(const std::string& str);
}
namespace SegWit
{
/** Decode a SegWit address. Returns (witver, witprog). witver = -1 means failure. */
std::pair<int, std::vector<uint8_t> > decode(const std::string& hrp, const std::string& addr);
/** Encode a SegWit address. Empty string means failure. */
std::string encode(const std::string& hrp, int witver, const std::vector<uint8_t>& witprog);
uint32_t checksum(const std::string& hrp, int witver, const std::vector<uint8_t>& witprog);
}
namespace Bitcoin {
typedef TList<ec_private> CPrivateList;
//--------------------------------------------------------------------------------------------------------------
struct CTransactionFee {
CString Fee;
uint_t min;
uint_t max;
};
struct CBitcoinConfig {
std::string endpoint = "tcp://mainnet.libbitcoin.net:9091";
uint64_t version_hd = hd_private::mainnet;
uint16_t version_ec = ec_private::mainnet;
uint8_t version_key = payment_address::mainnet_p2kh;
uint8_t version_script = payment_address::mainnet_p2sh;
CTransactionFee Miner {"1%", 200, 2000};
uint_t min_output = 200;
CString Symbol = "BTC";
};
//--------------------------------------------------------------------------------------------------------------
extern CBitcoinConfig BitcoinConfig;
//--------------------------------------------------------------------------------------------------------------
enum CAddressDecodeType { adtInfo, adtHtml, adtJson };
std::string string_to_hex(const std::string& input);
std::string hex_to_string(const std::string& input);
//--------------------------------------------------------------------------------------------------------------
std::string sha1(const std::string &value);
CString sha1(const CString &Value);
//--------------------------------------------------------------------------------------------------------------
std::string sha256(const std::string &value);
CString sha256(const CString &Value);
//--------------------------------------------------------------------------------------------------------------
std::string ripemd160(const std::string &value);
CString ripemd160(const CString &Value);
//--------------------------------------------------------------------------------------------------------------
double satoshi_to_btc(uint64_t Value);
uint64_t btc_to_satoshi(double Value);
//--------------------------------------------------------------------------------------------------------------
bool valid_address(const CString& Address);
//--------------------------------------------------------------------------------------------------------------
bool valid_public_key(const std::string& key);
bool valid_public_key(const CString& Key);
//--------------------------------------------------------------------------------------------------------------
bool key_belongs_address(const std::string& key, const std::string& address);
bool key_belongs_address(const CString& Key, const CString& Address);
//--------------------------------------------------------------------------------------------------------------
bool address_decode(CAddressDecodeType type, const CString& Address, CString& Result);
//--------------------------------------------------------------------------------------------------------------
bool address_decode(const CString& Address, CJSON& Result);
bool address_decode(const CString& Address, CString& Result);
//--------------------------------------------------------------------------------------------------------------
bool unwrap_legacy(wallet::wrapped_data &data, const wallet::payment_address &address);
bool unwrap_legacy(wallet::wrapped_data &data, const std::string &address);
//--------------------------------------------------------------------------------------------------------------
bool unwrap_segwit(wallet::wrapped_data &data, const std::string &address);
//--------------------------------------------------------------------------------------------------------------
bool IsLegacyAddress(const std::string& address);
bool IsLegacyAddress(const CString& Address);
bool IsSegWitAddress(const std::string& addr);
bool IsSegWitAddress(const CString& Addr);
bool IsBitcoinAddress(const std::string& addr);
bool IsBitcoinAddress(const CString& Addr);
//--------------------------------------------------------------------------------------------------------------
wallet::ek_token token_new(const std::string &passphrase, const data_chunk& salt);
wallet::ek_public ek_public(const wallet::ek_token &token, const data_chunk& seed, uint8_t version = payment_address::mainnet_p2kh);
wallet::ec_public ek_public_to_ec(const std::string &passphrase, const wallet::ek_public &key);
wallet::payment_address ek_address(const wallet::ek_token &token, const data_chunk& seed, uint8_t version = payment_address::mainnet_p2kh);
//--------------------------------------------------------------------------------------------------------------
wallet::hd_private hd_new(const data_chunk& seed, uint64_t prefixes = hd_private::mainnet);
wallet::ec_private hd_to_ec_private(const wallet::hd_key& key, uint64_t prefixes = hd_private::mainnet);
wallet::ec_public hd_to_ec_public(const wallet::hd_key& key, uint32_t prefix = hd_public::mainnet);
//--------------------------------------------------------------------------------------------------------------
bool verify_message(const std::string& msg, const std::string& addr, const std::string& sig);
bool VerifyMessage(const CString& Message, const CString& Address, const CString& Signature);
//--------------------------------------------------------------------------------------------------------------
#ifdef BITCOIN_VERSION_4
std::string address_to_key(const wallet::payment_address &address);
#endif
chain::script get_witness_script(const ec_public& key1, const ec_public& key2, const ec_public& key3);
chain::script get_redeem_script(const ec_public& key1, const ec_public& key2, const ec_public& key3);
std::string script_to_address(const chain::script &script, uint8_t version = payment_address::mainnet_p2sh);
std::string script_to_address(const std::string &script, uint8_t version = payment_address::mainnet_p2sh);
//--------------------------------------------------------------------------------------------------------------
#ifdef WITH_BITCOIN_CLIENT
uint64_t fetch_balance(const wallet::payment_address &address);
//--------------------------------------------------------------------------------------------------------------
void fetch_history(const wallet::payment_address &address, CJSON& Result);
void fetch_header(uint32_t height, CJSON& Result);
void fetch_header(const hash_digest& hash, CJSON& Result);
void send_tx(const chain::transaction& tx, CJSON& Result);
void send_tx(const std::string& hex, CJSON& Result);
//--------------------------------------------------------------------------------------------------------------
//-- CBalance --------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
class CBalance {
private:
uint32_t m_Transfers;
uint32_t m_Height;
uint32_t m_Received;
uint32_t m_Spent;
CDateTime m_TimeStamp;
protected:
CJSON m_History;
CJSON m_Header;
public:
CBalance() {
m_Transfers = 0;
m_Height = 0;
m_Received = 0;
m_Spent = 0;
m_TimeStamp = 0;
}
void Clear();
void Fetch(const CString &Address);
const CJSON &History() const { return m_History; };
const CJSON &Header() const { return m_Header; };
uint32_t Transfers() const { return m_Transfers; }
uint32_t Height() const { return m_Height; }
CDateTime TimeStamp() const { return m_TimeStamp; }
uint32_t Received() const { return m_Received; }
uint32_t Spent() const { return m_Spent; }
uint32_t Balance() const {
return m_Received - m_Spent;
}
};
#endif
//--------------------------------------------------------------------------------------------------------------
//-- CWitness --------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
class CWitness {
private:
std::vector<ec_private> m_secrets;
std::vector<ec_public> m_keys;
uint8_t m_signatures;
hash_digest m_hash;
chain::script m_script;
chain::script m_embedded;
void bind_script();
void bind_embedded();
public:
CWitness();
explicit CWitness(uint8_t signatures);
CWitness(const ec_private& key1, const ec_private& key2);
CWitness(const ec_private& key1, const ec_private& key2, const ec_private& key3);
CWitness(const ec_private& key1, const ec_private& key2, const ec_public& key3);
CWitness(const ec_private& key1, const ec_private& key2, const ec_private& key3, const ec_public& key4);
CWitness(const ec_public& key1, const ec_public& key2, const ec_public& key3);
void make(const ec_private& key1, const ec_private& key2);
void make(const ec_private& key1, const ec_private& key2, const ec_private& key3);
void make(const ec_private& key1, const ec_private& key2, const ec_public& key3);
void make(const ec_private& key1, const ec_private& key2, const ec_private& key3, const ec_public& key4);
void make(const ec_public& key1, const ec_public& key2, const ec_public& key3);
void bind();
const hash_digest& hash() const;
const chain::script& script() const { return m_script; };
const chain::script& embedded() const {return m_embedded; };
payment_address to_address(uint8_t version = payment_address::mainnet_p2sh) const;
const std::vector<ec_private> &secrets() const { return m_secrets; };
const std::vector<ec_public> &keys() const { return m_keys; };
};
//--------------------------------------------------------------------------------------------------------------
//-- CRecipient ------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
typedef struct CRecipient {
CString Address {};
uint64_t Amount;
CRecipient() {
Amount = 0;
}
CRecipient(const CRecipient &Other) {
if (this != &Other) {
this->Address = Other.Address;
this->Amount = Other.Amount;
}
};
CRecipient(const CString &Address, uint64_t Amount) {
this->Address = Address;
this->Amount = Amount;
}
CRecipient &operator=(const CRecipient &Other) {
if (this != &Other) {
this->Address = Other.Address;
this->Amount = Other.Amount;
}
return *this;
};
inline bool operator!=(const CRecipient &Value) { return Address != Value.Address; };
inline bool operator==(const CRecipient &Value) { return Address == Value.Address; };
} CRecipient, *PRecipient;
//--------------------------------------------------------------------------------------------------------------
typedef TList<CRecipient> CRecipients;
//--------------------------------------------------------------------------------------------------------------
//-- raw -------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
/**
* Serialization helper to convert between a byte stream and data_chunk.
*/
class raw
{
public:
/**
* Default constructor.
*/
raw();
/**
* Initialization constructor.
* @param[in] text The value to initialize with.
*/
raw(const std::string& text);
/**
* Initialization constructor.
* @param[in] value The value to initialize with.
*/
raw(data_chunk value);
/**
* Copy constructor.
* @param[in] other The object to copy into self on construct.
*/
raw(const raw& other);
/**
* Overload cast to internal type.
* @return This object's value cast to internal type.
*/
operator const data_chunk&() const;
/**
* Overload cast to generic data reference.
* @return This object's value cast to a generic data reference.
*/
operator data_slice() const;
/**
* Overload stream in. Throws if input is invalid.
* @param[in] input The input stream to read the value from.
* @param[out] argument The object to receive the read value.
* @return The input stream reference.
*/
friend std::istream& operator>>(std::istream& input,
raw& argument);
/**
* Overload stream out.
* @param[in] output The output stream to write the value to.
* @param[out] argument The object from which to obtain the value.
* @return The output stream reference.
*/
friend std::ostream& operator<<(std::ostream& output,
const raw& argument);
private:
/**
* The state of this object's raw data.
*/
data_chunk value_;
};
class wrapper
{
public:
/**
* Default constructor.
*/
wrapper();
/**
* Initialization constructor.
*
* @param[in] wrapped The value to initialize with.
*/
wrapper(const std::string& wrapped);
/**
* Initialization constructor.
* @param[in] wrapped The wrapped value to initialize with.
*/
wrapper(const data_chunk& wrapped);
/**
* Initialization constructor.
* @param[in] wrapped The wrapped value to initialize with.
*/
wrapper(const wallet::wrapped_data& wrapped);
/**
* Initialization constructor.
* @param[in] address The payment address to initialize with.
*/
wrapper(const wallet::payment_address& address);
/**
* Initialization constructor.
* @param[in] version The version for the new wrapped value.
* @param[in] payload The payload for the new wrapped value.
*/
wrapper(uint8_t version, const data_chunk& payload);
/**
* Copy constructor.
* @param[in] other The object to copy into self on construct.
*/
wrapper(const wrapper& other);
/**
* Serialize the wrapper to bytes according to the wire protocol.
* @return The byte serialized copy of the wrapper.
*/
const data_chunk to_data() const;
/**
* Overload cast to internal type.
* @return This object's value cast to internal type.
*/
operator const wallet::wrapped_data&() const;
/**
* Overload stream in. Throws if input is invalid.
* @param[in] input The input stream to read the value from.
* @param[out] argument The object to receive the read value.
* @return The input stream reference.
*/
friend std::istream& operator>>(std::istream& input,
wrapper& argument);
/**
* Overload stream out.
* @param[in] output The output stream to write the value to.
* @param[out] argument The object from which to obtain the value.
* @return The output stream reference.
*/
friend std::ostream& operator<<(std::ostream& output,
const wrapper& argument);
private:
/**
* The state of this object's data.
*/
wallet::wrapped_data value_;
};
/**
* Serialization helper to convert between string and message_signature.
*/
class signature
{
public:
/**
* Default constructor.
*/
signature();
/**
* Initialization constructor.
* @param[in] hexcode The value to initialize with.
*/
signature(const std::string& hexcode);
/**
* Initialization constructor.
* @param[in] value The value to initialize with.
*/
signature(const wallet::message_signature& value);
/**
* Copy constructor.
* @param[in] other The object to copy into self on construct.
*/
signature(const signature& other);
/**
* Overload cast to internal type.
* @return This object's value cast to internal type.
*/
operator wallet::message_signature&();
/**
* Overload cast to internal type.
* @return This object's value cast to internal type.
*/
operator const wallet::message_signature&() const;
/// Serializer.
std::string encoded() const;
/**
* Overload stream in. If input is invalid sets no bytes in argument.
* @param[in] input The input stream to read the value from.
* @param[out] argument The object to receive the read value.
* @return The input stream reference.
*/
friend std::istream& operator>>(std::istream& input, signature& argument);
/**
* Overload stream out.
* @param[in] output The output stream to write the value to.
* @param[out] argument The object from which to obtain the value.
* @return The output stream reference.
*/
friend std::ostream& operator<<(std::ostream& output, const signature& argument);
private:
/**
* The state of this object.
*/
wallet::message_signature value_;
};
/**
* Serialization helper to convert between base16/raw script and script_type.
*/
class script
{
public:
/**
* Default constructor.
*/
script();
/**
* Initialization constructor.
* @param[in] mnemonic The value to initialize with.
*/
script(const std::string& mnemonic);
/**
* Initialization constructor.
* @param[in] value The value to initialize with.
*/
script(const chain::script& value);
/**
* Initialization constructor.
* @param[in] value The value to initialize with.
*/
script(const data_chunk& value);
/**
* Initialization constructor.
* @param[in] tokens The mnemonic tokens to initialize with.
*/
script(const std::vector<std::string>& tokens);
/**
* Copy constructor.
* @param[in] other The object to copy into self on construct.
*/
script(const script& other);
/**
* Serialize the script to bytes according to the wire protocol.
* @return The byte serialized copy of the script.
*/
const bc::data_chunk to_data() const;
/**
* Return a pretty-printed copy of the script.
* @return A mnemonic-printed copy of the internal script.
*/
const std::string to_string() const;
/**
* Overload cast to internal type.
* @return This object's value cast to internal type.
*/
operator const chain::script&() const;
/**
* Overload stream in. Throws if input is invalid.
* @param[in] input The input stream to read the value from.
* @param[out] argument The object to receive the read value.
* @return The input stream reference.
*/
friend std::istream& operator>>(std::istream& input,
script& argument);
/**
* Overload stream out.
* @param[in] output The output stream to write the value to.
* @param[out] argument The object from which to obtain the value.
* @return The output stream reference.
*/
friend std::ostream& operator<<(std::ostream& output,
const script& argument);
private:
/**
* The state of this object.
*/
chain::script value_;
};
} // namespace Bitcoin
} // namespace Apostol
using namespace Apostol::Bitcoin;
using namespace Apostol::Bech32;
using namespace Apostol::SegWit;
}
#endif //APOSTOL_BITCOIN_HPP

532
src/app/Deal.cpp Normal file
View File

@@ -0,0 +1,532 @@
/*++
Program name:
BitDeals
Module Name:
Deal.cpp
Notices:
Apostol Core (Deal)
Author:
Copyright (c) Prepodobny Alen
mailto: alienufo@inbox.ru
mailto: ufocomp@gmail.com
--*/
#include "Core.hpp"
#include "Deal.hpp"
//----------------------------------------------------------------------------------------------------------------------
#ifdef __cplusplus
extern "C++" {
#endif // __cplusplus
namespace Apostol {
namespace Deal {
CString UTCFormat(const CString& Value) {
return Value.SubString(0, 19) << " UTC";
}
//--------------------------------------------------------------------------------------------------------------
CString BTCFormat(const CString& Value) {
if (Value.Find(BitcoinConfig.Symbol) == CString::npos)
return Value.TrimRight('0') << " " << BitcoinConfig.Symbol;
return Value.TrimRight('0');
}
//--------------------------------------------------------------------------------------------------------------
double BTCToDouble(const CString &Value) {
const size_t Pos = Value.Find(BitcoinConfig.Symbol);
if (Pos == CString::npos)
return StrToDouble(Value.c_str());
return StrToDouble(Value.SubString(0, Pos).TrimRight().c_str());
}
//--------------------------------------------------------------------------------------------------------------
CString DoubleToBTC(const double &Value, const CString &Format) {
TCHAR Buffer[25] = {0};
FloatToStr(Value, Buffer, sizeof(Buffer), Format.c_str());
return Buffer;
}
//--------------------------------------------------------------------------------------------------------------
CDateTime StringToDate(const CString &Value, const CString &Format) {
return StrToDateTimeDef(Value.c_str(), 0, Format.c_str());
}
//--------------------------------------------------------------------------------------------------------------
CString DateToString(const CDateTime &Value, const CString &Format) {
TCHAR Buffer[25] = {0};
DateTimeToStr(Value, Buffer, sizeof(Buffer), Format.c_str());
return Buffer;
}
//--------------------------------------------------------------------------------------------------------------
//-- DealData --------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
CString DealData::GetStringData() const {
CString Data;
Data.Format("Type: %d;", (int) Type);
Data.Format("URL: %s;", At.c_str());
Data.Format("Date: %s;", Date.c_str());
Data.Format("Seller: %s;", Seller.Address.c_str());
Data.Format("Customer: %s;", Customer.Address.c_str());
Data.Format("Until: %s;", Payment.Until.c_str());
Data.Format("Sum: %s;", Payment.Sum.c_str());
Data.Format("LeaveBefore: %s", FeedBack.LeaveBefore.c_str());
return Data;
}
//--------------------------------------------------------------------------------------------------------------
//-- CRating ---------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
void CRating::Parse(const CString &Value) {
size_t Pos = 0;
TCHAR ch = Value.at(Pos++);
if (Value.Size() < 4 || !IsNumeral(ch))
throw ExceptionFrm("Invalid rating value.");
CString Item;
while (!IsCtl(ch)) {
if (ch == '+' && !Item.IsEmpty()) {
Count = StrToIntDef(Item.c_str(), 0);
Count++;
Item.Clear();
} else if (ch == ',' && !Item.IsEmpty()) {
Count = StrToIntDef(Item.c_str(), 0);
Item.Clear();
} else if (ch == '%' && !Item.IsEmpty()) {
Positive = StrToIntDef(Item.c_str(), 0);
Item.Clear();
} else {
if (!(ch == ' ' || ch == ',')) {
if (!IsNumeral(ch))
throw ExceptionFrm("Invalid rating value.");
Item << ch;
}
}
ch = Value.at(Pos++);
}
}
//--------------------------------------------------------------------------------------------------------------
//-- CDeal -----------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
CDeal::CDeal() {
m_Data.Order = doCreate;
m_Data.FeedBack.Status = fsPositive;
}
//--------------------------------------------------------------------------------------------------------------
CDeal::CDeal(const YAML::Node &node) : CDeal() {
Parse(node);
}
//--------------------------------------------------------------------------------------------------------------
CDealOrder CDeal::StringToOrder(const CString &Value) {
const CString &S = Value.Lower();
if (S == "create") {
return doCreate;
} else if (S == "created") {
return doCreated;
} else if (S == "pay") {
return doPay;
} else if (S == "paid") {
return doPaid;
} else if (S == "complete") {
return doComplete;
} else if (S == "completed") {
return doCompleted;
} else if (S == "cancel") {
return doCancel;
} else if (S == "canceled") {
return doCanceled;
} else if (S == "execute") {
return doExecute;
} else if (S == "executed") {
return doExecuted;
} else if (S == "delete") {
return doDelete;
} else if (S == "deleted") {
return doDeleted;
} else if (S == "fail") {
return doFail;
} else if (S == "failed") {
return doFailed;
} else if (S == "feedback") {
return doFeedback;
} else {
throw ExceptionFrm("Invalid deal order value: \"%s\".", Value.c_str());
}
}
//--------------------------------------------------------------------------------------------------------------
CString CDeal::OrderToString(CDealOrder Order) {
switch (Order) {
case doCreate:
return "Create";
case doCreated:
return "Created";
case doPay:
return "Pay";
case doPaid:
return "Paid";
case doComplete:
return "Complete";
case doCompleted:
return "Completed";
case doCancel:
return "Cancel";
case doCanceled:
return "Canceled";
case doExecute:
return "Execute";
case doExecuted:
return "Executed";
case doDelete:
return "Delete";
case doDeleted:
return "Deleted";
case doFail:
return "Fail";
case doFailed:
return "Failed";
case doFeedback:
return "Feedback";
default:
return "Unknown";
}
}
//--------------------------------------------------------------------------------------------------------------
CDealType CDeal::StringToType(const CString &Value) {
const auto &status = Value.Lower();
if (status.Find("prepaid") != CString::npos || status.Find("prepayment") != CString::npos) {
return dtPrepaid;
} else if (status.Find("postpaid") != CString::npos || status.Find("postpayment") != CString::npos) {
return dtPostpaid;
} else {
throw ExceptionFrm(R"(Invalid order type value: "%s".)", status.c_str());
}
}
//--------------------------------------------------------------------------------------------------------------
CString CDeal::TypeToString(CDealType Type) {
switch (Type) {
case dtPrepaid:
return "Prepaid";
case dtPostpaid:
return "Postpaid";
default:
return "Unknown";
}
}
//--------------------------------------------------------------------------------------------------------------
CString CDeal::TypeCodeToString(const CString &Code) {
if (Code == "prepaid.deal") {
return CString("Prepaid");
} else if (Code == "postpaid.deal") {
return CString("Postpaid");
} else {
throw ExceptionFrm(R"(Invalid type code value: "%s".)", Code.c_str());
}
}
//--------------------------------------------------------------------------------------------------------------
CFeedBackStatus CDeal::StringToFeedBackStatus(const CString &Value) {
const CString &Status = Value.Lower();
if (Status == "negative") {
return fsNegative;
} else if (Status == "neutral") {
return fsNeutral;
} else if (Status == "positive") {
return fsPositive;
} else {
throw ExceptionFrm(R"(Invalid feedback status value: "%s".)", Status.c_str());
}
}
//--------------------------------------------------------------------------------------------------------------
CString CDeal::FeedBackStatusToString(CFeedBackStatus Status) {
switch (Status) {
case fsNegative:
return "Negative";
case fsNeutral:
return "Neutral";
case fsPositive:
return "Positive";
default:
return "Unknown";
}
}
//--------------------------------------------------------------------------------------------------------------
CString CDeal::GetHashData() {
return m_Data.GetStringData();
}
//--------------------------------------------------------------------------------------------------------------
std::string CDeal::get_hash() {
const std::string str(GetHashData().c_str());
return sha256(str);
}
//--------------------------------------------------------------------------------------------------------------
std::string CDeal::get_code() {
const std::string value(GetHashData().c_str());
const auto& hex = string_to_hex(value);
const config::base16 data(hex);
const auto& hash = ripemd160_hash(sha256_hash(data));
return encode_base16(hash);
}
//--------------------------------------------------------------------------------------------------------------
CString CDeal::GetCode() {
return get_code();
}
//--------------------------------------------------------------------------------------------------------------
CString CDeal::GetHash() {
return sha256(GetHashData());
}
//--------------------------------------------------------------------------------------------------------------
wallet::ec_public CDeal::to_public_ek(uint8_t version) {
const auto& hash = get_hash();
const std::string seed(hash.substr(0, 48));
const std::string salt(hash.substr(48, 16));
const auto& token = Bitcoin::token_new(hash, base16(salt));
const auto& key = Bitcoin::ek_public(token, base16(seed), version);
return ek_public_to_ec(hash, key);
}
//--------------------------------------------------------------------------------------------------------------
wallet::payment_address CDeal::to_address_ek(uint8_t version) {
const auto& hash = get_hash();
const std::string seed(hash.substr(0, 48));
const std::string salt(hash.substr(48, 16));
const auto& token = Bitcoin::token_new(hash, base16(salt));
return Bitcoin::ek_address(token, base16(seed), version);
}
//--------------------------------------------------------------------------------------------------------------
wallet::ec_public CDeal::to_public_hd(uint64_t prefixes) {
const auto& hash = get_hash();
const auto& key = hd_new(base16(hash), prefixes);
const auto& public_key = key.to_public();
return public_key.point();
}
//--------------------------------------------------------------------------------------------------------------
wallet::payment_address CDeal::to_address_hd(uint64_t prefixes) {
const auto& key = to_public_hd(prefixes);
return key.to_payment_address();
}
//--------------------------------------------------------------------------------------------------------------
std::string CDeal::get_payment_ek(const std::string &key1, const std::string &key2, std::string &key3,
uint8_t version_key, uint8_t version_script) {
CWitness Witness(ec_public(key1), ec_public(key2), key3.empty() ? to_public_ek(version_key) : ec_public(key3));
if (key3.empty())
key3 = Witness.keys()[2].encoded();
const auto& address = Witness.to_address(version_script);
return address.encoded();
}
//--------------------------------------------------------------------------------------------------------------
std::string CDeal::get_payment_hd(const std::string &key1, const std::string &key2, std::string &key3,
uint64_t version_key, uint8_t version_script) {
CWitness Witness(ec_public(key1), ec_public(key2), key3.empty() ? to_public_hd(version_key) : ec_public(key3));
if (key3.empty())
key3 = Witness.keys()[2].encoded();
const auto& address = Witness.to_address(version_script);
return address.encoded();
}
//--------------------------------------------------------------------------------------------------------------
CString CDeal::GetPaymentEK(const CString &Key1, const CString &Key2, CString &Key3,
uint8_t version_key, uint8_t version_script) {
std::string key3(Key3);
const auto& payment = get_payment_ek(Key1.c_str(), Key2.c_str(), key3, version_key, version_script);
Key3 = key3;
return payment;
}
//--------------------------------------------------------------------------------------------------------------
CString CDeal::GetPaymentHD(const CString &Key1, const CString &Key2, CString &Key3, uint64_t version_key,
uint8_t version_script) {
std::string key3(Key3);
const auto& payment = get_payment_hd(Key1.c_str(), Key2.c_str(), key3, version_key, version_script);
Key3 = key3;
return payment;
}
//--------------------------------------------------------------------------------------------------------------
void CDeal::Parse(const YAML::Node &node) {
const auto& deal = node["deal"];
if (deal) {
m_Data.Order = StringToOrder(deal["order"].as<std::string>());
m_Data.Type = StringToType(deal["type"].as<std::string>());
m_Data.At = deal["at"].as<std::string>();
m_Data.Date = UTCFormat(deal["date"].as<std::string>());
const auto& seller = deal["seller"];
m_Data.Seller.Address = seller["address"].as<std::string>();
if (!valid_address(m_Data.Seller.Address))
throw ExceptionFrm("Invalid seller address: %s.", m_Data.Seller.Address.c_str());
if (seller["rating"])
m_Data.Seller.Rating = seller["rating"].as<std::string>();
if (seller["signature"])
m_Data.Seller.Signature = seller["signature"].as<std::string>();
const auto& customer = deal["customer"];
m_Data.Customer.Address = customer["address"].as<std::string>();
if (!valid_address(m_Data.Customer.Address))
throw ExceptionFrm("Invalid customer address: %s.", m_Data.Customer.Address.c_str());
if (customer["rating"])
m_Data.Customer.Rating = customer["rating"].as<std::string>();
if (customer["signature"])
m_Data.Customer.Signature = customer["signature"].as<std::string>();
const auto& payment = deal["payment"];
if (payment) {
if (payment["address"])
m_Data.Payment.Address = payment["address"].as<std::string>();
if (payment["until"])
m_Data.Payment.Until = UTCFormat(payment["until"].as<std::string>());
m_Data.Payment.Sum = BTCFormat(payment["sum"].as<std::string>());
}
const auto& feedback = deal["feedback"];
if (feedback) {
if (feedback["leave-before"])
m_Data.FeedBack.LeaveBefore = UTCFormat(feedback["leave-before"].as<std::string>());
if (feedback["status"])
m_Data.FeedBack.Status = StringToFeedBackStatus(feedback["status"].as<std::string>());
if (feedback["refund"])
m_Data.FeedBack.Refund = feedback["refund"].as<std::string>();
if (feedback["comments"])
m_Data.FeedBack.Comments = feedback["comments"].as<std::string>();
}
const auto& transaction = deal["transaction"];
if (transaction) {
m_Data.Transaction.Hex = transaction["hex"].as<std::string>();
}
const auto& error = deal["error"];
if (error) {
m_Data.Error.Message = error["message"].as<std::string>();
}
const CDateTime Date = StringToDate(m_Data.Date);
if (m_Data.Payment.Until.IsEmpty())
m_Data.Payment.Until = DateToString(Date + (CDateTime) 3600 / SecsPerDay); // 60 min
if (m_Data.FeedBack.LeaveBefore.IsEmpty())
m_Data.FeedBack.LeaveBefore = DateToString(Date + 1);
m_Data.Code = GetCode();
} else
throw ExceptionFrm("Invalid YAML format: Need node \"deal\".");
}
//--------------------------------------------------------------------------------------------------------------
void CDeal::SetOrder(YAML::Node &Node, CDealOrder Order) {
Node["deal"]["order"] = CDeal::OrderToString(Order).c_str();
}
//--------------------------------------------------------------------------------------------------------------
void CDeal::AddFeedback(YAML::Node &Node, CFeedBackStatus Status, const CString &Comments) {
YAML::Node Deal = Node["deal"];
YAML::Node Feedback = Deal["feedback"];
Feedback["status"] = CDeal::FeedBackStatusToString(Status).c_str();
if (!Comments.IsEmpty())
Feedback["comments"] = Comments.c_str();
}
//--------------------------------------------------------------------------------------------------------------
void CDeal::AddTransaction(YAML::Node &Node, const transaction &tx) {
YAML::Node Deal = Node["deal"];
YAML::Node Transaction = Deal["transaction"];
const auto& hex = encode_base16(tx.to_data(true, true));
Transaction["hex"] = hex;
DebugMessage("tx: %s\n", hex.c_str());
}
//--------------------------------------------------------------------------------------------------------------
void CDeal::AddError(YAML::Node &Node, const CString &Message) {
YAML::Node Deal = Node["deal"];
YAML::Node Error = Deal["error"];
Error["message"] = Message.c_str();
}
}
}
using namespace Apostol::Deal;
#ifdef __cplusplus
}
#endif // __cplusplus

308
src/app/Deal.hpp Normal file
View File

@@ -0,0 +1,308 @@
/*++
Program name:
BitDeals
Module Name:
Deal.hpp
Notices:
Apostol Core (Deal)
Author:
Copyright (c) Prepodobny Alen
mailto: alienufo@inbox.ru
mailto: ufocomp@gmail.com
--*/
#ifndef APOSTOL_DEAL_HPP
#define APOSTOL_DEAL_HPP
#include "yaml-cpp/yaml.h"
//----------------------------------------------------------------------------------------------------------------------
#ifdef __cplusplus
extern "C++" {
#endif // __cplusplus
namespace Apostol {
namespace Deal {
CString UTCFormat(const CString& Value);
CString BTCFormat(const CString& Value);
//--------------------------------------------------------------------------------------------------------------
double BTCToDouble(const CString &Value);
CString DoubleToBTC(const double &Value, const CString &Format = _T("%f BTC"));
CDateTime StringToDate(const CString &Value, const CString &Format = _T("%04d-%02d-%02d %02d:%02d:%02d"));
CString DateToString(const CDateTime &Value, const CString &Format = _T("%Y-%m-%d %H:%M:%S UTC"));
//--------------------------------------------------------------------------------------------------------------
//-- CRating ---------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
typedef struct CRating {
int Count;
int Positive;
CRating(): Count(0), Positive(0) {
}
CRating(const CRating &Rating): CRating() {
Assign(Rating);
}
void Assign(const CRating& Rating) {
this->Count = Rating.Count;
this->Positive = Rating.Positive;
};
int Compare(const CRating& Rating) const {
if (this->Count == Rating.Count)
return 0;
if (this->Count > Rating.Count)
return 1;
return -1;
};
void ToString(CString &String) const {
String.Clear();
int q = 1;
int c = Count;
while ((c = div(c, 10).quot > 10))
q++;
c = c * (int) pow(10, q);
if (Count == c)
String.Format("%d, %d%%", c, Positive);
else
String.Format("%d+, %d%%", c, Positive);
}
void Parse(const CString &Value);
CString GetString() const {
CString S;
ToString(S);
return S;
};
bool operator== (const CRating& R) const {
return Compare(R) == 0;
};
bool operator!= (const CRating& R) const {
return Compare(R) != 0;
};
bool operator< (const CRating& R) const {
return Compare(R) < 0;
};
bool operator<= (const CRating& R) const {
return Compare(R) <= 0;
};
bool operator> (const CRating& R) const {
return Compare(R) > 0;
};
bool operator>= (const CRating& R) const {
return Compare(R) >= 0;
};
CRating& operator= (const CRating& R) {
if (this != &R) {
Assign(R);
}
return *this;
};
CRating& operator= (const CString& S) {
Parse(S);
return *this;
};
CRating& operator<< (const CString& S) {
Parse(S);
return *this;
};
friend CString& operator>> (const CRating &LS, CString &RS) {
LS.ToString(RS);
return RS;
}
} CRating;
//--------------------------------------------------------------------------------------------------------------
//-- CDealData -------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
enum CDealType { dtPrepaid = 0, dtPostpaid };
//--------------------------------------------------------------------------------------------------------------
enum CFeedBackStatus { fsNegative = -1, fsNeutral = 0, fsPositive = 1 };
//--------------------------------------------------------------------------------------------------------------
enum CDealOrder { doCreate = 0, doCreated, doPay, doPaid, doComplete, doCompleted, doCancel, doCanceled,
doExecute, doExecuted, doDelete, doDeleted, doFail, doFailed, doFeedback };
//--------------------------------------------------------------------------------------------------------------
typedef struct DealData {
CDealOrder Order = doCreate;
CDealType Type = dtPrepaid;
// Hidden value
CString Code {};
CString At {};
CString Date {};
struct seller {
CString Address;
CRating Rating;
CString Signature;
} Seller;
struct customer {
CString Address;
CRating Rating;
CString Signature;
} Customer;
struct payment {
CString Address {};
CString Until {};
CString Sum {};
} Payment;
struct feedback {
CString LeaveBefore {};
CFeedBackStatus Status = fsNeutral;
CString Refund {};
CString Comments {};
} FeedBack;
struct transaction {
CString Fee {};
CString Key {};
CString Hex {};
} Transaction;
struct error {
CString Message {};
} Error;
CString GetStringData() const;
} CDealData, *PDealData;
//--------------------------------------------------------------------------------------------------------------
//-- CDeal -----------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
class CDeal {
private:
CDealData m_Data;
CString GetHashData();
protected:
std::string get_hash();
std::string get_code();
wallet::ec_public to_public_ek(uint8_t version = payment_address::mainnet_p2kh);
wallet::payment_address to_address_ek(uint8_t version = payment_address::mainnet_p2kh);
wallet::ec_public to_public_hd(uint64_t prefixes = hd_private::mainnet);
wallet::payment_address to_address_hd(uint64_t prefixes = hd_private::mainnet);
std::string get_payment_ek(const std::string &key1, const std::string &key2, std::string &key3,
uint8_t version_key = payment_address::mainnet_p2kh,
uint8_t version_script = payment_address::mainnet_p2sh);
std::string get_payment_hd(const std::string &key1, const std::string &key2, std::string &key3,
uint64_t version_key = hd_private::mainnet,
uint8_t version_script = payment_address::mainnet_p2sh);
public:
CDeal();
explicit CDeal(const YAML::Node &node);
void Parse(const YAML::Node &node);
CString GetHash();
CString GetCode();
CString GetPaymentEK(const CString &Key1, const CString &Key2, CString &Key3,
uint8_t version_key = payment_address::mainnet_p2kh,
uint8_t version_script = payment_address::mainnet_p2sh);
CString GetPaymentHD(const CString &Key1, const CString &Key2, CString &Key3,
uint64_t version_key = hd_private::mainnet,
uint8_t version_script = payment_address::mainnet_p2sh);
static CDealOrder StringToOrder(const CString &Value);
static CString OrderToString(CDealOrder Order);
static CDealType StringToType(const CString &Value);
static CString TypeToString(CDealType Type);
static CString TypeCodeToString(const CString &Code);
static CFeedBackStatus StringToFeedBackStatus(const CString &Value);
static CString FeedBackStatusToString(CFeedBackStatus Status);
CDealOrder Order() const { return m_Data.Order; }
void Order(CDealOrder Value) { m_Data.Order = Value; }
CDealData &Data() { return m_Data; }
const CDealData &Data() const { return m_Data; }
static void SetOrder(YAML::Node &Node, CDealOrder Order);
static void AddFeedback(YAML::Node &Node, CFeedBackStatus Status, const CString &Comments);
static void AddTransaction(YAML::Node &Node, const transaction &tx);
static void AddError(YAML::Node &Node, const CString &Message);
CDeal& operator<< (const YAML::Node &node) {
Parse(node);
return *this;
}
};
//--------------------------------------------------------------------------------------------------------------
}
}
using namespace Apostol::Deal;
#ifdef __cplusplus
}
#endif // __cplusplus
#endif //APOSTOL_DEAL_HPP

46
src/app/Header.hpp Normal file
View File

@@ -0,0 +1,46 @@
/*++
Program name:
ship-safety
Module Name:
Header.hpp
Notices:
Ship Safety Service
Author:
Copyright (c) Prepodobny Alen
mailto: alienufo@inbox.ru
mailto: ufocomp@gmail.com
--*/
#ifndef APOSTOL_HEADER_HPP
#define APOSTOL_HEADER_HPP
//----------------------------------------------------------------------------------------------------------------------
#include <wait.h>
#include <execinfo.h>
//----------------------------------------------------------------------------------------------------------------------
//using namespace std;
//----------------------------------------------------------------------------------------------------------------------
#include "delphi.hpp"
//----------------------------------------------------------------------------------------------------------------------
#include "PGP.hpp"
#include "Bitcoin.hpp"
#include "Deal.hpp"
//----------------------------------------------------------------------------------------------------------------------
#include "Core.hpp"
//----------------------------------------------------------------------------------------------------------------------
#endif //APOSTOL_HEADER_HPP

1050
src/app/PGP.cpp Normal file

File diff suppressed because it is too large Load Diff

403
src/app/PGP.hpp Normal file
View File

@@ -0,0 +1,403 @@
/*++
Module Name:
PGP.hpp
Notices:
PGP library
Author:
Copyright (c) Prepodobny Alen
mailto: alienufo@inbox.ru
mailto: ufocomp@gmail.com
--*/
#include "OpenPGP.h"
using namespace OpenPGP;
//----------------------------------------------------------------------------------------------------------------------
#ifdef USE_LIB_GCRYPT
#include <gcrypt.h>
//----------------------------------------------------------------------------------------------------------------------
#endif
#ifndef APOSTOL_PGP_HPP
#define APOSTOL_PGP_HPP
extern "C++" {
namespace Apostol {
namespace PGP {
typedef struct CPGPUserId {
CString Name;
CString Mail;
CString Desc;
} CPGPUserId, *PPGPUserId;
typedef TList<CPGPUserId> CPGPUserIdList;
class Key: public OpenPGP::Key {
public:
Key();
Key(const PGP & copy);
Key(const Key & copy);
Key(const std::string & data);
Key(std::istream & stream);
~Key() override = default;
// output style inspired by gpg and SKS Keyserver/pgp.mit.edu
std::string ListKeys(std::size_t indents = 0, std::size_t indent_size = 4) const;
void ExportUID(CPGPUserIdList &List) const;
};
bool TryCleartextSignature(const CString& Key, const CString &Pass, const CString &Hash, const CString& ClearText,
CString& SignText);
void CleartextSignature(const CString& Key, const CString &Pass, const CString &Hash, const CString& ClearText,
CString& SignText);
#ifdef USE_LIB_GCRYPT
class CPGP;
extern CPGP *GPGP;
//--------------------------------------------------------------------------------------------------------------
typedef std::function<void (CPGP *Sender, LPCTSTR AFormat, va_list args)> COnPGPVerboseEvent;
//--------------------------------------------------------------------------------------------------------------
class EPGPError: public Delphi::Exception::Exception {
typedef Delphi::Exception::Exception inherited;
private:
int m_LastError;
public:
EPGPError() : inherited(), m_LastError(GPG_ERR_NO_ERROR) {};
EPGPError(int Error, LPCTSTR lpFormat) : inherited(lpFormat) {
m_LastError = Error;
};
explicit EPGPError(LPCTSTR lpFormat, ...): m_LastError(GPG_ERR_NO_ERROR), inherited() {
va_list argList;
va_start(argList, lpFormat);
FormatMessage(lpFormat, argList);
va_end(argList);
};
~EPGPError() override = default;
int GetLastError() { return m_LastError; }
};
//--------------------------------------------------------------------------------------------------------------
class CPGPComponent {
public:
CPGPComponent();
~CPGPComponent();
}; // CPGPComponent
//--------------------------------------------------------------------------------------------------------------
//-- CPGP ------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
class CPGP: public CObject {
private:
COnPGPVerboseEvent m_OnVerbose;
protected:
gcry_error_t m_LastError;
virtual void DoVerbose(LPCTSTR AFormat, va_list args);
public:
CPGP();
~CPGP() override = default;
inline static class CPGP *CreatePGP() { return GPGP = new CPGP(); };
inline static void DeletePGP() { delete GPGP; };
static void Initialize();
bool CheckForCipherError(gcry_error_t err);
bool CheckForCipherError(gcry_error_t err, int const ignore[], int count);
void RaiseCipherError(gcry_error_t err);
void Verbose(LPCSTR AFormat, ...);
void Verbose(LPCSTR AFormat, va_list args);
gcry_error_t LastError() const { return m_LastError; };
const COnPGPVerboseEvent &OnVerbose() const { return m_OnVerbose; }
void OnVerbose(COnPGPVerboseEvent && Value) { m_OnVerbose = Value; }
};
//--------------------------------------------------------------------------------------------------------------
//-- CPGPCipher ------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
class CPGPCipher: public CPGPComponent {
private:
gcry_cipher_hd_t m_Handle;
public:
CPGPCipher();
gcry_cipher_hd_t Handle() { return m_Handle; };
gcry_cipher_hd_t *Ptr() { return &m_Handle; };
bool Open(int algo, int mode, unsigned int flags);
void Close();
bool SetKey(const void *key, size_t keylen);
bool SetIV(const void *iv, size_t ivlen);
bool SetCTR(const void *ctr, size_t ctrlen);
bool Reset();
bool Authenticate(const void *abuf, size_t abuflen);
bool GetTag(void *tag, size_t taglen);
bool CheckTag(gcry_cipher_hd_t h, const void *tag, size_t taglen);
bool Encrypt(unsigned char *out, size_t outsize, const unsigned char *in, size_t inlen);
bool Decrypt(unsigned char *out, size_t outsize, const unsigned char *in, size_t inlen);
bool Final();
bool Sync();
bool Ctl(int cmd, void *buffer, size_t buflen);
bool Info(gcry_cipher_hd_t h, int what, void *buffer, size_t *nbytes);
};
//--------------------------------------------------------------------------------------------------------------
//-- CPGPAlgo --------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
class CPGPAlgo: public CPGPComponent {
public:
CPGPAlgo();
bool Info(int algo, int what, void *buffer, size_t *nbytes);
size_t KeyLen(int algo);
size_t BlkLen(int algo);
const char *Name(int algo);
int MapName(const char *name);
int ModeFromOid(const char *string);
};
//--------------------------------------------------------------------------------------------------------------
//-- CPGPMPI ---------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
class CPGPMPI: public CPGPComponent {
protected:
gcry_mpi_t m_Handle;
public:
CPGPMPI();
CPGPMPI(const CPGPMPI &Value) {
m_Handle = Value.m_Handle;
};
explicit CPGPMPI(gcry_mpi_t AHandle) {
m_Handle = AHandle;
};
~CPGPMPI() = default;
gcry_mpi_t Handle() { return m_Handle; };
void New(unsigned int nbits);
void SNew(unsigned int nbits);
void Copy(const gcry_mpi_t a);
void Release();
gcry_mpi_t Set(const gcry_mpi_t u);
gcry_mpi_t SetUI(unsigned long u);
void Swap(gcry_mpi_t b);
void Snatch(const gcry_mpi_t u);
void Neg(gcry_mpi_t u);
void Abs();
int Cmp(const gcry_mpi_t v) const;
int CmpUI(unsigned long v) const;
int IsNeg() const;
bool Scan (enum gcry_mpi_format format, const unsigned char *buffer, size_t buflen, size_t *nscanned);
bool Print (enum gcry_mpi_format format, unsigned char *buffer, size_t buflen, size_t *nwritten) const;
bool APrint(enum gcry_mpi_format format, unsigned char **buffer, size_t *nbytes) const;
void Dump();
};
//--------------------------------------------------------------------------------------------------------------
//-- CPGPSexp --------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
class CPGPSexp: public CPGPComponent {
protected:
gcry_sexp_t m_Handle;
public:
CPGPSexp();
CPGPSexp(const CPGPSexp& Value) {
m_Handle = Value.m_Handle;
};
explicit CPGPSexp(gcry_sexp_t AHandle) {
m_Handle = AHandle;
};
~CPGPSexp();
gcry_sexp_t Handle() { return m_Handle; };
bool New(const void *buffer, size_t length, int autodetect);
bool Create(void *buffer, size_t length, int autodetect, void (*freefnc)(void*));
bool Sscan(size_t *erroff, const char *buffer, size_t length);
bool Build(size_t *erroff, const char *format, ...);
size_t Sprint(int mode, char *buffer, size_t maxlength);
void Release();
void Dump();
static size_t CanonLen(const unsigned char *buffer, size_t length, size_t *erroff, gcry_error_t *errcode);
gcry_sexp_t FindToken(const char *token, size_t toklen);
int Length();
gcry_sexp_t Nth(int number);
gcry_sexp_t Car();
gcry_sexp_t Cdr();
const char *NthData(int number, size_t *datalen);
void *NthBuffer(int number, size_t *rlength);
char *NthString(int number);
gcry_mpi_t NthMPI(int number, int mpifmt);
};
//--------------------------------------------------------------------------------------------------------------
//-- CPGPKey ---------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------
class CPGPKey: public CPGPSexp {
public:
CPGPKey(): CPGPSexp() {
};
CPGPKey(const CPGPKey& Value) = default;
explicit CPGPKey(gcry_sexp_t AHandle): CPGPSexp(AHandle) {
};
bool TestKey ();
static bool AlgoInfo (int algo, int what, void *buffer, size_t *nbytes);
static bool Ctl (int cmd, void *buffer, size_t buflen);
bool GenKey (gcry_sexp_t parms);
bool PubKeyGetSexp(int mode, gcry_ctx_t ctx);
unsigned int GetNBits ();
unsigned char * KeyGrip (unsigned char *array);
bool Encrypt(gcry_sexp_t data, gcry_sexp_t pkey);
bool Decrypt(gcry_sexp_t data, gcry_sexp_t skey);
bool Sign(gcry_sexp_t data, gcry_sexp_t skey);
bool Verify(gcry_sexp_t data, gcry_sexp_t pkey);
static const char * AlgoName(int algo);
static int MapName (const char *name);
static int TestAlgo (int algo);
};
//--------------------------------------------------------------------------------------------------------------
void check_rsa_keys(COnPGPVerboseEvent && Verbose = nullptr);
void load_key(const char *KeyFile, const char* Passwd, COnPGPVerboseEvent &&Verbose = nullptr);
#endif
}
}
using namespace Apostol::PGP;
}
#endif //APOSTOL_PGP_HPP

264
src/app/dm.cpp Normal file
View File

@@ -0,0 +1,264 @@
/*++
Program name:
deal-module
Module Name:
DealModule.cpp
Notices:
Bitcoin Payment Service (Deal Module)
Author:
Copyright (c) Prepodobny Alen
mailto: alienufo@inbox.ru
mailto: ufocomp@gmail.com
--*/
#include "dm.hpp"
//----------------------------------------------------------------------------------------------------------------------
#define exit_failure(msg) { \
if (GLog != nullptr) \
GLog->Error(APP_LOG_EMERG, 0, msg); \
else \
std::cerr << APP_NAME << ": " << (msg) << std::endl; \
exitcode = EXIT_FAILURE; \
}
//----------------------------------------------------------------------------------------------------------------------
extern "C++" {
namespace Apostol {
namespace DealModule {
void CDealModule::ShowVersionInfo() {
std::cerr << APP_NAME " version: " APP_VERSION " (" APP_DESCRIPTION ")" LINEFEED << std::endl;
if (Config()->Flags().show_help) {
std::cerr << "Usage: " APP_NAME << " [-?hvVt] [-s signal] [-c filename]"
" [-p prefix] [-g directives]" LINEFEED
LINEFEED
"Options:" LINEFEED
" -?,-h : this help" LINEFEED
" -v : show version and exit" LINEFEED
" -V : show version and configure options then exit" LINEFEED
" -t : test configuration and exit" LINEFEED
" -s signal : send signal to a master process: stop, quit, reopen, reload" LINEFEED
#ifdef APP_PREFIX
" -p prefix : set prefix path (default: " APP_PREFIX ")" LINEFEED
#else
" -p prefix : set prefix path (default: NONE)" LINEFEED
#endif
" -c filename : set configuration file (default: " APP_CONF_FILE ")" LINEFEED
" -g directives : set global directives out of configuration file" LINEFEED
" -l locale : set locale (default: " APP_DEFAULT_LOCALE ")" LINEFEED
<< std::endl;
}
}
//--------------------------------------------------------------------------------------------------------------
void CDealModule::ParseCmdLine() {
LPCTSTR P;
for (int i = 1; i < argc(); ++i) {
P = argv()[i].c_str();
if (*P++ != '-') {
throw Delphi::Exception::ExceptionFrm(_T("invalid option: \"%s\""), P);
}
while (*P) {
switch (*P++) {
case '?':
case 'h':
Config()->Flags().show_version = true;
Config()->Flags().show_help = true;
break;
case 'v':
Config()->Flags().show_version = true;
break;
case 'V':
Config()->Flags().show_version = true;
Config()->Flags().show_configure = true;
break;
case 't':
Config()->Flags().test_config = true;
break;
case 'p':
if (*P) {
Config()->Prefix(P);
goto next;
}
if (!argv()[++i].empty()) {
Config()->Prefix(argv()[i]);
goto next;
}
throw Delphi::Exception::Exception(_T("option \"-p\" requires directory name"));
case 'c':
if (*P) {
Config()->ConfFile(P);
goto next;
}
if (!argv()[++i].empty()) {
Config()->ConfFile(argv()[i]);
goto next;
}
throw Delphi::Exception::Exception(_T("option \"-c\" requires file name"));
case 'g':
if (*P) {
Config()->ConfParam(P);
goto next;
}
if (!argv()[++i].empty()) {
Config()->ConfParam(argv()[i]);
goto next;
}
throw Delphi::Exception::Exception(_T("option \"-g\" requires parameter"));
case 's':
if (*P) {
Config()->Signal(P);
} else if (!argv()[++i].empty()) {
Config()->Signal(argv()[i]);
} else {
throw Delphi::Exception::Exception(_T("option \"-s\" requires parameter"));
}
if ( Config()->Signal() == "stop"
|| Config()->Signal() == "quit"
|| Config()->Signal() == "reopen"
|| Config()->Signal() == "reload")
{
ProcessType(ptSignaller);
goto next;
}
throw Delphi::Exception::ExceptionFrm(_T("invalid option: \"-s %s\""), Config()->Signal().c_str());
case 'l':
if (*P) {
Config()->Locale(P);
goto next;
}
if (!argv()[++i].empty()) {
Config()->Locale(argv()[i]);
goto next;
}
throw Delphi::Exception::Exception(_T("option \"-l\" requires locale"));
default:
throw Delphi::Exception::ExceptionFrm(_T("invalid option: \"%c\""), *(P - 1));
}
}
next:
continue;
}
}
//--------------------------------------------------------------------------------------------------------------
void CDealModule::StartProcess() {
if (Config()->Helper()) {
m_ProcessType = ptHelper;
}
CIniFile Bitcoin(Config()->ConfPrefix() + "bitcoin.conf");
if (Bitcoin.ReadBool("main", "testnet", false)) {
BitcoinConfig.endpoint = "tcp://testnet.libbitcoin.net:19091";
BitcoinConfig.version_hd = hd_private::testnet;
BitcoinConfig.version_ec = ec_private::testnet;
BitcoinConfig.version_key = payment_address::testnet_p2kh;
BitcoinConfig.version_script = payment_address::testnet_p2sh;
BitcoinConfig.min_output = 1000;
BitcoinConfig.Miner.Fee = "3000";
BitcoinConfig.Symbol = "tBTC";
} else {
BitcoinConfig.endpoint = Bitcoin.ReadString("endpoint", "url", BitcoinConfig.endpoint);
BitcoinConfig.Miner.Fee = Bitcoin.ReadString("miner", "fee", "1%");
BitcoinConfig.Miner.min = Bitcoin.ReadInteger("miner", "min", 200);
BitcoinConfig.Miner.max = Bitcoin.ReadInteger("miner", "max", 2000);
BitcoinConfig.min_output = Bitcoin.ReadInteger("transaction", "min_output", 200);
if (BitcoinConfig.Miner.min < 0)
BitcoinConfig.Miner.min = 0;
if (BitcoinConfig.Miner.max < 0)
BitcoinConfig.Miner.max = 0;
if (BitcoinConfig.Miner.min > BitcoinConfig.Miner.max)
BitcoinConfig.Miner.min = BitcoinConfig.Miner.max;
}
CApplication::StartProcess();
}
//--------------------------------------------------------------------------------------------------------------
void CDealModule::Run() {
CApplication::Run();
}
//--------------------------------------------------------------------------------------------------------------
}
}
}
//----------------------------------------------------------------------------------------------------------------------
int main(int argc, char *argv[]) {
int exitcode;
DefaultLocale.SetLocale("");
CDealModule dm(argc, argv);
try
{
dm.Name() = APP_NAME;
dm.Description() = APP_DESCRIPTION;
dm.Version() = APP_VERSION;
dm.Title() = APP_VER;
dm.Run();
exitcode = dm.ExitCode();
}
catch (std::exception& e)
{
exit_failure(e.what());
}
catch (...)
{
exit_failure("Unknown error...");
}
exit(exitcode);
}
//----------------------------------------------------------------------------------------------------------------------

75
src/app/dm.hpp Normal file
View File

@@ -0,0 +1,75 @@
/*++
Program name:
dm
Module Name:
dm.hpp
Notices:
BitDeals Payment Service (Deal Module)
Author:
Copyright (c) Prepodobny Alen
mailto: alienufo@inbox.ru
mailto: ufocomp@gmail.com
--*/
#ifndef APOSTOL_APOSTOL_HPP
#define APOSTOL_APOSTOL_HPP
#include "../../version.h"
//----------------------------------------------------------------------------------------------------------------------
#define APP_VERSION AUTO_VERSION
#define APP_VER APP_NAME "/" APP_VERSION
//----------------------------------------------------------------------------------------------------------------------
#include "Header.hpp"
//----------------------------------------------------------------------------------------------------------------------
extern "C++" {
namespace Apostol {
namespace DealModule {
class CDealModule: public CApplication {
protected:
void ParseCmdLine() override;
void ShowVersionInfo() override;
void StartProcess() override;
public:
CDealModule(int argc, char *const *argv): CApplication(argc, argv) {
};
~CDealModule() override = default;
static class CDealModule *Create(int argc, char *const *argv) {
return new CDealModule(argc, argv);
};
inline void Destroy() override { delete this; };
void Run() override;
};
}
}
using namespace Apostol::DealModule;
}
#endif //APOSTOL_APOSTOL_HPP