Committing updates.
This commit is contained in:
1441
src/app/Bitcoin.cpp
Normal file
1441
src/app/Bitcoin.cpp
Normal file
File diff suppressed because it is too large
Load Diff
733
src/app/Bitcoin.hpp
Normal file
733
src/app/Bitcoin.hpp
Normal 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
532
src/app/Deal.cpp
Normal 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
308
src/app/Deal.hpp
Normal 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
46
src/app/Header.hpp
Normal 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
1050
src/app/PGP.cpp
Normal file
File diff suppressed because it is too large
Load Diff
403
src/app/PGP.hpp
Normal file
403
src/app/PGP.hpp
Normal 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
264
src/app/dm.cpp
Normal 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
75
src/app/dm.hpp
Normal 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
|
||||
|
||||
Reference in New Issue
Block a user