Commit 22520a6d authored by Pierre Kim's avatar Pierre Kim

Initial commit

parents
.DS_Store
/build
/tags
/cryptonote.dir
/manateecoin.dir
/x64
\ No newline at end of file
This diff is collapsed.
set(CN_PROJECT_NAME "manateecoin")
set(CN_CURRENCY_DISPLAY_NAME "ManateeCoin")
set(CN_CURRENCY_TICKER "MTC")
**1. Clone wallet sources**
```
git clone https://github.com/manateecoin/cryptonotewallet.git
```
**2. Set symbolic link to coin sources at the same level as `src`. For example:**
```
ln -s ../cryptonote cryptonote
```
**3. Build**
```
mkdir build && cd build && cmake .. && make
```
// Copyright (c) 2011-2015 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <Common/Util.h>
#include <CryptoNoteConfig.h>
#include "CommandLineParser.h"
namespace WalletGui {
CommandLineParser::CommandLineParser(QObject* _parent) : QObject(_parent), m_parser(), m_helpOption(m_parser.addHelpOption()),
m_versionOption(m_parser.addVersionOption()),
m_testnetOption("testnet", tr("Used to deploy test nets. Checkpoints and hardcoded seeds are ignored, network id is changed. "
"Use it with –data-dir flag. The wallet must be launched with –testnet flag")),
m_p2pBindIpOption("p2p-bind-ip", tr("Interface for p2p network protocol"), tr("ip"), "0.0.0.0"),
m_p2pBindPortOption("p2p-bind-port", tr("Port for p2p network protocol"), tr("port"), QString::number(CryptoNote::P2P_DEFAULT_PORT)),
m_p2pExternalOption("p2p-external-port", tr("xternal port for p2p network protocol (if port forwarding used with NAT)"),
tr("port"), 0),
m_allowLocalIpOption("allow-local-ip", tr("Allow local ip add to peer list, mostly in debug purposes")),
m_addPeerOption("add-peer", tr("Manually add peer to local peerlist"), tr("peer")),
m_addPriorityNodeOption("add-priority-node", tr("Specify list of peers to connect to and attempt to keep the connection open"),
tr("node")),
m_addExclusiveNodeOption("add-exclusive-node", tr("Specify list of peers to connect to only. If this option is given the options "
"add-priority-node and seed-node are ignored"), tr("node")),
m_seedNodeOption("seed-node", tr("Connect to a node to retrieve peer addresses, and disconnect"), tr("node")),
m_hideMyPortOption("hide-my-port", tr("Do not announce yourself as peerlist candidate")),
m_dataDirOption("data-dir", tr("Specify data directory"), tr("directory"), QString::fromStdString(Tools::getDefaultDataDirectory())),
m_minimized("minimized", tr("Run application in minimized mode")) {
m_parser.setApplicationDescription(tr("Bytecoin wallet"));
m_parser.addHelpOption();
m_parser.addVersionOption();
m_parser.addOption(m_testnetOption);
m_parser.addOption(m_p2pBindIpOption);
m_parser.addOption(m_p2pBindPortOption);
m_parser.addOption(m_p2pExternalOption);
m_parser.addOption(m_allowLocalIpOption);
m_parser.addOption(m_addPeerOption);
m_parser.addOption(m_addPriorityNodeOption);
m_parser.addOption(m_addExclusiveNodeOption);
m_parser.addOption(m_seedNodeOption);
m_parser.addOption(m_hideMyPortOption);
m_parser.addOption(m_dataDirOption);
m_parser.addOption(m_minimized);
}
CommandLineParser::~CommandLineParser() {
}
bool CommandLineParser::process(const QStringList& _argv) {
#ifdef Q_OS_WIN
return m_parser.parse(_argv);
#else
m_parser.process(_argv);
return true;
#endif
}
bool CommandLineParser::hasHelpOption() const {
return m_parser.isSet(m_helpOption);
}
bool CommandLineParser::hasMinimizedOption() const {
return m_parser.isSet(m_minimized);
}
bool CommandLineParser::hasVersionOption() const {
return m_parser.isSet(m_versionOption);
}
bool CommandLineParser::hasTestnetOption() const {
return m_parser.isSet(m_testnetOption);
}
bool CommandLineParser::hasAllowLocalIpOption() const {
return m_parser.isSet(m_allowLocalIpOption);
}
bool CommandLineParser::hasHideMyPortOption() const {
return m_parser.isSet(m_hideMyPortOption);
}
QString CommandLineParser::getErrorText() const {
return m_parser.errorText();
}
QString CommandLineParser::getHelpText() const {
return m_parser.helpText();
}
QString CommandLineParser::getP2pBindIp() const {
return m_parser.value(m_p2pBindIpOption);
}
quint16 CommandLineParser::getP2pBindPort() const {
return m_parser.value(m_p2pBindPortOption).toUShort();
}
quint16 CommandLineParser::getP2pExternalPort() const {
return m_parser.value(m_p2pExternalOption).toUShort();
}
QStringList CommandLineParser::getPeers() const {
return m_parser.values(m_addPeerOption);
}
QStringList CommandLineParser::getPiorityNodes() const {
return m_parser.values(m_addPriorityNodeOption);
}
QStringList CommandLineParser::getExclusiveNodes() const {
return m_parser.values(m_addExclusiveNodeOption);
}
QStringList CommandLineParser::getSeedNodes() const {
return m_parser.values(m_seedNodeOption);
}
QString CommandLineParser::getDataDir() const {
return m_parser.value(m_dataDirOption);
}
}
// Copyright (c) 2011-2015 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#pragma once
#include <QCommandLineParser>
#include <QObject>
namespace WalletGui {
class CommandLineParser : public QObject {
Q_OBJECT
public:
CommandLineParser(QObject* _parent);
~CommandLineParser();
bool process(const QStringList& _argv);
bool hasHelpOption() const;
bool hasVersionOption() const;
bool hasTestnetOption() const;
bool hasMinimizedOption() const;
bool hasAllowLocalIpOption() const;
bool hasHideMyPortOption() const;
QString getErrorText() const;
QString getHelpText() const;
QString getP2pBindIp() const;
quint16 getP2pBindPort() const;
quint16 getP2pExternalPort() const;
QStringList getPeers() const;
QStringList getPiorityNodes() const;
QStringList getExclusiveNodes() const;
QStringList getSeedNodes() const;
QString getDataDir() const;
private:
QCommandLineParser m_parser;
QCommandLineOption m_helpOption;
QCommandLineOption m_versionOption;
QCommandLineOption m_testnetOption;
QCommandLineOption m_p2pBindIpOption;
QCommandLineOption m_p2pBindPortOption;
QCommandLineOption m_p2pExternalOption;
QCommandLineOption m_allowLocalIpOption;
QCommandLineOption m_addPeerOption;
QCommandLineOption m_addPriorityNodeOption;
QCommandLineOption m_addExclusiveNodeOption;
QCommandLineOption m_seedNodeOption;
QCommandLineOption m_hideMyPortOption;
QCommandLineOption m_dataDirOption;
QCommandLineOption m_minimized;
};
}
#pragma once
namespace WalletGui {
const char WALLET_CURRENCY_DISPLAY_NAME[] = "@CN_CURRENCY_DISPLAY_NAME@";
const char WALLET_CURRENCY_TICKER[] = "@CN_CURRENCY_TICKER@";
}
// Copyright (c) 2011-2015 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "CryptoNoteWrapper.h"
#include "CryptoNoteCore/CryptoNoteBasicImpl.h"
#include "CryptoNoteCore/CryptoNoteFormatUtils.h"
#include "CryptoNoteCore/Currency.h"
#include "NodeRpcProxy/NodeRpcProxy.h"
#include "CryptoNoteCore/CoreConfig.h"
#include "P2p/NetNodeConfig.h"
#include "CryptoNoteCore/Core.h"
#include "CryptoNoteProtocol/CryptoNoteProtocolHandler.h"
#include "InProcessNode/InProcessNode.h"
#include "P2p/NetNode.h"
#include "WalletLegacy/WalletLegacy.h"
#include "Logging/LoggerManager.h"
#include "System/Dispatcher.h"
namespace WalletGui {
namespace {
bool parsePaymentId(const std::string& payment_id_str, Crypto::Hash& payment_id) {
return CryptoNote::parsePaymentId(payment_id_str, payment_id);
}
std::string convertPaymentId(const std::string& paymentIdString) {
if (paymentIdString.empty()) {
return "";
}
Crypto::Hash paymentId;
if (!parsePaymentId(paymentIdString, paymentId)) {
std::stringstream errorStr;
errorStr << "Payment id has invalid format: \"" + paymentIdString + "\", expected 64-character string";
throw std::runtime_error(errorStr.str());
}
std::vector<uint8_t> extra;
CryptoNote::BinaryArray extraNonce;
CryptoNote::setPaymentIdToTransactionExtraNonce(extraNonce, paymentId);
if (!CryptoNote::addExtraNonceToTransactionExtra(extra, extraNonce)) {
std::stringstream errorStr;
errorStr << "Something went wrong with payment_id. Please check its format: \"" + paymentIdString + "\", expected 64-character string";
throw std::runtime_error(errorStr.str());
}
return std::string(extra.begin(), extra.end());
}
std::string extractPaymentId(const std::string& extra) {
std::vector<CryptoNote::TransactionExtraField> extraFields;
std::vector<uint8_t> extraVector;
std::copy(extra.begin(), extra.end(), std::back_inserter(extraVector));
if (!CryptoNote::parseTransactionExtra(extraVector, extraFields)) {
throw std::runtime_error("Can't parse extra");
}
std::string result;
CryptoNote::TransactionExtraNonce extraNonce;
if (CryptoNote::findTransactionExtraFieldByType(extraFields, extraNonce)) {
Crypto::Hash paymentIdHash;
if (CryptoNote::getPaymentIdFromTransactionExtraNonce(extraNonce.nonce, paymentIdHash)) {
unsigned char* buff = reinterpret_cast<unsigned char *>(&paymentIdHash);
for (size_t i = 0; i < sizeof(paymentIdHash); ++i) {
result.push_back("0123456789ABCDEF"[buff[i] >> 4]);
result.push_back("0123456789ABCDEF"[buff[i] & 15]);
}
}
}
return result;
}
}
Node::~Node() {
}
class RpcNode : CryptoNote::INodeObserver, public Node {
public:
RpcNode(const CryptoNote::Currency& currency, INodeCallback& callback, const std::string& nodeHost, unsigned short nodePort) :
m_callback(callback),
m_currency(currency),
m_node(nodeHost, nodePort) {
m_node.addObserver(this);
}
~RpcNode() override {
}
void init(const std::function<void(std::error_code)>& callback) override {
m_node.init(callback);
}
void deinit() override {
}
std::string convertPaymentId(const std::string& paymentIdString) override {
return WalletGui::convertPaymentId(paymentIdString);
}
std::string extractPaymentId(const std::string& extra) override {
return WalletGui::extractPaymentId(extra);
}
uint64_t getLastKnownBlockHeight() const override {
return m_node.getLastKnownBlockHeight();
}
uint64_t getLastLocalBlockHeight() const override {
return m_node.getLastLocalBlockHeight();
}
uint64_t getLastLocalBlockTimestamp() const override {
return m_node.getLastLocalBlockTimestamp();
}
uint64_t getPeerCount() const override {
return m_node.getPeerCount();
}
CryptoNote::IWalletLegacy* createWallet() override {
return new CryptoNote::WalletLegacy(m_currency, m_node);
}
private:
INodeCallback& m_callback;
const CryptoNote::Currency& m_currency;
CryptoNote::NodeRpcProxy m_node;
void peerCountUpdated(size_t count) {
m_callback.peerCountUpdated(*this, count);
}
void localBlockchainUpdated(uint64_t height) {
m_callback.localBlockchainUpdated(*this, height);
}
void lastKnownBlockHeightUpdated(uint64_t height) {
m_callback.lastKnownBlockHeightUpdated(*this, height);
}
};
class InprocessNode : CryptoNote::INodeObserver, public Node {
public:
InprocessNode(const CryptoNote::Currency& currency, Logging::LoggerManager& logManager, const CryptoNote::CoreConfig& coreConfig,
const CryptoNote::NetNodeConfig& netNodeConfig, INodeCallback& callback) :
m_currency(currency), m_dispatcher(),
m_callback(callback),
m_coreConfig(coreConfig),
m_netNodeConfig(netNodeConfig),
m_protocolHandler(currency, m_dispatcher, m_core, nullptr, logManager),
m_core(currency, &m_protocolHandler, logManager),
m_nodeServer(m_dispatcher, m_protocolHandler, logManager),
m_node(m_core, m_protocolHandler) {
m_core.set_cryptonote_protocol(&m_protocolHandler);
m_protocolHandler.set_p2p_endpoint(&m_nodeServer);
CryptoNote::Checkpoints checkpoints(logManager);
for (const CryptoNote::CheckpointData& checkpoint : CryptoNote::CHECKPOINTS) {
checkpoints.add_checkpoint(checkpoint.height, checkpoint.blockId);
}
}
~InprocessNode() override {
}
void init(const std::function<void(std::error_code)>& callback) override {
try {
if (!m_core.init(m_coreConfig, CryptoNote::MinerConfig(), true)) {
callback(make_error_code(CryptoNote::error::NOT_INITIALIZED));
return;
}
if (!m_nodeServer.init(m_netNodeConfig)) {
callback(make_error_code(CryptoNote::error::NOT_INITIALIZED));
return;
}
} catch (std::runtime_error& _err) {
callback(make_error_code(CryptoNote::error::NOT_INITIALIZED));
return;
}
m_node.init([this, callback](std::error_code ec) {
m_node.addObserver(this);
callback(ec);
});
m_nodeServer.run();
m_nodeServer.deinit();
m_node.shutdown();
}
void deinit() override {
m_nodeServer.sendStopSignal();
}
std::string convertPaymentId(const std::string& paymentIdString) override {
return WalletGui::convertPaymentId(paymentIdString);
}
std::string extractPaymentId(const std::string& extra) override {
return WalletGui::extractPaymentId(extra);
}
uint64_t getLastKnownBlockHeight() const override {
return m_node.getLastKnownBlockHeight();
}
uint64_t getLastLocalBlockHeight() const override {
return m_node.getLastLocalBlockHeight();
}
uint64_t getLastLocalBlockTimestamp() const override {
return m_node.getLastLocalBlockTimestamp();
}
uint64_t getPeerCount() const override {
return m_node.getPeerCount();
}
CryptoNote::IWalletLegacy* createWallet() override {
return new CryptoNote::WalletLegacy(m_currency, m_node);
}
private:
INodeCallback& m_callback;
const CryptoNote::Currency& m_currency;
System::Dispatcher m_dispatcher;
CryptoNote::CoreConfig m_coreConfig;
CryptoNote::NetNodeConfig m_netNodeConfig;
CryptoNote::core m_core;
CryptoNote::CryptoNoteProtocolHandler m_protocolHandler;
CryptoNote::NodeServer m_nodeServer;
CryptoNote::InProcessNode m_node;
std::future<bool> m_nodeServerFuture;
void peerCountUpdated(size_t count) {
m_callback.peerCountUpdated(*this, count);
}
void localBlockchainUpdated(uint64_t height) {
m_callback.localBlockchainUpdated(*this, height);
}
void lastKnownBlockHeightUpdated(uint64_t height) {
m_callback.lastKnownBlockHeightUpdated(*this, height);
}
};
Node* createRpcNode(const CryptoNote::Currency& currency, INodeCallback& callback, const std::string& nodeHost, unsigned short nodePort) {
return new RpcNode(currency, callback, nodeHost, nodePort);
}
Node* createInprocessNode(const CryptoNote::Currency& currency, Logging::LoggerManager& logManager,
const CryptoNote::CoreConfig& coreConfig, const CryptoNote::NetNodeConfig& netNodeConfig, INodeCallback& callback) {
return new InprocessNode(currency, logManager, coreConfig, netNodeConfig, callback);
}
}
// Copyright (c) 2011-2015 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#pragma once
#include <functional>
#include <memory>
#include <string>
#include <system_error>
namespace CryptoNote {
class INode;
class IWalletLegacy;
class Currency;
class CoreConfig;
class NetNodeConfig;
}
namespace Logging {
class LoggerManager;
}
namespace WalletGui {
class Node {
public:
virtual ~Node() = 0;
virtual void init(const std::function<void(std::error_code)>& callback) = 0;
virtual void deinit() = 0;
virtual std::string convertPaymentId(const std::string& paymentIdString) = 0;
virtual std::string extractPaymentId(const std::string& extra) = 0;
virtual uint64_t getLastKnownBlockHeight() const = 0;
virtual uint64_t getLastLocalBlockHeight() const = 0;
virtual uint64_t getLastLocalBlockTimestamp() const = 0;
virtual uint64_t getPeerCount() const = 0;
virtual CryptoNote::IWalletLegacy* createWallet() = 0;
};
class INodeCallback {
public:
virtual void peerCountUpdated(Node& node, size_t count) = 0;
virtual void localBlockchainUpdated(Node& node, uint64_t height) = 0;
virtual void lastKnownBlockHeightUpdated(Node& node, uint64_t height) = 0;
};
Node* createRpcNode(const CryptoNote::Currency& currency, INodeCallback& callback, const std::string& nodeHost, unsigned short nodePort);
Node* createInprocessNode(const CryptoNote::Currency& currency, Logging::LoggerManager& logManager,
const CryptoNote::CoreConfig& coreConfig, const CryptoNote::NetNodeConfig& netNodeConfig, INodeCallback& callback);
}
// Copyright (c) 2011-2015 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "CurrencyAdapter.h"
#include "CryptoNoteWalletConfig.h"
#include "LoggerAdapter.h"
namespace WalletGui {
CurrencyAdapter& CurrencyAdapter::instance() {
static CurrencyAdapter inst;
return inst;
}
CurrencyAdapter::CurrencyAdapter() : m_currency(CryptoNote::CurrencyBuilder(LoggerAdapter::instance().getLoggerManager()).currency()) {
}
CurrencyAdapter::~CurrencyAdapter() {
}
const CryptoNote::Currency& CurrencyAdapter::getCurrency() {
return m_currency;
}
quintptr CurrencyAdapter::getNumberOfDecimalPlaces() const {
return m_currency.numberOfDecimalPlaces();
}
QString CurrencyAdapter::getCurrencyDisplayName() const {
return WALLET_CURRENCY_DISPLAY_NAME;
}
QString CurrencyAdapter::getCurrencyName() const {
return CryptoNote::CRYPTONOTE_NAME;
}
QString CurrencyAdapter::getCurrencyTicker() const {
return WALLET_CURRENCY_TICKER;
}
quint64 CurrencyAdapter::getMinimumFee() const {
return m_currency.minimumFee();
}
QString CurrencyAdapter::formatAmount(quint64 _amount) const {
QString result = QString::number(_amount);
if (result.length() < getNumberOfDecimalPlaces() + 1) {
result = result.rightJustified(getNumberOfDecimalPlaces() + 1, '0');
}
quint32 dot_pos = result.length() - getNumberOfDecimalPlaces();
for (quint32 pos = result.length() - 1; pos > dot_pos + 1; --pos) {
if (result[pos] == '0') {
result.remove(pos, 1);
} else {
break;
}
}
result.insert(dot_pos, ".");
for (qint32 pos = dot_pos - 3; pos > 0; pos -= 3) {
if (result[pos - 1].isDigit()) {
result.insert(pos, ',');
}
}
return result;
}
quint64 CurrencyAdapter::parseAmount(const QString& _amountString) const {
QString amountString = _amountString.trimmed();
amountString.remove(',');
int pointIndex = amountString.indexOf('.');
int fractionSize;
if (pointIndex != -1) {
fractionSize = amountString.length() - pointIndex - 1;
while (getNumberOfDecimalPlaces() < fractionSize && amountString.right(1) == "0") {
amountString.remove(amountString.length() - 1, 1);
--fractionSize;
}
if (getNumberOfDecimalPlaces() < fractionSize) {
return 0;
}
amountString.remove(pointIndex, 1);
} else {
fractionSize = 0;
}
if (amountString.isEmpty()) {
return 0;
}
for (qint32 i = 0; i < getNumberOfDecimalPlaces() - fractionSize; ++i) {
amountString.append('0');
}
return amountString.toULongLong();
}
bool CurrencyAdapter::validateAddress(const QString& _address) const {
CryptoNote::AccountPublicAddress internalAddress;
return m_currency.parseAccountAddressString(_address.toStdString(), internalAddress);
}
}
// Copyright (c) 2011-2015 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#pragma once
#include <QString>
#include "CryptoNoteCore/Currency.h"
namespace WalletGui {
class CurrencyAdapter {
public:
static CurrencyAdapter& instance();
const CryptoNote::Currency& getCurrency();
QString getCurrencyDisplayName() const;
QString getCurrencyName() const;
QString getCurrencyTicker() const;
quint64 getMinimumFee() const;
quintptr getNumberOfDecimalPlaces() const;