diff --git a/.svn/pristine/01/016bf7c6d4d408fc5bc88abc77ad31377dcd6242.svn-base b/.svn/pristine/01/016bf7c6d4d408fc5bc88abc77ad31377dcd6242.svn-base new file mode 100644 index 0000000..2726a4a --- /dev/null +++ b/.svn/pristine/01/016bf7c6d4d408fc5bc88abc77ad31377dcd6242.svn-base @@ -0,0 +1,449 @@ + + + RecvHistory + + + + 0 + 0 + 780 + 628 + + + + Form + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + + 0 + 191 + + + + + 16777215 + 191 + + + + border:none + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 30 + + + + + + + 7 + + + + + + 41 + 41 + + + + + 41 + 41 + + + + background-image: url(:/res/png/recvicon.png);border:none + + + + + + + + + + + 0 + 76 + + + + + 16777215 + 76 + + + + + + + + + + IsRecv + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 0 + 82 + + + + + 16777215 + 82 + + + + + + + + 13 + + + + background-color: rgb(242, 241, 240); + + + true + + + + + + + + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 61 + + + + + 16777215 + 61 + + + + + 30 + + + + + + + + + + + + + add + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + TextLabel + + + Qt::TextSelectableByMouse + + + + + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 61 + + + + + 16777215 + 61 + + + + border:none + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 30 + + + + + 0 + + + 0 + + + + + + + + + + + date + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + TextLabel + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 61 + + + + + 16777215 + 61 + + + + border:none + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 30 + + + + + 0 + + + 0 + + + + + + + + info + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + TextLabel + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + Qt::Horizontal + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + diff --git a/.svn/pristine/05/05aa8408d84de79c9d0b0ff613082eff5a8d9951.svn-base b/.svn/pristine/05/05aa8408d84de79c9d0b0ff613082eff5a8d9951.svn-base new file mode 100644 index 0000000..ad33022 --- /dev/null +++ b/.svn/pristine/05/05aa8408d84de79c9d0b0ff613082eff5a8d9951.svn-base @@ -0,0 +1,33 @@ +#ifndef UNIONACCOUNTJOIN_H +#define UNIONACCOUNTJOIN_H + +#include +#include "wallet/wallet.h" +class WalletModel; +namespace Ui { +class unionaccountjoin; +} + +class unionaccountjoin : public QWidget +{ + Q_OBJECT + +public: + explicit unionaccountjoin(QWidget *parent = 0); + ~unionaccountjoin(); + void setModel(WalletModel *_model); + void showEvent(QShowEvent *event); +Q_SIGNALS: + void opensuccessjoinPage(); + void refreshunionaccount(); +private Q_SLOTS: + void on_joinBtn_pressed(); + + void on_btn_import_pressed(); + +private: + Ui::unionaccountjoin *ui; + WalletModel *model; +}; + +#endif // UNIONACCOUNTJOIN_H diff --git a/.svn/pristine/05/05fdd60e66b371ea92a4ad9b39ee4842fa4dcf8c.svn-base b/.svn/pristine/05/05fdd60e66b371ea92a4ad9b39ee4842fa4dcf8c.svn-base new file mode 100644 index 0000000..11f514a Binary files /dev/null and b/.svn/pristine/05/05fdd60e66b371ea92a4ad9b39ee4842fa4dcf8c.svn-base differ diff --git a/.svn/pristine/08/08bb7715e2d9941c74554230bbb79a6326cad2bc.svn-base b/.svn/pristine/08/08bb7715e2d9941c74554230bbb79a6326cad2bc.svn-base new file mode 100644 index 0000000..f4352f1 --- /dev/null +++ b/.svn/pristine/08/08bb7715e2d9941c74554230bbb79a6326cad2bc.svn-base @@ -0,0 +1,54 @@ +#ifndef UNIONACCOUNTHISTORY_H +#define UNIONACCOUNTHISTORY_H +#include +#include +#include "wallet/wallet.h" +class WalletModel; +class CWalletTx; +namespace Ui { +class unionaccounthistory; +} +struct tra_info{ + bool isSend; + std::string add; + CAmount num; + CAmount fee; + QString status; + QString strtime ; + QString txid; +}; +class unionaccounthistory : public QWidget +{ + Q_OBJECT + +public: + unionaccounthistory(QWidget *parent = 0); + ~unionaccounthistory(); + void updateinfo(std::map s); + void setAdd(std::string add); + void setnum(CAmount num); + void addline(); + void setModel(WalletModel *_model); + Q_SIGNALS: + void backtoTraPage(); + void jumptohistorysend(std::string add, CAmount fee,bool isSend,CAmount num,QString status,QString strtime,QString txid); + void jumptohistoryrecv(std::string add, CAmount fee,bool isSend,CAmount num,QString status,QString strtime,QString txid); + +private Q_SLOTS: + void on_btn_back_pressed(); + void lookupinfodetail(std::string add, bool isSend,QString status, + QString strtime,CAmount s,CAmount s1,QString txid); +private: + std::string getAdd(); + void addinfo(std::string add, CAmount fee,bool isSend, + CAmount num,QString status,QString strtime,QString txid); + CAmount getnum(); + Ui::unionaccounthistory *ui; + std::string m_add; + CAmount m_num; + QVBoxLayout * pvboxlayoutall; + WalletModel * m_pwalletmodel; + std::vector m_tra; +}; + +#endif // UNIONACCOUNTHISTORY_H diff --git a/.svn/pristine/0d/0d896f268b09a09b84e8f5b3ced269a8ecdbeb3d.svn-base b/.svn/pristine/0d/0d896f268b09a09b84e8f5b3ced269a8ecdbeb3d.svn-base new file mode 100644 index 0000000..b04b44e --- /dev/null +++ b/.svn/pristine/0d/0d896f268b09a09b84e8f5b3ced269a8ecdbeb3d.svn-base @@ -0,0 +1,57 @@ +#ifndef WALLETPAGEBUTTONS_H +#define WALLETPAGEBUTTONS_H + +#include +#include +class CMessageBox; +namespace Ui { +class walletpagebuttons; +} + +class walletpagebuttons : public QWidget +{ + Q_OBJECT + +public: + explicit walletpagebuttons(QWidget *parent = 0); + ~walletpagebuttons(); + + void fresh(int concount,int count); + +private Q_SLOTS: + void on_pushButton_set_pressed(); + void on_pushButton_setpic_pressed(); + void on_pushButton_ipc_pressed(); + void on_pushButton_ipcpic_pressed(); + void on_pushButton_recive_pressed(); + void on_pushButton_recivepic_pressed(); + void on_pushButton_send_pressed(); + void on_pushButton_sendpic_pressed(); + void on_pushButton_wallet_pressed(); + //void on_pushButton_walletpic_pressed(); + void getWalletPageButtonsStatus(); + void on_pushButton_markbill_pressed(); + + void on_pushButton_eipc_pressed(); + + void on_pushButton_unionaccount_pressed(); + +Q_SIGNALS: + void setpressed(); + void ipcpressed(); + void recivepressed(); + void sendpressed(); + void walletpressed(); + void tallypressed(); + void eipcpressed(); + void unionpressed(); +private: + Ui::walletpagebuttons *ui; + void setpushbuttonchecked(QString name,QPushButton* wallet,\ + QString graypicname,QString greenpicname); + void setMsgDlgPlace(CMessageBox*); + QString formatLang() ; + bool is_uniond; +}; + +#endif // WALLETPAGEBUTTONS_H diff --git a/.svn/pristine/0e/0e736510343e20f8df65d631ae45fe6940eccd73.svn-base b/.svn/pristine/0e/0e736510343e20f8df65d631ae45fe6940eccd73.svn-base new file mode 100644 index 0000000..b8ca763 --- /dev/null +++ b/.svn/pristine/0e/0e736510343e20f8df65d631ae45fe6940eccd73.svn-base @@ -0,0 +1,188 @@ +// Copyright (c) 2011-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "sendcoinsdialog.h" +#include "ui_sendcoinsdialog.h" +#include "addresstablemodel.h" +#include "ipchainunits.h" +#include "clientmodel.h" +#include "guiutil.h" +#include "optionsmodel.h" +#include "platformstyle.h" +#include "walletmodel.h" +#include "base58.h" +#include "chainparams.h" +#include "wallet/coincontrol.h" +#include "validation.h" +#include "ui_interface.h" +#include "txmempool.h" +#include "wallet/wallet.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "config/bitcoin-config.h" /* for USE_QRCODE */ +#include +#include "log/stateinfo.h" + +#define SEND_CONFIRM_DELAY 3 + +SendCoinsDialog::SendCoinsDialog(const PlatformStyle *_platformStyle, QWidget *parent) : + QDialog(parent), + ui(new Ui::SendCoinsDialog), + clientModel(0), + model(0), + fNewRecipientAllowed(true), + fFeeMinimized(true), + platformStyle(_platformStyle) +{ + ui->setupUi(this); + eTag =0; + ui->comboBox->addItem(tr("IPC"), IPC); + ui->comboBox->addItem(tr("mIPC"),mIPC); + ui->ReceiverEdit->setPlaceholderText(tr("input receiver")); + ui->labelEdit->setPlaceholderText(tr("input label")); + ui->CoinEdit->setPlaceholderText(tr("input num")); + QRegExp regx("^\\d+(\\.\\d+)?$"); + QValidator *validator = new QRegExpValidator(regx, ui->CoinEdit ); + ui->CoinEdit->setValidator( validator ); + connect(ui->comboBox, SIGNAL(activated(int)), this, SLOT(coinUpdate(int))); + +} +void SendCoinsDialog::coinUpdate(int idx) +{ + QDate current = QDate::currentDate(); + switch(ui->comboBox->itemData(idx).toInt()) + { + case IPC: + { + eTag = 0; + } + break; + case mIPC: + { + eTag = 1; + } + break; + case uIPC: + { + eTag = 2; + } + break; + case zhi: + { + eTag = 3; + } + break; + default: + { + eTag = 0; + } + } +} +void SendCoinsDialog::setClientModel(ClientModel *_clientModel) +{ + this->clientModel = _clientModel; +} + +void SendCoinsDialog::setModel(WalletModel *_model) +{ + this->model = _model; +} + +SendCoinsDialog::~SendCoinsDialog() +{ + QSettings settings; + delete ui; +} +void SendCoinsDialog::setAddress(const QString &address,const QString &label) +{ + ui->ReceiverEdit->setText(address); + ui->labelEdit->setText(label); +} +/* +void SendCoinsDialog::on_scanBtn_pressed() +{ + QString filename = GUIUtil::getOpenFileName(this, tr("Select payment request file to open"), "", "", NULL); + if(filename.isEmpty()) + return; + QRcode_encodeString("http://www.ipcchain.com/", 2, QR_ECLEVEL_Q, QR_MODE_8, 0); + QRcode *code = QRcode_encodeString("uri.toUtf8().constData()", 0, QR_ECLEVEL_L, QR_MODE_8, 1); + if (!code) + { + return; + } + QImage qrImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32); + qrImage.fill(0xffffff); + unsigned char *p = code->data; + for (int y = 0; y < code->width; y++) + { + for (int x = 0; x < code->width; x++) + { + qrImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff)); + p++; + } + } + QRcode_free(code); + + QImage qrAddrImage = QImage(300, 300+20, QImage::Format_RGB32); + qrAddrImage.fill(0xffffff); + + QPainter painter(&qrAddrImage); + painter.drawImage(0, 0, qrImage.scaled(300, 300)); + QFont font = GUIUtil::fixedPitchFont(); + font.setPixelSize(12); + painter.setFont(font); + QRect paddedRect = qrAddrImage.rect(); + paddedRect.setHeight(300+12); + painter.end(); + +} +*/ +void SendCoinsDialog::on_AddAdsButton_pressed() +{ + Q_EMIT openAddBookPagewidget(2); +} +void SendCoinsDialog::on_GoSettingBtn_pressed() +{ + + QString a = ui->ReceiverEdit->text(); + QString label = ui->labelEdit->text(); + QString b = ui->CoinEdit->text(); + if(a != NULL && b != NULL) + { + if(!model->validateAddress(a)) + { + ui->tiplabel->setText(tr("The recipient address is not valid. Please recheck.")); + return; + }else{ + ui->tiplabel->setText(tr("")); + } + } + else + { + ui->tiplabel->setText(tr("input info")); + return; + } + bool isCrypted = this->model->CheckIsCrypted(); + if(isCrypted) + { + + Q_EMIT openSendAffrimwidget(a,b,label,eTag); + } + else + { + Q_EMIT openSettingwidget(a,b,label,eTag); + } +} +void SendCoinsDialog::clearInfo() +{ + ui->ReceiverEdit->setText(""); + ui->labelEdit->setText(""); + ui->CoinEdit->setText(""); +} diff --git a/.svn/pristine/10/10fb07ee8d1da5d6628aaa3775bf4adf1f886078.svn-base b/.svn/pristine/10/10fb07ee8d1da5d6628aaa3775bf4adf1f886078.svn-base new file mode 100644 index 0000000..96e0f85 --- /dev/null +++ b/.svn/pristine/10/10fb07ee8d1da5d6628aaa3775bf4adf1f886078.svn-base @@ -0,0 +1,292 @@ +#include "unionaccounttrasend.h" +#include "ui_unionaccounttrasend.h" +#include "log/log.h" +#include +#include +#include +#include "intro.h" +#ifdef WIN32 +#include +const std::string DIRECTORY_SEPARATOR = "\\"; +#else +const std::string DIRECTORY_SEPARATOR = "/"; +#endif + +#ifdef WIN32 +static void CreateDir(const std::string& path) +{ + CreateDirectoryA(path.c_str(), NULL); +} +#else +#include +#include +#include + +#define MAX_PATH 512 + + +static void CreateDir(const std::string& path) +{ + mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); +} + +#endif +unionaccounttrasend::unionaccounttrasend(QWidget *parent) : + QWidget(parent), + ui(new Ui::unionaccounttrasend) +{ + ui->setupUi(this); + + QRegExp regx("^\\d+(\\.\\d+)?$"); + QValidator *validator = new QRegExpValidator(regx, ui->lineEdit_num ); + ui->lineEdit_num->setValidator( validator ); +} + +unionaccounttrasend::~unionaccounttrasend() +{ + delete ui; +} +void unionaccounttrasend::setModel(WalletModel *_model) +{ + this->model = _model; +} +void unionaccounttrasend::setaddress(QString add) +{ + ui->lineEdit_add->setText(""); + ui->lineEdit_num->setText(""); + ui->textEdit->setText(""); + ui->label_tip->setText(""); + m_add =add; +} +QString unionaccounttrasend::getaddress() +{ + return m_add; +} +void unionaccounttrasend::on_sendbtn_pressed() +{ + + + ui->label_tip->setText(""); + m_sendcoinerror = ""; + if(!model || !model->getOptionsModel()) + return; + if("" == ui->lineEdit_num->text() || + "" == ui->lineEdit_add->text()) + { + ui->label_tip->setText(tr("input info")); + return; + } + + if(!model->CheckPassword()) + { + ui->label_tip->setText(tr("Password error.")); + LOG_WRITE(LOG_INFO,"on_sendbtn_pressed Password error."); + return; + } + WalletModel::UnlockContext ctx(model, true, true); + + // CAmount t = (ui->lineEdit_num->text()).toDouble();//num + QString t = ui->lineEdit_num->text(); + int h= t.indexOf(" "); + QString s = t.mid(0,h); + double num = s.toDouble(); + num=num*100000000; + QString add = ui->lineEdit_add->text(); + ScriptError serror; + std::string strtx = ""; + QString add_from = getaddress(); + // LOG_WRITE(LOG_INFO,"SendMul num*00000",QString::number(num).toStdString().c_str()); + + WalletModel::SendCoinsReturn sendStatus =model->repreparUnionaccountCreate(add_from,add,num,serror,strtx); + + LOG_WRITE(LOG_INFO,"sendStatus",QString::number(sendStatus.status).toStdString().c_str()); + if( WalletModel::OK == sendStatus.status ) + { + if(ScriptError::SCRIPT_ERR_OK == serror) + { + std::string strFailReason; + ScriptError serror; + std::string strFailReason_plus; + std::string strtxout; + CMutableTransaction mergedTx; + if(model->commitUnionaccounttra( strtx, strFailReason,serror,strtxout,mergedTx)) + { + if(ScriptError::SCRIPT_ERR_OK == serror) + { + if(model->commitUnionaccounttra_plus(mergedTx,strFailReason_plus)) + { + Q_EMIT opensendsuccessPage(tr("sign successed"),""); + } + } + else + { + std::string path = Intro::m_datapath; + if(path == "")return; + CreateDir(path); + + std::string logFile = path +DIRECTORY_SEPARATOR+ "address.txt"; + + FILE* m_file = fopen(logFile.c_str(), "a+"); + + + fprintf(m_file, "address: %s\n", add_from.toStdString().c_str()); + fprintf(m_file, "script: %s\n",QString::fromStdString(strtx).toStdString().c_str() ); + + fclose(m_file); + + + Q_EMIT opensendsuccessPage(tr("create successed"), QString::fromStdString(strtxout)); + } + } + else + { + LOG_WRITE(LOG_INFO,"SEND sign error"); + ui->label_tip->setText(tr("sign error")); + } + } + else + { + + std::string path = Intro::m_datapath; + if(path == "")return; + CreateDir(path); + + std::string logFile = path +DIRECTORY_SEPARATOR+ "address.txt"; +/* + QFile file(logFile.c_str()); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + LOG_WRITE(LOG_INFO,"open fail"); + return; + } + else + { + QString str1, str2, qstr_similarity, sumqstr; + for(int i = 0; i < 1; ++i) + { + str1 = QString::fromStdString(ui->textEdit->document()->toPlainText().toStdString()); + + sumqstr = "address:"+add_from+"\n"+"script:" + QString::fromStdString(strtx) + "\n" ; + } + QTextStream in(&file); + in << sumqstr; + file.close(); + + } + */ + FILE* m_file = fopen(logFile.c_str(), "a+"); + + + fprintf(m_file, "address: %s\n", add_from.toStdString().c_str()); + fprintf(m_file, "script: %s\n",QString::fromStdString(strtx).toStdString().c_str() ); + fclose(m_file); + + + Q_EMIT opensendsuccessPage(tr("create successed"), QString::fromStdString(strtx)); + + } + + } + else + { + + m_sendcoinerror = model->m_sendcoinerror; + LOG_WRITE(LOG_INFO,"error",m_sendcoinerror.c_str()); + processSendCoinsReturn(sendStatus); + } + +} +void unionaccounttrasend::processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn) +{ + QPalette pa; + pa.setColor(QPalette::WindowText,Qt::black); + + switch(sendCoinsReturn.status) + { + case WalletModel::PsdErr: + ui->label_tip->setText(tr("password error")); + break; + case WalletModel::InvalidAddress: + ui->label_tip->setText(tr("The recipient address is not valid. Please recheck.")); + break; + case WalletModel::InvalidAmount: + ui->label_tip->setText(tr("Invalid Amount!")); + break; + case WalletModel::AmountExceedsBalance: + ui->label_tip->setText(tr("The amount exceeds your balance.")); + break; + case WalletModel::AmountWithFeeExceedsBalance: + // ui->label_tip->setText(tr("The total exceeds your balance when the 0.001IPC/KB transaction fee is included.").arg(msgArg)); + break; + case WalletModel::DuplicateAddress: + ui->label_tip->setText(tr("Duplicate address found: addresses should only be used once each.")); + break; + case WalletModel::TransactionCreationFailed: + if(m_sendcoinerror!="") + ui->label_tip->setText(m_sendcoinerror.c_str()); + else + ui->label_tip->setText(tr("Transaction creation failed!")); + break; + case WalletModel::TransactionCommitFailed: + { + if("bad-Token-tokensymbol-repeat" == sendCoinsReturn.reasonCommitFailed ) + { + ui->label_tip->setText(tr("The transaction was rejected with the following reason: bad-Token-tokensymbol-repeat")); + + } + else if("bad-Token-tokenhash-repeat" == sendCoinsReturn.reasonCommitFailed ) + { + ui->label_tip->setText(tr("The transaction was rejected with the following reason: bad-Token-tokenhash-repeat")); + + } + else if("bad-Token-Multi-inType" == sendCoinsReturn.reasonCommitFailed ) + { + ui->label_tip->setText(tr("The transaction was rejected with the following reason: bad-Token-Multi-inType")); + + } + else if("bad-Token-Reg-issueDate(Regtime)" == sendCoinsReturn.reasonCommitFailed) + { + ui->label_tip->setText(tr("The transaction was rejected with the following reason: bad-Token-Reg-issueDate(Regtime)")); + + } + else if("bad-Token-regtotoken-value-unequal" == sendCoinsReturn.reasonCommitFailed ) + { + ui->label_tip->setText(tr("The transaction was rejected with the following reason: bad-Token-regtotoken-value-unequal")); + } + else if("bad-Token-Label-contain-errvalue"== sendCoinsReturn.reasonCommitFailed) + { + ui->label_tip->setText(tr("The transaction was rejected with the following reason: bad-Token-Label-contain-errvalue")); + } + else if("bad-Token-Symbol-contain-errvalue"== sendCoinsReturn.reasonCommitFailed) + { + ui->label_tip->setText(tr("The transaction was rejected with the following reason: bad-Token-Symbol-contain-errvalue")); + } + else if("bad-Token-value-unequal" == sendCoinsReturn.reasonCommitFailed ) + { + ui->label_tip->setText(tr("The transaction was rejected with the following reason: bad-Token-value-unequal")); + } + else if("bad-Token-Multi-outType" == sendCoinsReturn.reasonCommitFailed ) + { + ui->label_tip->setText(tr("The transaction was rejected with the following reason: bad-Token-Multi-outType")); + } + else + { + ui->label_tip->setText(tr("The transaction was rejected with the following reason: %1").arg(sendCoinsReturn.reasonCommitFailed)); + } + } + break; + case WalletModel::AbsurdFee: + ui->label_tip->setText(tr("A fee higher is considered an absurdly high fee.")); + break; + case WalletModel::PaymentRequestExpired: + ui->label_tip->setText(tr("Payment request expired.")); + break; + case WalletModel::OK: + default: + return; + } +} + +void unionaccounttrasend::on_pushButton_back_pressed() +{ + Q_EMIT backtotraPage(); +} diff --git a/.svn/pristine/11/11023b6c4929327c658c99158dbf98c0f62ad26c.svn-base b/.svn/pristine/11/11023b6c4929327c658c99158dbf98c0f62ad26c.svn-base new file mode 100644 index 0000000..a414e04 --- /dev/null +++ b/.svn/pristine/11/11023b6c4929327c658c99158dbf98c0f62ad26c.svn-base @@ -0,0 +1,154 @@ +#include "ecoinsendaffrimdialog.h" +#include "forms/ui_ecoinsendaffrimdialog.h" +#include "addresstablemodel.h" +#include "optionsmodel.h" +#include "ipchainunits.h" +#include "wallet/coincontrol.h" +#include "guiutil.h" +#include +#include "wallet/wallet.h" +#include +#include "log/log.h" +#include +#include +#include + +ecoinsendaffrimdialog::ecoinsendaffrimdialog(QWidget *parent) : + QWidget(parent), + ui(new Ui::ecoinsendaffrimdialog) +{ + ui->setupUi(this); +} +void ecoinsendaffrimdialog::showEvent(QShowEvent * p) +{ + ui->addEdit->setText(""); + ui->numEdit->setText(""); + ui->tiplabel->setText(""); + ui->addEdit->setFocusPolicy(Qt::StrongFocus); + ui->addEdit->setFocus(Qt::OtherFocusReason); + ui->numEdit->clearFocus(); +} +ecoinsendaffrimdialog::~ecoinsendaffrimdialog() +{ + delete ui; +} +void ecoinsendaffrimdialog::setModel(WalletModel *_model) +{ + this->model = _model; +} +void ecoinsendaffrimdialog::setMsg(QString name,QString num) +{ + + m_name = name; + m_num = num; + std::string strname = name.toStdString(); + int acc = model->GetAccuracyBySymbol(strname); + QString exp("1000000000000000000|([0-9]{0,19}[\.][0-9]{0,"); + exp+=(QString::number(acc)); + exp = exp + ("})"); + QRegExp double_rx10000(exp); + QValidator *validator = new QRegExpValidator(double_rx10000, ui->numEdit ); + ui->numEdit->setValidator( validator ); + ui->tokenlabel->setText(name); + ui->addEdit->setText(""); + ui->numEdit->setText(""); + ui->tiplabel->setText(""); + ui->numEdit->clearFocus(); + +} + +void ecoinsendaffrimdialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, const QString &msgArg) +{ + QPalette pa; + pa.setColor(QPalette::WindowText,Qt::black); + + LOG_WRITE(LOG_INFO,"processSendCoinsReturn","sendCoinsReturn.status",\ + QString::number(sendCoinsReturn.status).toStdString().c_str(),\ + "m_error",m_error.c_str()); + + switch(sendCoinsReturn.status) + { + case WalletModel::PsdErr: + ui->tiplabel->setText(tr("password error")); + break; + case WalletModel::NumErr: + ui->tiplabel->setText(tr("Please enter the correct amount")); + break; + case WalletModel::InvalidAddress: + ui->tiplabel->setText(tr("The recipient address is not valid. Please recheck.")); + break; + case WalletModel::InvalidAmount: + ui->tiplabel->setText(tr("The amount to pay must be larger than 0.")); + break; + case WalletModel::AmountExceedsBalance: + ui->tiplabel->setText(tr("The amount exceeds your balance.")); + break; + case WalletModel::AmountWithFeeExceedsBalance: + ui->tiplabel->setText(tr("The total exceeds your balance.")); + break; + case WalletModel::DuplicateAddress: + ui->tiplabel->setText(tr("Duplicate address found: addresses should only be used once each.")); + break; + case WalletModel::TransactionCreationFailed: + if(m_error == "The tokenvalue is too big,you have not enough tokencoins.") + ui->tiplabel->setText(tr("The tokenvalue is too big,you have not enough tokencoins.")); + else if(m_error == "The Tokenvalue is too big,you have not enough Tokencoins.") + ui->tiplabel->setText(tr("The Tokenvalue is too big,you have not enough Tokencoins.")); + else + ui->tiplabel->setText(tr("Transaction creation failed!") + " " + m_error.c_str()); + break; + case WalletModel::TransactionCommitFailed: + if(m_error == "Token-reg-starttime-is-up-yet") + ui->tiplabel->setText(tr("Token-reg-starttime-is-up-yet")); + else + ui->tiplabel->setText(tr("The transaction was rejected with the following reason: %1").arg(sendCoinsReturn.reasonCommitFailed)); + break; + case WalletModel::AbsurdFee: + ui->tiplabel->setText(tr("A fee higher")); + break; + case WalletModel::PaymentRequestExpired: + ui->tiplabel->setText(tr("Payment request expired.")); + break; + case WalletModel::OK: + default: + return; + } +} + + +void ecoinsendaffrimdialog::on_sendecoinButton_pressed() +{ + m_error = ""; + if(!model || !model->getOptionsModel()) + return; + if("" == ui->addEdit->text() || + "" == ui->numEdit->text()) + { + ui->tiplabel->setText(tr("input info")); + return; + } + QString num = ui->numEdit->text(); + QString pointword = "."; + if(num.indexOf(pointword) == num.size()-1){ + ui->tiplabel->setText(tr("Please enter the correct amount")); + return; + } + + QString add = ui->addEdit->text(); + + WalletModel::SendCoinsReturn sendStatus =model->prepareecoinaffrim(num,add,m_name); + + if(sendStatus.status == WalletModel::OK) + { + Q_EMIT gotoecoinconfrimsendaffrim(num,add); + } + else + { + m_error = model->m_sendcoinerror;//20180201 + processSendCoinsReturn(sendStatus); + } + + + + +} diff --git a/.svn/pristine/11/114676a07f49c1d5eb002660aba392147bc7a2b5.svn-base b/.svn/pristine/11/114676a07f49c1d5eb002660aba392147bc7a2b5.svn-base new file mode 100644 index 0000000..0115dd8 --- /dev/null +++ b/.svn/pristine/11/114676a07f49c1d5eb002660aba392147bc7a2b5.svn-base @@ -0,0 +1,637 @@ + + + eCoinSenddialog + + + + 0 + 0 + 1065 + 819 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + 0 + + + + + + 0 + 67 + + + + + 16777215 + 67 + + + + border:none + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 31 + 31 + 111 + 16 + + + + font-size : 14px; +color: rgb(51, 51, 51); + + + name + + + + + + 150 + 30 + 721 + 20 + + + + TextLabel + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 67 + + + + + 16777215 + 67 + + + + border:none + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 31 + 21 + 111 + 16 + + + + font-size : 14px; +color: rgb(51, 51, 51); + + + num + + + + + + 150 + 20 + 741 + 20 + + + + TextLabel + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 67 + + + + QFrame::NoFrame + + + QFrame::Raised + + + + + 30 + 30 + 67 + 17 + + + + font-size : 14px; +color: rgb(51, 51, 51); + + + available + + + + + + 150 + 30 + 671 + 17 + + + + TextLabel + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 67 + + + + + 16777215 + 67 + + + + QFrame::NoFrame + + + QFrame::Raised + + + + + 30 + 30 + 67 + 17 + + + + font-size : 14px; +color: rgb(51, 51, 51); + + + time + + + + + + 150 + 30 + 541 + 17 + + + + TextLabel + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 67 + + + + QFrame::NoFrame + + + QFrame::Raised + + + + + 30 + 30 + 61 + 16 + + + + font-size : 14px; +color: rgb(51, 51, 51); + + + accuracy + + + + + + 150 + 30 + 67 + 17 + + + + TextLabel + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 67 + + + + QFrame::NoFrame + + + QFrame::Raised + + + + + 30 + 30 + 67 + 17 + + + + font-size : 14px; +color: rgb(51, 51, 51); + + + hash + + + + + + 150 + 30 + 821 + 17 + + + + TextLabel + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 16777215 + 320 + + + + border:none + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 30 + 10 + 80 + 20 + + + + font-size : 14px; +color: rgb(51, 51, 51); + + + Address + + + + + + 100 + 30 + 457 + 291 + + + + + + + + 0 + 222 + + + + + 16777215 + 222 + + + + + + + Qt::Horizontal + + + + 110 + 20 + + + + + + + + + 200 + 200 + + + + + 200 + 200 + + + + + + + + + + + Qt::Horizontal + + + + 109 + 20 + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + TextLabel + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 235 + 50 + + + + + 235 + 50 + + + + background-image: url(:/res/png/buttons/235_50.png);border:none;font-size : 16px; +color: rgb(255, 255, 255); + + + Send + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + diff --git a/.svn/pristine/13/13690f5310717013bf741fd02b1bff842145afa1.svn-base b/.svn/pristine/13/13690f5310717013bf741fd02b1bff842145afa1.svn-base new file mode 100644 index 0000000..2ae8a4e --- /dev/null +++ b/.svn/pristine/13/13690f5310717013bf741fd02b1bff842145afa1.svn-base @@ -0,0 +1,1579 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "interpreter.h" + +#include "primitives/transaction.h" +#include "crypto/ripemd160.h" +#include "crypto/sha1.h" +#include "crypto/sha256.h" +#include "pubkey.h" +#include "script/script.h" +#include "uint256.h" + +using namespace std; + +typedef vector valtype; + +namespace { + +inline bool set_success(ScriptError* ret) +{ + if (ret) + *ret = SCRIPT_ERR_OK; + return true; +} + +inline bool set_error(ScriptError* ret, const ScriptError serror) +{ + if (ret) + *ret = serror; + return false; +} + +} // anon namespace + +bool CastToBool(const valtype& vch) +{ + for (unsigned int i = 0; i < vch.size(); i++) + { + if (vch[i] != 0) + { + // Can be negative zero + if (i == vch.size()-1 && vch[i] == 0x80) + return false; + return true; + } + } + return false; +} + +/** + * Script is a stack machine (like Forth) that evaluates a predicate + * returning a bool indicating valid or not. There are no loops. + */ +#define stacktop(i) (stack.at(stack.size()+(i))) +#define altstacktop(i) (altstack.at(altstack.size()+(i))) +static inline void popstack(vector& stack) +{ + if (stack.empty()) + throw runtime_error("popstack(): stack empty"); + stack.pop_back(); +} + +bool static IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) { + if (vchPubKey.size() < 33) { + // Non-canonical public key: too short + return false; + } + if (vchPubKey[0] == 0x04) { + if (vchPubKey.size() != 65) { + // Non-canonical public key: invalid length for uncompressed key + return false; + } + } else if (vchPubKey[0] == 0x02 || vchPubKey[0] == 0x03) { + if (vchPubKey.size() != 33) { + // Non-canonical public key: invalid length for compressed key + return false; + } + } else { + // Non-canonical public key: neither compressed nor uncompressed + return false; + } + return true; +} + +bool static IsCompressedPubKey(const valtype &vchPubKey) { + if (vchPubKey.size() != 33) { + // Non-canonical public key: invalid length for compressed key + return false; + } + if (vchPubKey[0] != 0x02 && vchPubKey[0] != 0x03) { + // Non-canonical public key: invalid prefix for compressed key + return false; + } + return true; +} + +/** + * A canonical signature exists of: <30> <02> <02> + * Where R and S are not negative (their first byte has its highest bit not set), and not + * excessively padded (do not start with a 0 byte, unless an otherwise negative number follows, + * in which case a single 0 byte is necessary and even required). + * + * See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623 + * + * This function is consensus-critical since BIP66. + */ +bool static IsValidSignatureEncoding(const std::vector &sig) { + // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] [sighash] + // * total-length: 1-byte length descriptor of everything that follows, + // excluding the sighash byte. + // * R-length: 1-byte length descriptor of the R value that follows. + // * R: arbitrary-length big-endian encoded R value. It must use the shortest + // possible encoding for a positive integers (which means no null bytes at + // the start, except a single one when the next byte has its highest bit set). + // * S-length: 1-byte length descriptor of the S value that follows. + // * S: arbitrary-length big-endian encoded S value. The same rules apply. + // * sighash: 1-byte value indicating what data is hashed (not part of the DER + // signature) + + // Minimum and maximum size constraints. + if (sig.size() < 9) return false; + if (sig.size() > 73) return false; + + // A signature is of type 0x30 (compound). + if (sig[0] != 0x30) return false; + + // Make sure the length covers the entire signature. + if (sig[1] != sig.size() - 3) return false; + + // Extract the length of the R element. + unsigned int lenR = sig[3]; + + // Make sure the length of the S element is still inside the signature. + if (5 + lenR >= sig.size()) return false; + + // Extract the length of the S element. + unsigned int lenS = sig[5 + lenR]; + + // Verify that the length of the signature matches the sum of the length + // of the elements. + if ((size_t)(lenR + lenS + 7) != sig.size()) return false; + + // Check whether the R element is an integer. + if (sig[2] != 0x02) return false; + + // Zero-length integers are not allowed for R. + if (lenR == 0) return false; + + // Negative numbers are not allowed for R. + if (sig[4] & 0x80) return false; + + // Null bytes at the start of R are not allowed, unless R would + // otherwise be interpreted as a negative number. + if (lenR > 1 && (sig[4] == 0x00) && !(sig[5] & 0x80)) return false; + + // Check whether the S element is an integer. + if (sig[lenR + 4] != 0x02) return false; + + // Zero-length integers are not allowed for S. + if (lenS == 0) return false; + + // Negative numbers are not allowed for S. + if (sig[lenR + 6] & 0x80) return false; + + // Null bytes at the start of S are not allowed, unless S would otherwise be + // interpreted as a negative number. + if (lenS > 1 && (sig[lenR + 6] == 0x00) && !(sig[lenR + 7] & 0x80)) return false; + + return true; +} + +bool static IsLowDERSignature(const valtype &vchSig, ScriptError* serror) { + if (!IsValidSignatureEncoding(vchSig)) { + return set_error(serror, SCRIPT_ERR_SIG_DER); + } + std::vector vchSigCopy(vchSig.begin(), vchSig.begin() + vchSig.size() - 1); + if (!CPubKey::CheckLowS(vchSigCopy)) { + return set_error(serror, SCRIPT_ERR_SIG_HIGH_S); + } + return true; +} + +bool static IsDefinedHashtypeSignature(const valtype &vchSig) { + if (vchSig.size() == 0) { + return false; + } + unsigned char nHashType = vchSig[vchSig.size() - 1] & (~(SIGHASH_ANYONECANPAY)); + if (nHashType < SIGHASH_ALL || nHashType > SIGHASH_SINGLE) + return false; + + return true; +} + +bool CheckSignatureEncoding(const vector &vchSig, unsigned int flags, ScriptError* serror) { + // Empty signature. Not strictly DER encoded, but allowed to provide a + // compact way to provide an invalid signature for use with CHECK(MULTI)SIG + if (vchSig.size() == 0) { + return true; + } + if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) != 0 && !IsValidSignatureEncoding(vchSig)) { + return set_error(serror, SCRIPT_ERR_SIG_DER); + } else if ((flags & SCRIPT_VERIFY_LOW_S) != 0 && !IsLowDERSignature(vchSig, serror)) { + // serror is set + return false; + } else if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsDefinedHashtypeSignature(vchSig)) { + return set_error(serror, SCRIPT_ERR_SIG_HASHTYPE); + } + return true; +} + +bool static CheckPubKeyEncoding(const valtype &vchPubKey, unsigned int flags, const SigVersion &sigversion, ScriptError* serror) { + if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsCompressedOrUncompressedPubKey(vchPubKey)) { + return set_error(serror, SCRIPT_ERR_PUBKEYTYPE); + } + // Only compressed keys are accepted in segwit + if ((flags & SCRIPT_VERIFY_WITNESS_PUBKEYTYPE) != 0 && sigversion == SIGVERSION_WITNESS_V0 && !IsCompressedPubKey(vchPubKey)) { + return set_error(serror, SCRIPT_ERR_WITNESS_PUBKEYTYPE); + } + return true; +} + +bool static CheckMinimalPush(const valtype& data, opcodetype opcode) { + if (data.size() == 0) { + // Could have used OP_0. + return opcode == OP_0; + } else if (data.size() == 1 && data[0] >= 1 && data[0] <= 16) { + // Could have used OP_1 .. OP_16. + return opcode == OP_1 + (data[0] - 1); + } else if (data.size() == 1 && data[0] == 0x81) { + // Could have used OP_1NEGATE. + return opcode == OP_1NEGATE; + } else if (data.size() <= 75) { + // Could have used a direct push (opcode indicating number of bytes pushed + those bytes). + return opcode == data.size(); + } else if (data.size() <= 255) { + // Could have used OP_PUSHDATA. + return opcode == OP_PUSHDATA1; + } else if (data.size() <= 65535) { + // Could have used OP_PUSHDATA2. + return opcode == OP_PUSHDATA2; + } + return true; +} + +bool EvalScript(vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* serror) +{ + static const CScriptNum bnZero(0); + static const CScriptNum bnOne(1); + static const CScriptNum bnFalse(0); + static const CScriptNum bnTrue(1); + static const valtype vchFalse(0); + static const valtype vchZero(0); + static const valtype vchTrue(1, 1); + + CScript::const_iterator pc = script.begin(); + CScript::const_iterator pend = script.end(); + CScript::const_iterator pbegincodehash = script.begin(); + opcodetype opcode; + valtype vchPushValue; + vector vfExec; + vector altstack; + set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); + if (script.size() > MAX_SCRIPT_SIZE) + return set_error(serror, SCRIPT_ERR_SCRIPT_SIZE); + int nOpCount = 0; + bool fRequireMinimal = (flags & SCRIPT_VERIFY_MINIMALDATA) != 0; + + try + { + while (pc < pend) + { + bool fExec = !count(vfExec.begin(), vfExec.end(), false); + + // + // Read instruction + // + if (!script.GetOp(pc, opcode, vchPushValue)) + return set_error(serror, SCRIPT_ERR_BAD_OPCODE); + if (vchPushValue.size() > MAX_SCRIPT_ELEMENT_SIZE) + return set_error(serror, SCRIPT_ERR_PUSH_SIZE); + + // Note how OP_RESERVED does not count towards the opcode limit. + if (opcode > OP_16 && ++nOpCount > MAX_OPS_PER_SCRIPT) + return set_error(serror, SCRIPT_ERR_OP_COUNT); + + if (opcode == OP_CAT || + opcode == OP_SUBSTR || + opcode == OP_LEFT || + opcode == OP_RIGHT || + opcode == OP_INVERT || + opcode == OP_AND || + opcode == OP_OR || + opcode == OP_XOR || + opcode == OP_2MUL || + opcode == OP_2DIV || + opcode == OP_MUL || + opcode == OP_DIV || + opcode == OP_MOD || + opcode == OP_LSHIFT || + opcode == OP_RSHIFT) + return set_error(serror, SCRIPT_ERR_DISABLED_OPCODE); // Disabled opcodes. + + if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4) { + if (fRequireMinimal && !CheckMinimalPush(vchPushValue, opcode)) { + return set_error(serror, SCRIPT_ERR_MINIMALDATA); + } + stack.push_back(vchPushValue); + } else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF)) + switch (opcode) + { + // + // Push value + // + case OP_1NEGATE: + case OP_1: + case OP_2: + case OP_3: + case OP_4: + case OP_5: + case OP_6: + case OP_7: + case OP_8: + case OP_9: + case OP_10: + case OP_11: + case OP_12: + case OP_13: + case OP_14: + case OP_15: + case OP_16: + { + // ( -- value) + CScriptNum bn((int)opcode - (int)(OP_1 - 1)); + stack.push_back(bn.getvch()); + // The result of these opcodes should always be the minimal way to push the data + // they push, so no need for a CheckMinimalPush here. + } + break; + + + // + // Control + // + case OP_NOP: + break; + + case OP_CHECKLOCKTIMEVERIFY: + { + if (!(flags & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)) { + // not enabled; treat as a NOP2 + if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) { + return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS); + } + break; + } + + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + + // Note that elsewhere numeric opcodes are limited to + // operands in the range -2**31+1 to 2**31-1, however it is + // legal for opcodes to produce results exceeding that + // range. This limitation is implemented by CScriptNum's + // default 4-byte limit. + // + // If we kept to that limit we'd have a year 2038 problem, + // even though the nLockTime field in transactions + // themselves is uint32 which only becomes meaningless + // after the year 2106. + // + // Thus as a special case we tell CScriptNum to accept up + // to 5-byte bignums, which are good until 2**39-1, well + // beyond the 2**32-1 limit of the nLockTime field itself. + const CScriptNum nLockTime(stacktop(-1), fRequireMinimal, 5); + + // In the rare event that the argument may be < 0 due to + // some arithmetic being done first, you can always use + // 0 MAX CHECKLOCKTIMEVERIFY. + if (nLockTime < 0) + return set_error(serror, SCRIPT_ERR_NEGATIVE_LOCKTIME); + + // Actually compare the specified lock time with the transaction. + if (!checker.CheckLockTime(nLockTime)) + return set_error(serror, SCRIPT_ERR_UNSATISFIED_LOCKTIME); + + break; + } + + case OP_CHECKSEQUENCEVERIFY: + { + if (!(flags & SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)) { + // not enabled; treat as a NOP3 + if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) { + return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS); + } + break; + } + + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + + // nSequence, like nLockTime, is a 32-bit unsigned integer + // field. See the comment in CHECKLOCKTIMEVERIFY regarding + // 5-byte numeric operands. + const CScriptNum nSequence(stacktop(-1), fRequireMinimal, 5); + + // In the rare event that the argument may be < 0 due to + // some arithmetic being done first, you can always use + // 0 MAX CHECKSEQUENCEVERIFY. + if (nSequence < 0) + return set_error(serror, SCRIPT_ERR_NEGATIVE_LOCKTIME); + + // To provide for future soft-fork extensibility, if the + // operand has the disabled lock-time flag set, + // CHECKSEQUENCEVERIFY behaves as a NOP. + if ((nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) != 0) + break; + + // Compare the specified sequence number with the input. + if (!checker.CheckSequence(nSequence)) + return set_error(serror, SCRIPT_ERR_UNSATISFIED_LOCKTIME); + + break; + } + + case OP_NOP1: case OP_NOP4: case OP_NOP5: + case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10: + { + if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) + return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS); + } + break; + + case OP_IF: + case OP_NOTIF: + { + // if [statements] [else [statements]] endif + bool fValue = false; + if (fExec) + { + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); + valtype& vch = stacktop(-1); + if (sigversion == SIGVERSION_WITNESS_V0 && (flags & SCRIPT_VERIFY_MINIMALIF)) { + if (vch.size() > 1) + return set_error(serror, SCRIPT_ERR_MINIMALIF); + if (vch.size() == 1 && vch[0] != 1) + return set_error(serror, SCRIPT_ERR_MINIMALIF); + } + fValue = CastToBool(vch); + if (opcode == OP_NOTIF) + fValue = !fValue; + popstack(stack); + } + vfExec.push_back(fValue); + } + break; + + case OP_ELSE: + { + if (vfExec.empty()) + return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); + vfExec.back() = !vfExec.back(); + } + break; + + case OP_ENDIF: + { + if (vfExec.empty()) + return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); + vfExec.pop_back(); + } + break; + + case OP_VERIFY: + { + // (true -- ) or + // (false -- false) and return + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + bool fValue = CastToBool(stacktop(-1)); + if (fValue) + popstack(stack); + else + return set_error(serror, SCRIPT_ERR_VERIFY); + } + break; + + case OP_RETURN: + { + return set_error(serror, SCRIPT_ERR_OP_RETURN); + } + break; + + + // + // Stack ops + // + case OP_TOALTSTACK: + { + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + altstack.push_back(stacktop(-1)); + popstack(stack); + } + break; + + case OP_FROMALTSTACK: + { + if (altstack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_ALTSTACK_OPERATION); + stack.push_back(altstacktop(-1)); + popstack(altstack); + } + break; + + case OP_2DROP: + { + // (x1 x2 -- ) + if (stack.size() < 2) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + popstack(stack); + popstack(stack); + } + break; + + case OP_2DUP: + { + // (x1 x2 -- x1 x2 x1 x2) + if (stack.size() < 2) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype vch1 = stacktop(-2); + valtype vch2 = stacktop(-1); + stack.push_back(vch1); + stack.push_back(vch2); + } + break; + + case OP_3DUP: + { + // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3) + if (stack.size() < 3) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype vch1 = stacktop(-3); + valtype vch2 = stacktop(-2); + valtype vch3 = stacktop(-1); + stack.push_back(vch1); + stack.push_back(vch2); + stack.push_back(vch3); + } + break; + + case OP_2OVER: + { + // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2) + if (stack.size() < 4) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype vch1 = stacktop(-4); + valtype vch2 = stacktop(-3); + stack.push_back(vch1); + stack.push_back(vch2); + } + break; + + case OP_2ROT: + { + // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2) + if (stack.size() < 6) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype vch1 = stacktop(-6); + valtype vch2 = stacktop(-5); + stack.erase(stack.end()-6, stack.end()-4); + stack.push_back(vch1); + stack.push_back(vch2); + } + break; + + case OP_2SWAP: + { + // (x1 x2 x3 x4 -- x3 x4 x1 x2) + if (stack.size() < 4) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + swap(stacktop(-4), stacktop(-2)); + swap(stacktop(-3), stacktop(-1)); + } + break; + + case OP_IFDUP: + { + // (x - 0 | x x) + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype vch = stacktop(-1); + if (CastToBool(vch)) + stack.push_back(vch); + } + break; + + case OP_DEPTH: + { + // -- stacksize + CScriptNum bn(stack.size()); + stack.push_back(bn.getvch()); + } + break; + + case OP_DROP: + { + // (x -- ) + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + popstack(stack); + } + break; + + case OP_DUP: + { + // (x -- x x) + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype vch = stacktop(-1); + stack.push_back(vch); + } + break; + + case OP_NIP: + { + // (x1 x2 -- x2) + if (stack.size() < 2) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + stack.erase(stack.end() - 2); + } + break; + + case OP_OVER: + { + // (x1 x2 -- x1 x2 x1) + if (stack.size() < 2) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype vch = stacktop(-2); + stack.push_back(vch); + } + break; + + case OP_PICK: + case OP_ROLL: + { + // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn) + // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn) + if (stack.size() < 2) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + int n = CScriptNum(stacktop(-1), fRequireMinimal).getint(); + popstack(stack); + if (n < 0 || n >= (int)stack.size()) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype vch = stacktop(-n-1); + if (opcode == OP_ROLL) + stack.erase(stack.end()-n-1); + stack.push_back(vch); + } + break; + + case OP_ROT: + { + // (x1 x2 x3 -- x2 x3 x1) + // x2 x1 x3 after first swap + // x2 x3 x1 after second swap + if (stack.size() < 3) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + swap(stacktop(-3), stacktop(-2)); + swap(stacktop(-2), stacktop(-1)); + } + break; + + case OP_SWAP: + { + // (x1 x2 -- x2 x1) + if (stack.size() < 2) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + swap(stacktop(-2), stacktop(-1)); + } + break; + + case OP_TUCK: + { + // (x1 x2 -- x2 x1 x2) + if (stack.size() < 2) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype vch = stacktop(-1); + stack.insert(stack.end()-2, vch); + } + break; + + + case OP_SIZE: + { + // (in -- in size) + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + CScriptNum bn(stacktop(-1).size()); + stack.push_back(bn.getvch()); + } + break; + + + // + // Bitwise logic + // + case OP_EQUAL: + case OP_EQUALVERIFY: + //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL + { + // (x1 x2 - bool) + if (stack.size() < 2) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype& vch1 = stacktop(-2); + valtype& vch2 = stacktop(-1); + bool fEqual = (vch1 == vch2); + // OP_NOTEQUAL is disabled because it would be too easy to say + // something like n != 1 and have some wiseguy pass in 1 with extra + // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001) + //if (opcode == OP_NOTEQUAL) + // fEqual = !fEqual; + popstack(stack); + popstack(stack); + stack.push_back(fEqual ? vchTrue : vchFalse); + if (opcode == OP_EQUALVERIFY) + { + if (fEqual) + popstack(stack); + else + return set_error(serror, SCRIPT_ERR_EQUALVERIFY); + } + } + break; + + + // + // Numeric + // + case OP_1ADD: + case OP_1SUB: + case OP_NEGATE: + case OP_ABS: + case OP_NOT: + case OP_0NOTEQUAL: + { + // (in -- out) + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + CScriptNum bn(stacktop(-1), fRequireMinimal); + switch (opcode) + { + case OP_1ADD: bn += bnOne; break; + case OP_1SUB: bn -= bnOne; break; + case OP_NEGATE: bn = -bn; break; + case OP_ABS: if (bn < bnZero) bn = -bn; break; + case OP_NOT: bn = (bn == bnZero); break; + case OP_0NOTEQUAL: bn = (bn != bnZero); break; + default: assert(!"invalid opcode"); break; + } + popstack(stack); + stack.push_back(bn.getvch()); + } + break; + + case OP_ADD: + case OP_SUB: + case OP_BOOLAND: + case OP_BOOLOR: + case OP_NUMEQUAL: + case OP_NUMEQUALVERIFY: + case OP_NUMNOTEQUAL: + case OP_LESSTHAN: + case OP_GREATERTHAN: + case OP_LESSTHANOREQUAL: + case OP_GREATERTHANOREQUAL: + case OP_MIN: + case OP_MAX: + { + // (x1 x2 -- out) + if (stack.size() < 2) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + CScriptNum bn1(stacktop(-2), fRequireMinimal); + CScriptNum bn2(stacktop(-1), fRequireMinimal); + CScriptNum bn(0); + switch (opcode) + { + case OP_ADD: + bn = bn1 + bn2; + break; + + case OP_SUB: + bn = bn1 - bn2; + break; + + case OP_BOOLAND: bn = (bn1 != bnZero && bn2 != bnZero); break; + case OP_BOOLOR: bn = (bn1 != bnZero || bn2 != bnZero); break; + case OP_NUMEQUAL: bn = (bn1 == bn2); break; + case OP_NUMEQUALVERIFY: bn = (bn1 == bn2); break; + case OP_NUMNOTEQUAL: bn = (bn1 != bn2); break; + case OP_LESSTHAN: bn = (bn1 < bn2); break; + case OP_GREATERTHAN: bn = (bn1 > bn2); break; + case OP_LESSTHANOREQUAL: bn = (bn1 <= bn2); break; + case OP_GREATERTHANOREQUAL: bn = (bn1 >= bn2); break; + case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break; + case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break; + default: assert(!"invalid opcode"); break; + } + popstack(stack); + popstack(stack); + stack.push_back(bn.getvch()); + + if (opcode == OP_NUMEQUALVERIFY) + { + if (CastToBool(stacktop(-1))) + popstack(stack); + else + return set_error(serror, SCRIPT_ERR_NUMEQUALVERIFY); + } + } + break; + + case OP_WITHIN: + { + // (x min max -- out) + if (stack.size() < 3) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + CScriptNum bn1(stacktop(-3), fRequireMinimal); + CScriptNum bn2(stacktop(-2), fRequireMinimal); + CScriptNum bn3(stacktop(-1), fRequireMinimal); + bool fValue = (bn2 <= bn1 && bn1 < bn3); + popstack(stack); + popstack(stack); + popstack(stack); + stack.push_back(fValue ? vchTrue : vchFalse); + } + break; + + + // + // Crypto + // + case OP_RIPEMD160: + case OP_SHA1: + case OP_SHA256: + case OP_HASH160: + case OP_HASH256: + { + // (in -- hash) + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + valtype& vch = stacktop(-1); + valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32); + if (opcode == OP_RIPEMD160) + CRIPEMD160().Write(vch.data(), vch.size()).Finalize(vchHash.data()); + else if (opcode == OP_SHA1) + CSHA1().Write(vch.data(), vch.size()).Finalize(vchHash.data()); + else if (opcode == OP_SHA256) + CSHA256().Write(vch.data(), vch.size()).Finalize(vchHash.data()); + else if (opcode == OP_HASH160) + CHash160().Write(vch.data(), vch.size()).Finalize(vchHash.data()); + else if (opcode == OP_HASH256) + CHash256().Write(vch.data(), vch.size()).Finalize(vchHash.data()); + popstack(stack); + stack.push_back(vchHash); + } + break; + + case OP_CODESEPARATOR: + { + // Hash starts after the code separator + pbegincodehash = pc; + } + break; + + case OP_CHECKSIG: + case OP_CHECKSIGVERIFY: + { + // (sig pubkey -- bool) + if (stack.size() < 2) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + + valtype& vchSig = stacktop(-2); + valtype& vchPubKey = stacktop(-1); + + // Subset of script starting at the most recent codeseparator + CScript scriptCode(pbegincodehash, pend); + + // Drop the signature in pre-segwit scripts but not segwit scripts + if (sigversion == SIGVERSION_BASE) { + scriptCode.FindAndDelete(CScript(vchSig)); + } + + if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, sigversion, serror)) { + //serror is set + return false; + } + bool fSuccess = checker.CheckSig(vchSig, vchPubKey, scriptCode, sigversion); + + if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && vchSig.size()) + return set_error(serror, SCRIPT_ERR_SIG_NULLFAIL); + + popstack(stack); + popstack(stack); + stack.push_back(fSuccess ? vchTrue : vchFalse); + if (opcode == OP_CHECKSIGVERIFY) + { + if (fSuccess) + popstack(stack); + else + return set_error(serror, SCRIPT_ERR_CHECKSIGVERIFY); + } + } + break; + + case OP_CHECKMULTISIG: + case OP_CHECKMULTISIGVERIFY: + { + // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool) + + int i = 1; + if ((int)stack.size() < i) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + + int nKeysCount = CScriptNum(stacktop(-i), fRequireMinimal).getint(); + if (nKeysCount < 0 || nKeysCount > MAX_PUBKEYS_PER_MULTISIG) + return set_error(serror, SCRIPT_ERR_PUBKEY_COUNT); + nOpCount += nKeysCount; + if (nOpCount > MAX_OPS_PER_SCRIPT) + return set_error(serror, SCRIPT_ERR_OP_COUNT); + int ikey = ++i; + // ikey2 is the position of last non-signature item in the stack. Top stack item = 1. + // With SCRIPT_VERIFY_NULLFAIL, this is used for cleanup if operation fails. + int ikey2 = nKeysCount + 2; + i += nKeysCount; + if ((int)stack.size() < i) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + + int nSigsCount = CScriptNum(stacktop(-i), fRequireMinimal).getint(); + if (nSigsCount < 0 || nSigsCount > nKeysCount) + return set_error(serror, SCRIPT_ERR_SIG_COUNT); + int isig = ++i; + i += nSigsCount; + if ((int)stack.size() < i) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + + // Subset of script starting at the most recent codeseparator + CScript scriptCode(pbegincodehash, pend); + + // Drop the signature in pre-segwit scripts but not segwit scripts + for (int k = 0; k < nSigsCount; k++) + { + valtype& vchSig = stacktop(-isig-k); + if (sigversion == SIGVERSION_BASE) { + scriptCode.FindAndDelete(CScript(vchSig)); + } + } + + bool fSuccess = true; + while (fSuccess && nSigsCount > 0) + { + valtype& vchSig = stacktop(-isig); + valtype& vchPubKey = stacktop(-ikey); + + // Note how this makes the exact order of pubkey/signature evaluation + // distinguishable by CHECKMULTISIG NOT if the STRICTENC flag is set. + // See the script_(in)valid tests for details. + if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, sigversion, serror)) { + // serror is set + return false; + } + + // Check signature + bool fOk = checker.CheckSig(vchSig, vchPubKey, scriptCode, sigversion); + + if (fOk) { + isig++; + nSigsCount--; + } + ikey++; + nKeysCount--; + + // If there are more signatures left than keys left, + // then too many signatures have failed. Exit early, + // without checking any further signatures. + if (nSigsCount > nKeysCount) + fSuccess = false; + } + + // Clean up stack of actual arguments + while (i-- > 1) { + // If the operation failed, we require that all signatures must be empty vector + if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && !ikey2 && stacktop(-1).size()) + return set_error(serror, SCRIPT_ERR_SIG_NULLFAIL); + if (ikey2 > 0) + ikey2--; + popstack(stack); + } + + // A bug causes CHECKMULTISIG to consume one extra argument + // whose contents were not checked in any way. + // + // Unfortunately this is a potential source of mutability, + // so optionally verify it is exactly equal to zero prior + // to removing it from the stack. + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + if ((flags & SCRIPT_VERIFY_NULLDUMMY) && stacktop(-1).size()) + return set_error(serror, SCRIPT_ERR_SIG_NULLDUMMY); + popstack(stack); + + stack.push_back(fSuccess ? vchTrue : vchFalse); + + if (opcode == OP_CHECKMULTISIGVERIFY) + { + if (fSuccess) + popstack(stack); + else + return set_error(serror, SCRIPT_ERR_CHECKMULTISIGVERIFY); + } + } + break; + + default: + return set_error(serror, SCRIPT_ERR_BAD_OPCODE); + } + + // Size limits + if (stack.size() + altstack.size() > 1000) + return set_error(serror, SCRIPT_ERR_STACK_SIZE); + } + } + catch (...) + { + return set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); + } + + if (!vfExec.empty()) + return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); + + return set_success(serror); +} + +namespace { + +/** + * Wrapper that serializes like CTransaction, but with the modifications + * required for the signature hash done in-place + */ +class CTransactionSignatureSerializer { +private: + const CTransaction& txTo; //!< reference to the spending transaction (the one being serialized) + const CScript& scriptCode; //!< output script being consumed + const unsigned int nIn; //!< input index of txTo being signed + const bool fAnyoneCanPay; //!< whether the hashtype has the SIGHASH_ANYONECANPAY flag set + const bool fHashSingle; //!< whether the hashtype is SIGHASH_SINGLE + const bool fHashNone; //!< whether the hashtype is SIGHASH_NONE + +public: + CTransactionSignatureSerializer(const CTransaction &txToIn, const CScript &scriptCodeIn, unsigned int nInIn, int nHashTypeIn) : + txTo(txToIn), scriptCode(scriptCodeIn), nIn(nInIn), + fAnyoneCanPay(!!(nHashTypeIn & SIGHASH_ANYONECANPAY)), + fHashSingle((nHashTypeIn & 0x1f) == SIGHASH_SINGLE), + fHashNone((nHashTypeIn & 0x1f) == SIGHASH_NONE) {} + + /** Serialize the passed scriptCode, skipping OP_CODESEPARATORs */ + template + void SerializeScriptCode(S &s) const { + CScript::const_iterator it = scriptCode.begin(); + CScript::const_iterator itBegin = it; + opcodetype opcode; + unsigned int nCodeSeparators = 0; + while (scriptCode.GetOp(it, opcode)) { + if (opcode == OP_CODESEPARATOR) + nCodeSeparators++; + } + ::WriteCompactSize(s, scriptCode.size() - nCodeSeparators); + it = itBegin; + while (scriptCode.GetOp(it, opcode)) { + if (opcode == OP_CODESEPARATOR) { + s.write((char*)&itBegin[0], it-itBegin-1); + itBegin = it; + } + } + if (itBegin != scriptCode.end()) + s.write((char*)&itBegin[0], it-itBegin); + } + + /** Serialize an input of txTo */ + template + void SerializeInput(S &s, unsigned int nInput) const { + // In case of SIGHASH_ANYONECANPAY, only the input being signed is serialized + if (fAnyoneCanPay) + nInput = nIn; + // Serialize the prevout + ::Serialize(s, txTo.vin[nInput].prevout); + // Serialize the script + if (nInput != nIn) + // Blank out other inputs' signatures + ::Serialize(s, CScriptBase()); + else + SerializeScriptCode(s); + // Serialize the nSequence + if (nInput != nIn && (fHashSingle || fHashNone)) + // let the others update at will + ::Serialize(s, (int)0); + else + ::Serialize(s, txTo.vin[nInput].nSequence); + } + + /** Serialize an output of txTo */ + template + void SerializeOutput(S &s, unsigned int nOutput) const { + if (fHashSingle && nOutput != nIn) + // Do not lock-in the txout payee at other indices as txin + ::Serialize(s, CTxOut()); + else + ::Serialize(s, txTo.vout[nOutput]); + } + + /** Serialize txTo */ + template + void Serialize(S &s) const { + // Serialize nVersion + ::Serialize(s, txTo.nVersion); + // Serialize vin + unsigned int nInputs = fAnyoneCanPay ? 1 : txTo.vin.size(); + ::WriteCompactSize(s, nInputs); + for (unsigned int nInput = 0; nInput < nInputs; nInput++) + SerializeInput(s, nInput); + // Serialize vout + unsigned int nOutputs = fHashNone ? 0 : (fHashSingle ? nIn+1 : txTo.vout.size()); + ::WriteCompactSize(s, nOutputs); + for (unsigned int nOutput = 0; nOutput < nOutputs; nOutput++) + SerializeOutput(s, nOutput); + // Serialize nLockTime + ::Serialize(s, txTo.nLockTime); + } +}; + +uint256 GetPrevoutHash(const CTransaction& txTo) { + CHashWriter ss(SER_GETHASH, 0); + for (unsigned int n = 0; n < txTo.vin.size(); n++) { + ss << txTo.vin[n].prevout; + } + return ss.GetHash(); +} + +uint256 GetSequenceHash(const CTransaction& txTo) { + CHashWriter ss(SER_GETHASH, 0); + for (unsigned int n = 0; n < txTo.vin.size(); n++) { + ss << txTo.vin[n].nSequence; + } + return ss.GetHash(); +} + +uint256 GetOutputsHash(const CTransaction& txTo) { + CHashWriter ss(SER_GETHASH, 0); + for (unsigned int n = 0; n < txTo.vout.size(); n++) { + ss << txTo.vout[n]; + } + return ss.GetHash(); +} + +} // anon namespace + +PrecomputedTransactionData::PrecomputedTransactionData(const CTransaction& txTo) +{ + hashPrevouts = GetPrevoutHash(txTo); + hashSequence = GetSequenceHash(txTo); + hashOutputs = GetOutputsHash(txTo); +} + +uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache) +{ + if (sigversion == SIGVERSION_WITNESS_V0) { + uint256 hashPrevouts; + uint256 hashSequence; + uint256 hashOutputs; + + if (!(nHashType & SIGHASH_ANYONECANPAY)) { + hashPrevouts = cache ? cache->hashPrevouts : GetPrevoutHash(txTo); + } + + if (!(nHashType & SIGHASH_ANYONECANPAY) && (nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { + hashSequence = cache ? cache->hashSequence : GetSequenceHash(txTo); + } + + + if ((nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { + hashOutputs = cache ? cache->hashOutputs : GetOutputsHash(txTo); + } else if ((nHashType & 0x1f) == SIGHASH_SINGLE && nIn < txTo.vout.size()) { + CHashWriter ss(SER_GETHASH, 0); + ss << txTo.vout[nIn]; + hashOutputs = ss.GetHash(); + } + + CHashWriter ss(SER_GETHASH, 0); + // Version + ss << txTo.nVersion; + // Input prevouts/nSequence (none/all, depending on flags) + ss << hashPrevouts; + ss << hashSequence; + // The input being signed (replacing the scriptSig with scriptCode + amount) + // The prevout may already be contained in hashPrevout, and the nSequence + // may already be contain in hashSequence. + ss << txTo.vin[nIn].prevout; + ss << static_cast(scriptCode); + ss << amount; + ss << txTo.vin[nIn].nSequence; + // Outputs (none/one/all, depending on flags) + ss << hashOutputs; + // Locktime + ss << txTo.nLockTime; + // Sighash type + ss << nHashType; + + return ss.GetHash(); + } + + static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001")); + if (nIn >= txTo.vin.size()) { + // nIn out of range + return one; + } + + // Check for invalid use of SIGHASH_SINGLE + if ((nHashType & 0x1f) == SIGHASH_SINGLE) { + if (nIn >= txTo.vout.size()) { + // nOut out of range + return one; + } + } + + // Wrapper to serialize only the necessary parts of the transaction being signed + CTransactionSignatureSerializer txTmp(txTo, scriptCode, nIn, nHashType); + + // Serialize and hash + CHashWriter ss(SER_GETHASH, 0); + ss << txTmp << nHashType; + return ss.GetHash(); +} + +bool TransactionSignatureChecker::VerifySignature(const std::vector& vchSig, const CPubKey& pubkey, const uint256& sighash) const +{ + return pubkey.Verify(sighash, vchSig); +} + +bool TransactionSignatureChecker::CheckSig(const vector& vchSigIn, const vector& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const +{ + CPubKey pubkey(vchPubKey); + if (!pubkey.IsValid()) + return false; + + // Hash type is one byte tacked on to the end of the signature + vector vchSig(vchSigIn); + if (vchSig.empty()) + return false; + int nHashType = vchSig.back(); + vchSig.pop_back(); + + uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion, this->txdata); + + if (!VerifySignature(vchSig, pubkey, sighash)) + return false; + + return true; +} + +bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) const +{ + // There are two kinds of nLockTime: lock-by-blockheight + // and lock-by-blocktime, distinguished by whether + // nLockTime < LOCKTIME_THRESHOLD. + // + // We want to compare apples to apples, so fail the script + // unless the type of nLockTime being tested is the same as + // the nLockTime in the transaction. + if (!( + (txTo->nLockTime < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) || + (txTo->nLockTime >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD) + )) + return false; + + // Now that we know we're comparing apples-to-apples, the + // comparison is a simple numeric one. + if (nLockTime > (int64_t)txTo->nLockTime) + return false; + + // Finally the nLockTime feature can be disabled and thus + // CHECKLOCKTIMEVERIFY bypassed if every txin has been + // finalized by setting nSequence to maxint. The + // transaction would be allowed into the blockchain, making + // the opcode ineffective. + // + // Testing if this vin is not final is sufficient to + // prevent this condition. Alternatively we could test all + // inputs, but testing just this input minimizes the data + // required to prove correct CHECKLOCKTIMEVERIFY execution. + if (CTxIn::SEQUENCE_FINAL == txTo->vin[nIn].nSequence) + return false; + + return true; +} + +bool TransactionSignatureChecker::CheckSequence(const CScriptNum& nSequence) const +{ + // Relative lock times are supported by comparing the passed + // in operand to the sequence number of the input. + const int64_t txToSequence = (int64_t)txTo->vin[nIn].nSequence; + + // Fail if the transaction's version number is not set high + // enough to trigger BIP 68 rules. + if (static_cast(txTo->nVersion) < 2) + return false; + + // Sequence numbers with their most significant bit set are not + // consensus constrained. Testing that the transaction's sequence + // number do not have this bit set prevents using this property + // to get around a CHECKSEQUENCEVERIFY check. + if (txToSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) + return false; + + // Mask off any bits that do not have consensus-enforced meaning + // before doing the integer comparisons + const uint32_t nLockTimeMask = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | CTxIn::SEQUENCE_LOCKTIME_MASK; + const int64_t txToSequenceMasked = txToSequence & nLockTimeMask; + const CScriptNum nSequenceMasked = nSequence & nLockTimeMask; + + // There are two kinds of nSequence: lock-by-blockheight + // and lock-by-blocktime, distinguished by whether + // nSequenceMasked < CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG. + // + // We want to compare apples to apples, so fail the script + // unless the type of nSequenceMasked being tested is the same as + // the nSequenceMasked in the transaction. + if (!( + (txToSequenceMasked < CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG && nSequenceMasked < CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) || + (txToSequenceMasked >= CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG && nSequenceMasked >= CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) + )) { + return false; + } + + // Now that we know we're comparing apples-to-apples, the + // comparison is a simple numeric one. + if (nSequenceMasked > txToSequenceMasked) + return false; + + return true; +} + +static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion, const std::vector& program, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) +{ + vector > stack; + CScript scriptPubKey; + + if (witversion == 0) { + if (program.size() == 32) { + // Version 0 segregated witness program: SHA256(CScript) inside the program, CScript + inputs in witness + if (witness.stack.size() == 0) { + return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY); + } + scriptPubKey = CScript(witness.stack.back().begin(), witness.stack.back().end()); + stack = std::vector >(witness.stack.begin(), witness.stack.end() - 1); + uint256 hashScriptPubKey; + CSHA256().Write(&scriptPubKey[0], scriptPubKey.size()).Finalize(hashScriptPubKey.begin()); + if (memcmp(hashScriptPubKey.begin(), &program[0], 32)) { + return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH); + } + } else if (program.size() == 20) { + // Special case for pay-to-pubkeyhash; signature + pubkey in witness + if (witness.stack.size() != 2) { + return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH); // 2 items in witness + } + scriptPubKey << OP_DUP << OP_HASH160 << program << OP_EQUALVERIFY << OP_CHECKSIG; + stack = witness.stack; + } else { + return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH); + } + } else if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM) { + return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM); + } else { + // Higher version witness scripts return true for future softfork compatibility + return set_success(serror); + } + + // Disallow stack item size > MAX_SCRIPT_ELEMENT_SIZE in witness stack + for (unsigned int i = 0; i < stack.size(); i++) { + if (stack.at(i).size() > MAX_SCRIPT_ELEMENT_SIZE) + return set_error(serror, SCRIPT_ERR_PUSH_SIZE); + } + + if (!EvalScript(stack, scriptPubKey, flags, checker, SIGVERSION_WITNESS_V0, serror)) { + return false; + } + + // Scripts inside witness implicitly require cleanstack behaviour + if (stack.size() != 1) + return set_error(serror, SCRIPT_ERR_EVAL_FALSE); + if (!CastToBool(stack.back())) + return set_error(serror, SCRIPT_ERR_EVAL_FALSE); + return true; +} + +bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) +{ + static const CScriptWitness emptyWitness; + if (witness == NULL) { + witness = &emptyWitness; + } + bool hadWitness = false; + + set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); + + if ((flags & SCRIPT_VERIFY_SIGPUSHONLY) != 0 && !scriptSig.IsPushOnly()) { + return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY); + } + + vector > stack, stackCopy; + if (!EvalScript(stack, scriptSig, flags, checker, SIGVERSION_BASE, serror)) + { + // serror is set + return false; + } + + if (flags & SCRIPT_VERIFY_P2SH) + stackCopy = stack; + if (!EvalScript(stack, scriptPubKey, flags, checker, SIGVERSION_BASE, serror)) + { + // serror is set + return false; + } + + if (stack.empty()) + return set_error(serror, SCRIPT_ERR_EVAL_FALSE); + if (CastToBool(stack.back()) == false) + return set_error(serror, SCRIPT_ERR_EVAL_FALSE); + + // Bare witness programs + int witnessversion; + std::vector witnessprogram; + if (flags & SCRIPT_VERIFY_WITNESS) { + if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) { + hadWitness = true; + if (scriptSig.size() != 0) { + // The scriptSig must be _exactly_ CScript(), otherwise we reintroduce malleability. + return set_error(serror, SCRIPT_ERR_WITNESS_MALLEATED); + } + if (!VerifyWitnessProgram(*witness, witnessversion, witnessprogram, flags, checker, serror)) { + return false; + } + // Bypass the cleanstack check at the end. The actual stack is obviously not clean + // for witness programs. + stack.resize(1); + } + } + + // Additional validation for spend-to-script-hash transactions: + if ((flags & SCRIPT_VERIFY_P2SH) && scriptPubKey.IsPayToScriptHash()) + { + // scriptSig must be literals-only or validation fails + if (!scriptSig.IsPushOnly()) + return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY); + + // Restore stack. + swap(stack, stackCopy); + + // stack cannot be empty here, because if it was the + // P2SH HASH <> EQUAL scriptPubKey would be evaluated with + // an empty stack and the EvalScript above would return false. + assert(!stack.empty()); + + const valtype& pubKeySerialized = stack.back(); + CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end()); + popstack(stack); + + if (!EvalScript(stack, pubKey2, flags, checker, SIGVERSION_BASE, serror)) + // serror is set + return false; + if (stack.empty()) + return set_error(serror, SCRIPT_ERR_EVAL_FALSE); + if (!CastToBool(stack.back())) + return set_error(serror, SCRIPT_ERR_EVAL_FALSE); + + // P2SH witness program + if (flags & SCRIPT_VERIFY_WITNESS) { + if (pubKey2.IsWitnessProgram(witnessversion, witnessprogram)) { + hadWitness = true; + if (scriptSig != CScript() << std::vector(pubKey2.begin(), pubKey2.end())) { + // The scriptSig must be _exactly_ a single push of the redeemScript. Otherwise we + // reintroduce malleability. + return set_error(serror, SCRIPT_ERR_WITNESS_MALLEATED_P2SH); + } + if (!VerifyWitnessProgram(*witness, witnessversion, witnessprogram, flags, checker, serror)) { + return false; + } + // Bypass the cleanstack check at the end. The actual stack is obviously not clean + // for witness programs. + stack.resize(1); + } + } + } + + // The CLEANSTACK check is only performed after potential P2SH evaluation, + // as the non-P2SH evaluation of a P2SH script will obviously not result in + // a clean stack (the P2SH inputs remain). The same holds for witness evaluation. + if ((flags & SCRIPT_VERIFY_CLEANSTACK) != 0) { + // Disallow CLEANSTACK without P2SH, as otherwise a switch CLEANSTACK->P2SH+CLEANSTACK + // would be possible, which is not a softfork (and P2SH should be one). + assert((flags & SCRIPT_VERIFY_P2SH) != 0); + assert((flags & SCRIPT_VERIFY_WITNESS) != 0); + if (stack.size() != 1) { + return set_error(serror, SCRIPT_ERR_CLEANSTACK); + } + } + + if (flags & SCRIPT_VERIFY_WITNESS) { + // We can't check for correct unexpected witness data if P2SH was off, so require + // that WITNESS implies P2SH. Otherwise, going from WITNESS->P2SH+WITNESS would be + // possible, which is not a softfork. + assert((flags & SCRIPT_VERIFY_P2SH) != 0); + if (!hadWitness && !witness->IsNull()) { + return set_error(serror, SCRIPT_ERR_WITNESS_UNEXPECTED); + } + } + + return set_success(serror); +} + +size_t static WitnessSigOps(int witversion, const std::vector& witprogram, const CScriptWitness& witness, int flags) +{ + if (witversion == 0) { + if (witprogram.size() == 20) + return 1; + + if (witprogram.size() == 32 && witness.stack.size() > 0) { + CScript subscript(witness.stack.back().begin(), witness.stack.back().end()); + return subscript.GetSigOpCount(true); + } + } + + // Future flags may be implemented here. + return 0; +} + +size_t CountWitnessSigOps(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags) +{ + static const CScriptWitness witnessEmpty; + + if ((flags & SCRIPT_VERIFY_WITNESS) == 0) { + return 0; + } + assert((flags & SCRIPT_VERIFY_P2SH) != 0); + + int witnessversion; + std::vector witnessprogram; + if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) { + return WitnessSigOps(witnessversion, witnessprogram, witness ? *witness : witnessEmpty, flags); + } + + if (scriptPubKey.IsPayToScriptHash() && scriptSig.IsPushOnly()) { + CScript::const_iterator pc = scriptSig.begin(); + vector data; + while (pc < scriptSig.end()) { + opcodetype opcode; + scriptSig.GetOp(pc, opcode, data); + } + CScript subscript(data.begin(), data.end()); + if (subscript.IsWitnessProgram(witnessversion, witnessprogram)) { + return WitnessSigOps(witnessversion, witnessprogram, witness ? *witness : witnessEmpty, flags); + } + } + + return 0; +} diff --git a/.svn/pristine/16/161e4584aed75b864808fd4409ddf75fa8ea329e.svn-base b/.svn/pristine/16/161e4584aed75b864808fd4409ddf75fa8ea329e.svn-base new file mode 100644 index 0000000..d998ba8 --- /dev/null +++ b/.svn/pristine/16/161e4584aed75b864808fd4409ddf75fa8ea329e.svn-base @@ -0,0 +1,746 @@ + + + recvipchistory + + + + 0 + 0 + 953 + 675 + + + + Form + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 951 + 708 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + + 0 + 191 + + + + + 16777215 + 191 + + + + border:none + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 30 + + + 0 + + + + + 7 + + + + + + 41 + 41 + + + + + 41 + 41 + + + + background-image: url(:/res/png/recvicon.png);border:none + + + + + + + + + + + IsRecv + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 0 + 82 + + + + + 16777215 + 82 + + + + + + + + 0 + 0 + + + + + 13 + + + + background-color: rgb(242, 241, 240); + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + true + + + + + + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 61 + + + + + 16777215 + 61 + + + + border:none + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 30 + + + + + 0 + + + 7 + + + + + ipctype + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::RightToLeft + + + TextLabel + + + + + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 61 + + + + + 16777215 + 61 + + + + + 30 + + + 15 + + + + + authtype + + + + + + + Qt::Horizontal + + + + 566 + 20 + + + + + + + + TextLabel + + + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 61 + + + + + 16777215 + 61 + + + + + 30 + + + 15 + + + + + authlimit + + + + + + + Qt::Horizontal + + + + 566 + 20 + + + + + + + + TextLabel + + + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 61 + + + + + 16777215 + 61 + + + + + 30 + + + 15 + + + + + authdate + + + + + + + Qt::Horizontal + + + + 566 + 20 + + + + + + + + TextLabel + + + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 61 + + + + + 16777215 + 61 + + + + + 30 + + + 15 + + + + + fee + + + + + + + Qt::Horizontal + + + + 779 + 20 + + + + + + + + TextLabel + + + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 61 + + + + + 16777215 + 61 + + + + + 30 + + + 15 + + + + + add + + + + + + + Qt::Horizontal + + + + 807 + 20 + + + + + + + + TextLabel + + + Qt::TextSelectableByMouse + + + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 61 + + + + + 16777215 + 61 + + + + border:none + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 30 + + + + + + + ipcdate + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::RightToLeft + + + TextLabel + + + + + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 61 + + + + + 16777215 + 61 + + + + border:none + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 30 + + + + + + + ipcinfo + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + TextLabel + + + + + + + + + + + + Qt::Horizontal + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + diff --git a/.svn/pristine/1a/1a2a9df568d7ffbe07e6de2e2972fd27fa8803d1.svn-base b/.svn/pristine/1a/1a2a9df568d7ffbe07e6de2e2972fd27fa8803d1.svn-base new file mode 100644 index 0000000..39c9476 Binary files /dev/null and b/.svn/pristine/1a/1a2a9df568d7ffbe07e6de2e2972fd27fa8803d1.svn-base differ diff --git a/.svn/pristine/1a/1a34e14505778529c52448ea3757f7afb60aa901.svn-base b/.svn/pristine/1a/1a34e14505778529c52448ea3757f7afb60aa901.svn-base new file mode 100644 index 0000000..b8ea08d --- /dev/null +++ b/.svn/pristine/1a/1a34e14505778529c52448ea3757f7afb60aa901.svn-base @@ -0,0 +1,84 @@ +#ifndef ADDBOOKWIDGET_H +#define ADDBOOKWIDGET_H + +class AddressTableModel; +class AddModel; +#include +#include +#include +#include "guiutil.h" +#include +#include +#include +#include "MyLabel.h" +using namespace std; + +QT_BEGIN_NAMESPACE +class QItemSelection; +class QMenu; +class QModelIndex; +class QSortFilterProxyModel; +class QTableView; +class MyItemDelegate; +class MyStandardItemModel; + +QT_END_NAMESPACE +namespace Ui { +class AddBookWidget; +} +; + +struct txchangmap{ + QString txadd; + QString txlabel; +}; +class AddBookWidget : public QWidget +{ + Q_OBJECT + +public: + explicit AddBookWidget(QWidget *parent = 0); + ~AddBookWidget(); + enum TabTypes { + TAB_send = 2, + TAB_set = 5, + TAB_other = 3 + }; + QString returnaddress; + int addnewoneipcmessage(int pictype,QString name,QString add,int picprogess); + bool AddEditedRow(QString key,QString value); + void setModel(AddressTableModel *_model); + void selectNewAddress(const QModelIndex &parent, int begin, int /*end*/); + //void setModel(WalletModel *model); + QStandardItemModel *student_model; + + bool eventFilter(QObject *obj, QEvent *event); + void settag(int tag); + + int gettag(); + +Q_SIGNALS: + void backSend(); + void selectaddressyes(QString a,QString b); + void textChanged(QString text); +public Q_SLOTS: + void on_backButton_pressed(); + void txChanged(QString t,QString add); + void presswSlot(QString t,QString add); +private: + QLineEdit* namelabel ; + QLabel* namelabel0 ; + QLabel* timelabel ; + QLineEdit* timelabel0; + int etag ; + Ui::AddBookWidget *ui; + AddressTableModel *model; + AddModel *modelmodel; + QSortFilterProxyModel *proxyModel; + QSortFilterProxyModel *proxyModelnew; + QVBoxLayout * pvboxlayoutall; + std::unique_ptr filter; + map my_Map; +}; + +#endif // ADDBOOKWIDGET_H diff --git a/.svn/pristine/1b/1b2a5e3608e4039e663b87ba87af5bcd0b791892.svn-base b/.svn/pristine/1b/1b2a5e3608e4039e663b87ba87af5bcd0b791892.svn-base new file mode 100644 index 0000000..f2f0be3 --- /dev/null +++ b/.svn/pristine/1b/1b2a5e3608e4039e663b87ba87af5bcd0b791892.svn-base @@ -0,0 +1,411 @@ +// Copyright (c) 2011-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_QT_WALLETMODEL_H +#define BITCOIN_QT_WALLETMODEL_H + +#include "paymentrequestplus.h" +#include "walletmodeltransaction.h" + +#include "support/allocators/secure.h" + +#include +#include +#include +#include +#include +class AddressTableModel; +class OptionsModel; +class PlatformStyle; +class RecentRequestsTableModel; +class TransactionTableModel; +class WalletModelTransaction; +class CValidationState; +class CCoinControl; +class CKeyID; +class COutPoint; +class COutput; +class CPubKey; +class CWallet; +class uint256; +class CWalletTx; +class UnionAddressInfo; +QT_BEGIN_NAMESPACE +class QTimer; +QT_END_NAMESPACE + +class SendCoinsRecipient +{ +public: + explicit SendCoinsRecipient() : amount(0), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) { } + explicit SendCoinsRecipient(const QString &addr, const QString &_label, const CAmount& _amount, const QString &_message): + address(addr), label(_label), amount(_amount), message(_message), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) {} + + QString address; + QString label; + CAmount amount; + // If from a payment request, this is used for storing the memo + QString message; + + // If from a payment request, paymentRequest.IsInitialized() will be true + PaymentRequestPlus paymentRequest; + // Empty if no authentication or invalid signature/cert/etc. + QString authenticatedMerchant; + + bool fSubtractFeeFromAmount; // memory only + + static const int CURRENT_VERSION = 1; + int nVersion; + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { + std::string sAddress = address.toStdString(); + std::string sLabel = label.toStdString(); + std::string sMessage = message.toStdString(); + std::string sPaymentRequest; + if (!ser_action.ForRead() && paymentRequest.IsInitialized()) + paymentRequest.SerializeToString(&sPaymentRequest); + std::string sAuthenticatedMerchant = authenticatedMerchant.toStdString(); + + READWRITE(this->nVersion); + READWRITE(sAddress); + READWRITE(sLabel); + READWRITE(amount); + READWRITE(sMessage); + READWRITE(sPaymentRequest); + READWRITE(sAuthenticatedMerchant); + + if (ser_action.ForRead()) + { + address = QString::fromStdString(sAddress); + label = QString::fromStdString(sLabel); + message = QString::fromStdString(sMessage); + if (!sPaymentRequest.empty()) + paymentRequest.parse(QByteArray::fromRawData(sPaymentRequest.data(), sPaymentRequest.size())); + authenticatedMerchant = QString::fromStdString(sAuthenticatedMerchant); + } + } +}; + +/** Interface to Bitcoin wallet from Qt view code. */ +class WalletModel : public QObject +{ + Q_OBJECT + +public: + explicit WalletModel(const PlatformStyle *platformStyle, CWallet *wallet, OptionsModel *optionsModel, QObject *parent = 0); + ~WalletModel(); + + enum StatusCode // Returned by sendCoins + { + OK, + InvalidAmount, + InvalidAddress, + AmountExceedsBalance, + AmountWithFeeExceedsBalance, + DuplicateAddress, + TransactionCreationFailed, // Error returned when wallet is still locked + TransactionCommitFailed, + AbsurdFee, + PaymentRequestExpired, + PsdErr, + NumErr, + InitErr + }; + + enum EncryptionStatus + { + Unencrypted, // !wallet->IsCrypted() + Locked, // wallet->IsCrypted() && wallet->IsLocked() + Unlocked // wallet->IsCrypted() && !wallet->IsLocked() + }; + + OptionsModel *getOptionsModel(); + AddressTableModel *getAddressTableModel(); + TransactionTableModel *getTransactionTableModel(); + RecentRequestsTableModel *getRecentRequestsTableModel(); + + CAmount getBalance(const CCoinControl *coinControl = NULL) const; + + CAmount GetDetained() const; + int GetDepth() const; + + uint64_t getpow10(uint64_t oldnum,int n); + + CAmount getUnconfirmedBalance() const; + CAmount getImmatureBalance() const; + bool haveWatchOnly() const; + CAmount getWatchBalance() const; + CAmount getWatchUnconfirmedBalance() const; + CAmount getWatchImmatureBalance() const; + EncryptionStatus getEncryptionStatus() const; + + // Check address for validity + bool validateAddress(const QString &address); + + // Return status record for SendCoins, contains error id + information + struct SendCoinsReturn + { + SendCoinsReturn(StatusCode _status = OK, QString _reasonCommitFailed = "") + : status(_status), + reasonCommitFailed(_reasonCommitFailed) + { + } + StatusCode status; + QString reasonCommitFailed; + }; + + + struct CBookKeep + { + std::string time; + std::string award; + }; + struct keepupaccountInfo{ + CAmount Coin_; + QString Add_; + + + }; + + + void getbookkeepList(std::vector& bookkeeplist); +//20180201 + void startTimerControl(); + + QString processeCoinsCreateReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn); + + SendCoinsReturn prepareeCoinsCreate(QString coin_name,QString coin_md5,QString coin_label,QString timestr,QString add1,QString &msg,int inttimr,int accuracy,uint64_t amount1); + +//20180201 + // prepare transaction for getting txfee before sending coins + SendCoinsReturn prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl = NULL); + + SendCoinsReturn prepareBookkeepingTransaction(QString add1,CAmount amount1,std::string &error,WalletModelTransaction &transaction, const CCoinControl *coinControl); + SendCoinsReturn sendBookkeeping(QString add2,WalletModelTransaction &transaction); + SendCoinsReturn prepareExitBookkeeping(const CCoinControl *coinControl,std::string &error); + SendCoinsReturn ExitBookkeeping(WalletModelTransaction &transaction); + SendCoinsReturn prepareeCoinsCreateTransaction(QStringList label,QString add1,WalletModelTransaction &transaction, const CCoinControl *coinControl); + SendCoinsReturn prepareeCoinsSendCreateTransaction(std::string& Txid,int Index,uint64_t eCount,WalletModelTransaction &transaction, std::string &error, const CCoinControl *coinControl = NULL); + + SendCoinsReturn prepareNormalTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl = NULL); + SendCoinsReturn prepareIPCRegTransaction(WalletModelTransaction &transaction, uint8_t ExtendType, uint32_t startTime, uint32_t stopTime, uint8_t reAuthorize, uint8_t uniqueAuthorize, std::string hash, std::string labelTitle, std::string txLabel, const CCoinControl *coinControl = NULL); + SendCoinsReturn prepareIPCSendTransaction(std::string& IPCSendvinTxid,int Index, WalletModelTransaction &transaction, const CCoinControl *coinControl = NULL); + SendCoinsReturn prepareIPCAuthorizationTransaction(WalletModelTransaction &transaction,std::string txid,int txi, QStringList data, const CCoinControl *coinControl = NULL); + SendCoinsReturn prepareTokenRegTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl = NULL); + SendCoinsReturn prepareTokenTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl = NULL); + + + SendCoinsReturn sendIpcTransfer(); + SendCoinsReturn sendCoins(WalletModelTransaction &transaction); + + SendCoinsReturn sendcreateeCoins(); + + bool setWalletEncrypted(bool encrypted, const SecureString &passphrase); + // Passphrase only needed when unlocking + bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString()); + bool changePassphrase(const SecureString &oldPass, const SecureString &newPass); + // Wallet backup + bool backupWallet(const QString &filename); + void getScript(std::string add,int& sign_num,int &nRequired,std::string& script); + + bool analyTransaction(const std::string& str,std::string& strFailReason,std::string& address,CAmount& money,int haveSigned,std::string& sourceaddress); + SendCoinsReturn prepareUnionaccountCreateTransaction(QString addfrom,WalletModelTransaction &transaction, const CCoinControl *coinControl,ScriptError &serror,std::string &strtx,std::string &m_error); + WalletModel::SendCoinsReturn repreparUnionaccountCreate(QString addfrom,QString add,CAmount num,ScriptError &serror,std::string &strtx); + bool commitUnionaccounttra(const std::string& strtx, std::string& strFailReason, ScriptError& serror, std::string& strtxout,CMutableTransaction& mergedTx); + + bool commitUnionaccounttra_plus(CMutableTransaction& mergedTx,std::string& error); + + // RAI object for unlocking wallet, returned by requestUnlock() + class UnlockContext + { + public: + UnlockContext(WalletModel *wallet, bool valid, bool relock); + ~UnlockContext(); + + bool isValid() const { return valid; } + + // Copy operator and constructor transfer the context + UnlockContext(const UnlockContext& obj) { CopyFrom(obj); } + UnlockContext& operator=(const UnlockContext& rhs) { CopyFrom(rhs); return *this; } + private: + WalletModel *wallet; + bool valid; + mutable bool relock; // mutable, as it can be set to false by copying + + void CopyFrom(const UnlockContext& rhs); + }; + + UnlockContext requestUnlock(); + + bool getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const; + bool havePrivKey(const CKeyID &address) const; + bool getPrivKey(const CKeyID &address, CKey& vchPrivKeyOut) const; + void getOutputs(const std::vector& vOutpoints, std::vector& vOutputs); + bool isSpent(const COutPoint& outpoint) const; + void listCoins(std::map >& mapCoins) const; + + bool isLockedCoin(uint256 hash, unsigned int n) const; + void lockCoin(COutPoint& output); + void unlockCoin(COutPoint& output); + void listLockedCoins(std::vector& vOutpts); + + void loadReceiveRequests(std::vector& vReceiveRequests); + bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest); + + bool transactionCanBeAbandoned(uint256 hash) const; + bool abandonTransaction(uint256 hash) const; + + static bool isWalletEnabled(); + + bool hdEnabled() const; + + int getDefaultConfirmTarget() const; + + //ipclist + std::vector m_ipcCoins; + std::vector m_eCoins; + //get ipc list + void getIpcListCoins(QVector&); + void getTokenListCoins(std::map&); + QStringList getInfoFromIpcList(int index); + bool CreateIpcRegister(QString,QString,QString,QString,int,QString &msg,int &fee); + bool CreateWalletFromFile(QString); + QString IntTimeToQStringTime(int); + QString IntTimeToLocalQStringTime(int inttime); + QString IntTimeToQStringTimeForDetilDialog(int); + bool sendIpcCoins(); + bool LoadWalletFromFile(QString filepath); + bool transferIpc(QString address,QString &errstr); + + //20180201 + + void lookuphistory(std::map &vCoins ,std::string add); + + + bool preparetransferIpc(QString address,QString &msg); + bool prepareauthorizationIpc(QString address,int license,int exclusive,int intstart,int intend,QString& msg); + bool sendauthorizationIpc(QString &msg); + WalletModel::SendCoinsReturn prepareecoinaffrim(QString num,QString add,QString name); + WalletModel::SendCoinsReturn sendecoinaffrim(); + + WalletModel::SendCoinsReturn sendtransferIpc(); + //20180201 + bool authorizationIpc(QString,int,int,int,int,QString&); + CAmount getTotal(QList&,QSet&,int &); + bool ExportWalletToFile(std::string); + bool CheckPassword(); + bool CheckIsCrypted(); + int GetAccuracyBySymbol(std::string tokensymbol); + std::string m_sendcoinerror; + QString getAccuracyNumstr(QString name ,QString num); + QString getDeposit(QString address); + void setUpdataFinished(); + bool m_bFinishedLoading; + int GetDepthInMainChain(int iIndex); + QString GetECoinCanUseNum(QString name); + QString GetIssueDateBySymbol(QString name); + QString GetTimeOfTokenInChain(int iIndex); + QDate getSySQDate(); + bool CanIPCTransaction(int iIndex); + bool copyFileToPath(QString sourceDir ,QString toDir, bool coverFileIfExist,bool flushwallet); + QString getCreditValue(QString strDeposit); + QString GetHashBySymbol(QString tokensymbol); + + bool addtopubkey(std::string& add,std::string& key, std::string& strFailReason); + bool CreateUnionAddress(unsigned int nRequired, const std::vector& strPubkeys, std::string& multiscript, std::string& strmultiaddress,std::string& strFailReason ); + bool joinunionaccount(std::string union_script, std::string& strFailReason ,std::string name); + void getUnionAddressinfo(std::vector &addinfo); + void getAccounttrainfo(std::map &addinfo); + bool isMyPk(std::string addpk); + bool vinsFindAddress(const std::vector& vin,std::string address); + int64_t GetBlockTime(const CWalletTx& wtx); + QString FormatTxTimeP2SH(const CWalletTx& wtx); + QString FormatTxStatus(const CWalletTx& wtx); +private: + CWallet *wallet; + WalletModelTransaction *m_WalletModelTransactionIpcRegister; + WalletModelTransaction *m_WalletModelTransactioneCoinRegister; + WalletModelTransaction *m_WalletModelTransactioneCoinSend1; + WalletModelTransaction *m_WalletModelTransactionIpcTransfer; + WalletModelTransaction *currentTransaction1; + bool fHaveWatchOnly; + bool fForceCheckBalanceChanged; + bool ipcSendIsValidState; + int ipcSelectFromList; + + + // Wallet has an options model for wallet-specific options + // (transaction fee, for example) + OptionsModel *optionsModel; + + AddressTableModel *addressTableModel; + TransactionTableModel *transactionTableModel; + RecentRequestsTableModel *recentRequestsTableModel; + + // Cache some values to be able to detect changes + CAmount cachedBalance; + CAmount cachedUnconfirmedBalance; + CAmount cachedImmatureBalance; + CAmount cachedWatchOnlyBalance; + CAmount cachedWatchUnconfBalance; + CAmount cachedWatchImmatureBalance; + CAmount cachednewDepositBalance; + + + EncryptionStatus cachedEncryptionStatus; + int cachedNumBlocks; + + QTimer *pollTimer; + QTimer *pollTimer_; + void subscribeToCoreSignals(); + void unsubscribeFromCoreSignals(); + void checkBalanceChanged(); + +Q_SIGNALS: + // Signal that balance in wallet changed + void balanceChanged(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance, + const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance,const CAmount& depositBalance); + + // Encryption status of wallet changed + void encryptionStatusChanged(int status); + + // Signal emitted when wallet needs to be unlocked + // It is valid behaviour for listeners to keep the wallet locked after this signal; + // this means that the unlocking failed or was cancelled. + void requireUnlock(); + + // Fired when a message should be reported to the user + void message(const QString &title, const QString &message, unsigned int style); + + // Coins sent: from wallet, to recipient, in (serialized) transaction: + void coinsSent(CWallet* wallet, SendCoinsRecipient recipient, QByteArray transaction); + + // Show progress dialog e.g. for rescan + void showProgress(const QString &title, int nProgress); + + // Watch-only address added + void notifyWatchonlyChanged(bool fHaveWatchonly); + + void updateIpcList(); + void updataLoadingFinished(); + void updataLater(); + +public Q_SLOTS: + /* Wallet status might have changed */ + void updateStatus(); + /* New transaction, or transaction changed status */ + void updateTransaction(); + /* New, updated or removed address book entry */ + void updateAddressBook(const QString &address, const QString &label, bool isMine, const QString &purpose, int status); + /* Watch-only added */ + void updateWatchOnlyFlag(bool fHaveWatchonly); + /* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */ + void pollBalanceChanged(); + void updateTimer(); +}; + +#endif // BITCOIN_QT_WALLETMODEL_H diff --git a/.svn/pristine/1c/1c72965062cef9b7c380890298b8ba195bb6a1ca.svn-base b/.svn/pristine/1c/1c72965062cef9b7c380890298b8ba195bb6a1ca.svn-base new file mode 100644 index 0000000..b1ec608 --- /dev/null +++ b/.svn/pristine/1c/1c72965062cef9b7c380890298b8ba195bb6a1ca.svn-base @@ -0,0 +1,112 @@ +#include "recvipchistory.h" +#include "ui_recvipchistory.h" +#include "transactiontablemodel.h" +#include "log/log.h" +#include +recvipchistory::recvipchistory(QWidget *parent) : + QWidget(parent), + ui(new Ui::recvipchistory) +{ + ui->setupUi(this); + this->setWindowFlags(Qt::FramelessWindowHint); + ui->scrollArea->setFrameShape(QFrame::NoFrame); +} + +recvipchistory::~recvipchistory() +{ + delete ui; +} +void recvipchistory::updateInfo(QString status) +{ + ui->infolabel->setText(status); +} + +void recvipchistory::showVisual(bool visual) +{ + if(visual) + { + setVisible(true); + } + else + { + setVisible(false); + } +} +void recvipchistory::setinfo(const QModelIndex &idx) +{ + QString add = idx.data(TransactionTableModel::AddressRole).toString(); + QString add1 = idx.data(TransactionTableModel::ToAddress).toString(); + + QString ipctitle = idx.data(TransactionTableModel::IPCTitle).toString(); + qint64 ipctype = idx.data(TransactionTableModel::IPCType).toLongLong(); + + QString Authlimit = idx.data(TransactionTableModel::AuthLimit).toString(); + QString Authtype = idx.data(TransactionTableModel::AuthType).toString(); + QString Authtime = idx.data(TransactionTableModel::AuthTime).toString(); + QString lang = idx.data(TransactionTableModel::LanguageRole).toString(); + QString m_txid = idx.data(TransactionTableModel::TxIDRole).toString(); + LOG_WRITE(LOG_INFO,"recvipchistory++hashid",m_txid.toStdString().c_str()); + QString m_status = idx.data(TransactionTableModel::InfoStatus).toString(); + QString m_time = idx.data(TransactionTableModel::InfoTime).toString(); + qint64 txfee = idx.data(TransactionTableModel::feeAmount).toLongLong(); + QString m_txfee = BitcoinUnits::formatWithUnit(BitcoinUnit::IPC, txfee, false, BitcoinUnits::separatorAlways); + if(txfee != 0) + { + QString m_txfee = BitcoinUnits::formatWithUnit(BitcoinUnit::IPC, txfee, false, BitcoinUnits::separatorAlways); + ui->feeLabel->show(); + ui->feelabel->show(); + ui->widget_6->show(); + ui->line_9->show(); + ui->feeLabel->setText(m_txfee); + }else{ + ui->feeLabel->hide(); + ui->feelabel->hide(); + ui->widget_6->hide(); + ui->line_9->hide(); + } + + if(Authtime == "forever") + { + ui->authdata->setText(tr("forever")); + }else + { + if(Authtime.indexOf("forever") != -1) + { + int t = Authtime.indexOf("--"); + QString X = Authtime.mid(0,t); + Authtime = X + tr("--")+tr("forever"); + ui->authdata->setText(Authtime); + } + else + { + ui->authdata->setText(Authtime); + } + + } + if("ownership"==Authtype){ + ui->authtype->setText(tr("ownership")); + }else{ + ui->authtype->setText(tr("Use right")); + } + if("can authorization"==Authlimit){ + ui->authlimit->setText(tr("can authorization")); + }else{ + ui->authlimit->setText(tr("cannot authorization")); + } + + QStringList type = QStringList()<=0&&ipctype<8) + { + IPCType = type.at(ipctype); + } + else + { + IPCType =tr("patent"); + } + ui->typelabel->setText(IPCType); + ui->add_label->setText(add); + ui->infolabel->setText(m_status); + ui->timelabel->setText(m_time); + ui->ipclabel->setText(ipctitle); +} diff --git a/.svn/pristine/20/20405e941917e2fa31a140229a5fad60b5a3a8d6.svn-base b/.svn/pristine/20/20405e941917e2fa31a140229a5fad60b5a3a8d6.svn-base new file mode 100644 index 0000000..94192ba --- /dev/null +++ b/.svn/pristine/20/20405e941917e2fa31a140229a5fad60b5a3a8d6.svn-base @@ -0,0 +1,274 @@ +#include "addbookwidget.h" +#include "forms/ui_addbookwidget.h" +#include "addresstablemodel.h" +#include "ui_interface.h" +#include "clickqlabel.h" +#include +#include "addmodel.h" +#include +#include "upgradewidget.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +bool AddBookWidget::eventFilter(QObject *obj, QEvent *event) +{ + + QMouseEvent *ev = (QMouseEvent*)event;//QEvent::KeyPress + if (obj == ui->scrollArea) { + if (ev->button() ==Qt::LeftButton || event->type() == QEvent::MouseMove) { + QMouseEvent *event = static_cast (event); + return true; + } else { + return false; + } + } + + else if(obj == namelabel) + { + if (event->type() == QEvent::KeyRelease) + { + return true; + } else { + return false; + } + } + else if(obj == timelabel) + { + if (event->type() == QEvent::KeyRelease) + { + return true; + } else { + return false; + } + } + else { + } +} +AddBookWidget::AddBookWidget(QWidget *parent) : + QWidget(parent), + ui(new Ui::AddBookWidget) +{ + ui->setupUi(this); + ui->scrollArea->installEventFilter(this); + QWidget * pnewall = new QWidget(); + pvboxlayoutall = new QVBoxLayout(); + pnewall->setLayout(pvboxlayoutall); + proxyModel = NULL; + ui->scrollArea->setWidget(pnewall); +} +bool AddBookWidget::AddEditedRow(QString key,QString value){ + QWidget * pnewall = new QWidget(); + pvboxlayoutall = new QVBoxLayout(); + pnewall->setLayout(pvboxlayoutall); + + ui->scrollArea->setWidget(pnewall); + + model->addRow( AddressTableModel::Send, + key, + value); + setModel(model); + return true; +} + +int AddBookWidget::addnewoneipcmessage(int pictype,QString name,QString add,int picprogess) +{ + upgradewidget * pnewone = new upgradewidget(); + pnewone->setMaximumHeight(105); + pnewone->setMinimumHeight(105); + if(TAB_set == gettag()) + { + pnewone->setIntertag(5); + } + else if(TAB_other == gettag()) + { + pnewone->setIntertag(3); + } + else if(TAB_send == gettag()) + { + pnewone->setIntertag(2); + } + QHBoxLayout * phboxlayout = new QHBoxLayout(); + pnewone->setLayout(phboxlayout); + static int num=0; + num++; + QLabel* pictypelabel = new QLabel(QString::number(num)); + phboxlayout->addWidget(pictypelabel);//ren + QVBoxLayout * pvboxlayout = new QVBoxLayout(); + phboxlayout->addLayout(pvboxlayout); + + if(TAB_send == gettag()) + { + namelabel0 = new ClickQLabel(); + namelabel0->setText(name); + QFont font("Microsoft YaHei", 12, 35); + namelabel0->setFont(font); + pvboxlayout->addWidget(namelabel0); + } + else + { + namelabel =new QLineEdit(); + namelabel->setFocusPolicy(Qt::ClickFocus); + namelabel->setStyleSheet("background-color:rgb(242,241,240);border:0px");//color:#F2F1F0; + namelabel->setMouseTracking(true); + namelabel->setAutoFillBackground(true); + namelabel->setText(name); + + QFont ftname; + ftname.setPointSize(12); + QFont font("Microsoft YaHei", 12, 35); + namelabel->setFont(font);//"Timers" , 28 , QFont::Bold) + QPalette paname; + paname.setColor(QPalette::WindowText,Qt::gray); + namelabel->setPalette(paname); + connect(namelabel,SIGNAL(textChanged(QString)),pnewone,SLOT(changetext(QString))); + pvboxlayout->addWidget(namelabel); + } + connect(pnewone,SIGNAL(updateinfo(QString,QString)),this,SLOT(txChanged(QString,QString))); + + if(TAB_send == gettag()) + { + timelabel = new ClickQLabel(); + timelabel->setText(add); + QFont fttime("Microsoft YaHei", 12, 35);; + timelabel->setFont(fttime); + QPalette patime; + patime.setColor(QPalette::WindowText,Qt::gray); + timelabel->setPalette(patime); + pvboxlayout->addWidget(timelabel); + } + else + { + timelabel0 =new QLineEdit(); + timelabel0->setReadOnly(true); + timelabel0->setFocusPolicy(Qt::ClickFocus); + timelabel0->setStyleSheet("background-color:rgb(242,241,240);border:0px");//color:#F2F1F0; + timelabel0->setMouseTracking(true); + timelabel0->setAutoFillBackground(true); + timelabel0->setText(add); + + QFont font("Microsoft YaHei", 9, 35); + timelabel0->setFont(font);//"Timers" , 28 , QFont::Bold) + QPalette paname; + paname.setColor(QPalette::WindowText,Qt::gray); + pvboxlayout->addWidget(timelabel0); + } + pnewone->setadd(add); + pnewone->setlabel(name); + + pvboxlayoutall->addWidget(pnewone); + connect(pnewone,SIGNAL(pressw(QString,QString)),this,SIGNAL(selectaddressyes(QString,QString)) ); + QString picpath; + QString picprogesspath; + + picprogesspath =":/res/png/ren.png"; + pictypelabel->setFixedSize(57,57); + QPixmapCache::clear(); + QPixmapCache::setCacheLimit(1); + QPixmap p; + p.load(picprogesspath); + pictypelabel->setPixmap(p); + + txchangmap txmap; + txmap.txadd =add; + txmap.txlabel = name; + return 1; + +} + + +void AddBookWidget::txChanged(QString t,QString add) +{ + this->model->updateEntry(add,t,false,"",ChangeType::CT_UPDATEDM); +} + +void AddBookWidget::settag(int tag) +{ + etag = tag; + + if(TAB_set == etag) + { + ui->backButton->setVisible(false); + } + else if(TAB_send == etag) + { + ui->backButton->setVisible(true); + } + else + { + ui->backButton->setVisible(false); + } + +} + +int AddBookWidget::gettag() +{ + return etag; +} +void AddBookWidget::setModel(AddressTableModel *_model) +{ + this->model = _model; + if(!_model) + return; + if(proxyModel) + { + QList btns = this->pvboxlayoutall->findChildren(); + BOOST_FOREACH(QWidget* btn, btns) + { + btn->deleteLater(); + delete btn; + } + pvboxlayoutall->deleteLater(); + delete pvboxlayoutall; + pvboxlayoutall = NULL; + QWidget * pnewall = new QWidget(); + pvboxlayoutall = new QVBoxLayout(); + pnewall->setLayout(pvboxlayoutall); + delete proxyModel; + proxyModel = NULL; + ui->scrollArea->setWidget(pnewall); + + //proxyModel->invalidate(); + }//else{ + proxyModel = new QSortFilterProxyModel(this); + proxyModel->setSourceModel(_model); + proxyModel->setDynamicSortFilter(true); + proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); + proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); + proxyModel->setFilterRole(AddressTableModel::TypeRole); + proxyModel->setFilterFixedString(AddressTableModel::Send); + proxyModel->setFilterRole(AddressTableModel::TypeRole); + //} + int t = proxyModel->rowCount(); + for(int i= 0,j=0;iindex(j,0, QModelIndex()); + QModelIndex buttomindex= proxyModel->index(j,1, QModelIndex()); + QVariant topvar= topindex.data(); + QVariant bumvar= buttomindex.data(); + addnewoneipcmessage(1,topvar.toString(),bumvar.toString(),1); + } + + QSpacerItem* horizontalSpacer = new QSpacerItem(20,40,QSizePolicy::Minimum, QSizePolicy::Expanding); + pvboxlayoutall->addSpacerItem(horizontalSpacer); +} +AddBookWidget::~AddBookWidget() +{ + delete ui; +} + +void AddBookWidget::on_backButton_pressed() +{ + Q_EMIT backSend(); +} +void AddBookWidget::presswSlot(QString t,QString add) +{ + + Q_EMIT selectaddressyes(t,add); +} diff --git a/.svn/pristine/21/21420691c098abd1018cd2727f3210b8aef4133a.svn-base b/.svn/pristine/21/21420691c098abd1018cd2727f3210b8aef4133a.svn-base new file mode 100644 index 0000000..a988489 --- /dev/null +++ b/.svn/pristine/21/21420691c098abd1018cd2727f3210b8aef4133a.svn-base @@ -0,0 +1,41 @@ +#ifndef SETRECOVERY_H +#define SETRECOVERY_H + +#include +class WalletModel; +namespace Ui { +class SetRecovery; +} + +class SetRecovery : public QWidget +{ + Q_OBJECT + +public: + explicit SetRecovery(QWidget *parent = 0); + ~SetRecovery(); + WalletModel *walletModel; + void setWalletModel(WalletModel * model); + void setDestSourcePath(QString path); + static QString m_setRecoveryPath; +private Q_SLOTS: + void on_pushButton_import_pressed(); + void on_pushButton_select_pressed(); + void on_pushButton_back_pressed(); +Q_SIGNALS: + void back(); + void next(); + void success(int); + +private: + Ui::SetRecovery *ui; + QString m_file_full; + bool setCreatePage; + QString m_desPath; + QString m_file_path; + + bool isDirExist(QString fullPath); + bool copyFileToPath(QString sourceDir ,QString toDir, bool coverFileIfExist); +}; + +#endif // SETRECOVERY_H diff --git a/.svn/pristine/22/221ab47133894f43745ea3fd8c86846cdbaf79d1.svn-base b/.svn/pristine/22/221ab47133894f43745ea3fd8c86846cdbaf79d1.svn-base new file mode 100644 index 0000000..7e0ef5f --- /dev/null +++ b/.svn/pristine/22/221ab47133894f43745ea3fd8c86846cdbaf79d1.svn-base @@ -0,0 +1,979 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + +#include "util.h" + +#include "chainparamsbase.h" +#include "random.h" +#include "serialize.h" +#include "sync.h" +#include "utilstrencodings.h" +#include "utiltime.h" + +#include + +#if (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)) +#include +#include +#endif + +#ifndef WIN32 +// for posix_fallocate +#ifdef __linux__ + +#ifdef _POSIX_C_SOURCE +#undef _POSIX_C_SOURCE +#endif + +#define _POSIX_C_SOURCE 200112L + +#endif // __linux__ + +#include +#include +#include +#include + +#else + +#ifdef _MSC_VER +#pragma warning(disable:4786) +#pragma warning(disable:4804) +#pragma warning(disable:4805) +#pragma warning(disable:4717) +#endif + +#ifdef _WIN32_WINNT +#undef _WIN32_WINNT +#endif +#define _WIN32_WINNT 0x0501 + +#ifdef _WIN32_IE +#undef _WIN32_IE +#endif +#define _WIN32_IE 0x0501 + +#define WIN32_LEAN_AND_MEAN 1 +#ifndef NOMINMAX +#define NOMINMAX +#endif + +#include /* for _commit */ +#include +#endif + +#ifdef HAVE_SYS_PRCTL_H +#include +#endif + +#ifdef HAVE_MALLOPT_ARENA_MAX +#include +#endif + +#include // for to_lower() +#include +#include // for startswith() and endswith() +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +// Work around clang compilation problem in Boost 1.46: +// /usr/include/boost/program_options/detail/config_file.hpp:163:17: error: call to function 'to_internal' that is neither visible in the template definition nor found by argument-dependent lookup +// See also: http://stackoverflow.com/questions/10020179/compilation-fail-in-boost-librairies-program-options +// http://clang.debian.net/status.php?version=3.0&key=CANNOT_FIND_FUNCTION +namespace boost { + + namespace program_options { + std::string to_internal(const std::string&); + } + +} // namespace boost + +using namespace std; + +const char * const BITCOIN_CONF_FILENAME = "ipchaind.conf"; +const char * const BITCOIN_PID_FILENAME = "ipchaind.pid"; +const string strDebuglogDir= "Debuglogs"; + +CCriticalSection cs_args; +map mapArgs; +static map > _mapMultiArgs; +const map >& mapMultiArgs = _mapMultiArgs; +bool fDebug = false; +bool fPrintToConsole = false; +bool fPrintToDebugLog = true; +//bool fPrintToDebugLog = false; +bool fDebugLogFirst = true; + +bool fLogTimestamps = DEFAULT_LOGTIMESTAMPS; +bool fLogTimeMicros = DEFAULT_LOGTIMEMICROS; +bool fLogIPs = DEFAULT_LOGIPS; +std::atomic fReopenDebugLog(false); +std::atomic fReopenDebugLogQ(false); +CTranslationInterface translationInterface; + +/** Init OpenSSL library multithreading support */ +static CCriticalSection** ppmutexOpenSSL; +void locking_callback(int mode, int i, const char* file, int line) NO_THREAD_SAFETY_ANALYSIS +{ + if (mode & CRYPTO_LOCK) { + ENTER_CRITICAL_SECTION(*ppmutexOpenSSL[i]); + } else { + LEAVE_CRITICAL_SECTION(*ppmutexOpenSSL[i]); + } +} + +// Init +class CInit +{ +public: + CInit() + { + // Init OpenSSL library multithreading support + ppmutexOpenSSL = (CCriticalSection**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(CCriticalSection*)); + for (int i = 0; i < CRYPTO_num_locks(); i++) + ppmutexOpenSSL[i] = new CCriticalSection(); + CRYPTO_set_locking_callback(locking_callback); + + // OpenSSL can optionally load a config file which lists optional loadable modules and engines. + // We don't use them so we don't require the config. However some of our libs may call functions + // which attempt to load the config file, possibly resulting in an exit() or crash if it is missing + // or corrupt. Explicitly tell OpenSSL not to try to load the file. The result for our libs will be + // that the config appears to have been loaded and there are no modules/engines available. + OPENSSL_no_config(); + +#ifdef WIN32 + // Seed OpenSSL PRNG with current contents of the screen + RAND_screen(); +#endif + + // Seed OpenSSL PRNG with performance counter + RandAddSeed(); + } + ~CInit() + { + // Securely erase the memory used by the PRNG + RAND_cleanup(); + // Shutdown OpenSSL library multithreading support + CRYPTO_set_locking_callback(NULL); + for (int i = 0; i < CRYPTO_num_locks(); i++) + delete ppmutexOpenSSL[i]; + OPENSSL_free(ppmutexOpenSSL); + } +} +instance_of_cinit; + +/** + * LogPrintf() has been broken a couple of times now + * by well-meaning people adding mutexes in the most straightforward way. + * It breaks because it may be called by global destructors during shutdown. + * Since the order of destruction of static/global objects is undefined, + * defining a mutex as a global object doesn't work (the mutex gets + * destroyed, and then some later destructor calls OutputDebugStringF, + * maybe indirectly, and you get a core dump at shutdown trying to lock + * the mutex). + */ + +static boost::once_flag debugPrintInitFlag = BOOST_ONCE_INIT; + +/** + * We use boost::call_once() to make sure mutexDebugLog and + * vMsgsBeforeOpenLog are initialized in a thread-safe manner. + * + * NOTE: fileout, mutexDebugLog and sometimes vMsgsBeforeOpenLog + * are leaked on exit. This is ugly, but will be cleaned up by + * the OS/libc. When the shutdown sequence is fully audited and + * tested, explicit destruction of these objects can be implemented. + */ +static FILE* fileout = NULL; +static boost::mutex* mutexDebugLog = NULL; +static list *vMsgsBeforeOpenLog; + +static FILE* fileoutQ = NULL; +static boost::mutex* mutexDebugLogQ = NULL; +static list *vMsgsBeforeOpenLogQ; + +uint32_t m_timey = 0; +uint8_t m_timem = 0; +uint8_t m_timemin = 0; +string strCurlogFileN = ""; + +static int FileWriteStr(const std::string &str, FILE *fp) +{ + return fwrite(str.data(), 1, str.size(), fp); +} + +static void DebugPrintInit() +{ + assert(mutexDebugLog == NULL); + mutexDebugLog = new boost::mutex(); + vMsgsBeforeOpenLog = new list; + assert(mutexDebugLogQ == NULL); + mutexDebugLogQ = new boost::mutex(); + vMsgsBeforeOpenLogQ = new list; + + time_t tn = time(NULL); + struct tm* now = localtime(&tn); + m_timey = now->tm_year; + m_timem = now->tm_mon; + m_timemin = now->tm_min; + strCurlogFileN = strprintf("%4d%02d", m_timey + 1900, m_timem + 1); + //strCurlogFileN = strprintf("%4d%02d%02d%02d", m_timey + 1900, m_timem + 1, now->tm_mday, now->tm_hour); + strCurlogFileN += "_debug.log"; + boost::filesystem::path topath = GetDataDir() / strDebuglogDir; + + if (!boost::filesystem::exists(topath)) + { + boost::filesystem::create_directory(topath); + } + std::cout << "[DebugPrintInit]strCurlogFileN = " << strCurlogFileN << std::endl; +} + +void OpenDebugLog() +{ + boost::call_once(&DebugPrintInit, debugPrintInitFlag); + boost::mutex::scoped_lock scoped_lock(*mutexDebugLog); + + assert(fileout == NULL); + assert(vMsgsBeforeOpenLog); + // boost::filesystem::path pathDebug = GetDataDir() / "debug.log"; + boost::filesystem::path pathDebug = GetDataDir() / strDebuglogDir / strCurlogFileN; + fileout = fopen(pathDebug.string().c_str(), "a"); + if (fileout) { + setbuf(fileout, NULL); // unbuffered + // dump buffered messages from before we opened the log + while (!vMsgsBeforeOpenLog->empty()) { + FileWriteStr(vMsgsBeforeOpenLog->front(), fileout); + vMsgsBeforeOpenLog->pop_front(); + } + } + + delete vMsgsBeforeOpenLog; + vMsgsBeforeOpenLog = NULL; + + boost::mutex::scoped_lock scoped_lockQ(*mutexDebugLogQ); + + assert(fileoutQ == NULL); + assert(vMsgsBeforeOpenLogQ); + boost::filesystem::path pathDebugQ = GetDataDir() / "Question.log"; + fileoutQ = fopen(pathDebugQ.string().c_str(), "a"); + if (fileoutQ) { + setbuf(fileoutQ, NULL); // unbuffered + // dump buffered messages from before we opened the log + while (!vMsgsBeforeOpenLogQ->empty()) { + FileWriteStr(vMsgsBeforeOpenLogQ->front(), fileoutQ); + vMsgsBeforeOpenLogQ->pop_front(); + } + } + delete vMsgsBeforeOpenLogQ; + vMsgsBeforeOpenLogQ = NULL; +} + +bool LogAcceptCategory(const char* category) +{ + if (category != NULL) + { + if (!fDebug) + return false; + + // Give each thread quick access to -debug settings. + // This helps prevent issues debugging global destructors, + // where mapMultiArgs might be deleted before another + // global destructor calls LogPrint() + static boost::thread_specific_ptr > ptrCategory; + if (ptrCategory.get() == NULL) + { + if (mapMultiArgs.count("-debug")) { + const vector& categories = mapMultiArgs.at("-debug"); + ptrCategory.reset(new set(categories.begin(), categories.end())); + // thread_specific_ptr automatically deletes the set when the thread ends. + } else + ptrCategory.reset(new set()); + } + const set& setCategories = *ptrCategory.get(); + + // if not debugging everything and not debugging specific category, LogPrint does nothing. + if (setCategories.count(string("")) == 0 && + setCategories.count(string("1")) == 0 && + setCategories.count(string(category)) == 0) + return false; + } + return true; +} + +/** + * fStartedNewLine is a state variable held by the calling context that will + * suppress printing of the timestamp when multiple calls are made that don't + * end in a newline. Initialize it to true, and hold it, in the calling context. + */ +static std::string LogTimestampStr(const std::string &str, std::atomic_bool *fStartedNewLine) +{ + string strStamped; + + if (!fLogTimestamps) + return str; + + if (*fStartedNewLine) { + int64_t nTimeMicros = GetLogTimeMicros(); + strStamped = DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nTimeMicros/1000000); + if (fLogTimeMicros) + strStamped += strprintf(".%06d", nTimeMicros%1000000); + + struct timeval curtime; + gettimeofday(&curtime, NULL); + strStamped += strprintf(" %010d %06d", curtime.tv_sec, curtime.tv_usec); + + strStamped += ' ' + str; + } else + strStamped = str; + + if (!str.empty() && str[str.size()-1] == '\n') + *fStartedNewLine = true; + else + *fStartedNewLine = false; + + return strStamped; +} + +int LogPrintStrForOnly(const std::string &str) +{ + int ret = 0; // Returns total number of characters written + static std::atomic_bool fStartedNewLine(true); + + string strTimestamped = LogTimestampStr(str, &fStartedNewLine); + +// if (fPrintToConsole) +// { +// // print to console +// ret = fwrite(strTimestamped.data(), 1, strTimestamped.size(), stdout); +// fflush(stdout); +// } +// else if (fPrintToDebugLog) + { + boost::call_once(&DebugPrintInit, debugPrintInitFlag); + boost::mutex::scoped_lock scoped_lockQ(*mutexDebugLogQ); + + // buffer if we haven't opened the log yet + if (fileoutQ == NULL) { + assert(vMsgsBeforeOpenLogQ); + ret = strTimestamped.length(); + vMsgsBeforeOpenLogQ->push_back(strTimestamped); + } + else + { + // reopen the log file, if requested + if (fReopenDebugLogQ) { + fReopenDebugLogQ = false; + boost::filesystem::path pathDebug = GetDataDir() / "Question.log"; + if (freopen(pathDebug.string().c_str(), "a", fileoutQ) != NULL) + setbuf(fileoutQ, NULL); // unbuffered + } + + ret = FileWriteStr(strTimestamped, fileoutQ); + + } + } + return ret; +} + +int LogPrintStr(const std::string &str) +{ + int ret = 0; // Returns total number of characters written + static std::atomic_bool fStartedNewLine(true); + + string strTimestamped = LogTimestampStr(str, &fStartedNewLine); + + time_t tn = time(NULL); + struct tm* now = localtime(&tn); + if (m_timey != now->tm_year || m_timem != now->tm_mon ) + { + m_timey = now->tm_year; + m_timem = now->tm_mon; + if (fileout) + { + strCurlogFileN = strprintf("%4d%02d", m_timey + 1900, m_timem + 1); + strCurlogFileN += "_debug.log"; + boost::filesystem::path topath = GetDataDir() / strDebuglogDir; + + if (!boost::filesystem::exists(topath)) + { + boost::filesystem::create_directory(topath); + } + topath = GetDataDir() / strDebuglogDir / strCurlogFileN; + if (freopen(topath.string().c_str(), "a", fileout) != NULL) + setbuf(fileout, NULL); // unbuffered + + } + } + + if (fPrintToConsole) + { + // print to console + ret = fwrite(strTimestamped.data(), 1, strTimestamped.size(), stdout); + fflush(stdout); + } + else if (fPrintToDebugLog) + { + boost::call_once(&DebugPrintInit, debugPrintInitFlag); + boost::mutex::scoped_lock scoped_lock(*mutexDebugLog); + + // buffer if we haven't opened the log yet + if (fileout == NULL) { + assert(vMsgsBeforeOpenLog); + ret = strTimestamped.length(); + vMsgsBeforeOpenLog->push_back(strTimestamped); + } + else + { + // reopen the log file, if requested + if (fReopenDebugLog) { + fReopenDebugLog = false; + // boost::filesystem::path pathDebug = GetDataDir() / "debug.log"; + boost::filesystem::path pathDebug = GetDataDir() / strDebuglogDir / strCurlogFileN; + if (freopen(pathDebug.string().c_str(),"a",fileout) != NULL) + setbuf(fileout, NULL); // unbuffered + } + + ret = FileWriteStr(strTimestamped, fileout); + + } + } + return ret; +} + +/** Interpret string as boolean, for argument parsing */ +static bool InterpretBool(const std::string& strValue) +{ + if (strValue.empty()) + return true; + return (atoi(strValue) != 0); +} + +/** Turn -noX into -X=0 */ +static void InterpretNegativeSetting(std::string& strKey, std::string& strValue) +{ + if (strKey.length()>3 && strKey[0]=='-' && strKey[1]=='n' && strKey[2]=='o') + { + strKey = "-" + strKey.substr(3); + strValue = InterpretBool(strValue) ? "0" : "1"; + } +} + +void ParseParameters(int argc, const char* const argv[]) +{ + LOCK(cs_args); + mapArgs.clear(); + _mapMultiArgs.clear(); + + for (int i = 1; i < argc; i++) + { + std::string str(argv[i]); + std::string strValue; + size_t is_index = str.find('='); + if (is_index != std::string::npos) + { + strValue = str.substr(is_index+1); + str = str.substr(0, is_index); + } +#ifdef WIN32 + boost::to_lower(str); + if (boost::algorithm::starts_with(str, "/")) + str = "-" + str.substr(1); +#endif + + if (str[0] != '-') + break; + + // Interpret --foo as -foo. + // If both --foo and -foo are set, the last takes effect. + if (str.length() > 1 && str[1] == '-') + str = str.substr(1); + InterpretNegativeSetting(str, strValue); + + mapArgs[str] = strValue; + _mapMultiArgs[str].push_back(strValue); + } +} + +bool IsArgSet(const std::string& strArg) +{ + LOCK(cs_args); + return mapArgs.count(strArg); +} + +std::string GetArg(const std::string& strArg, const std::string& strDefault) +{ + LOCK(cs_args); + if (mapArgs.count(strArg)) + return mapArgs[strArg]; + return strDefault; +} + +int64_t GetArg(const std::string& strArg, int64_t nDefault) +{ + LOCK(cs_args); + if (mapArgs.count(strArg)) + return atoi64(mapArgs[strArg]); + return nDefault; +} + +bool GetBoolArg(const std::string& strArg, bool fDefault) +{ + LOCK(cs_args); + if (mapArgs.count(strArg)) + return InterpretBool(mapArgs[strArg]); + return fDefault; +} + +bool SoftSetArg(const std::string& strArg, const std::string& strValue) +{ + LOCK(cs_args); + if (mapArgs.count(strArg)) + return false; + mapArgs[strArg] = strValue; + return true; +} + +bool SoftSetBoolArg(const std::string& strArg, bool fValue) +{ + if (fValue) + return SoftSetArg(strArg, std::string("1")); + else + return SoftSetArg(strArg, std::string("0")); +} + +void ForceSetArg(const std::string& strArg, const std::string& strValue) +{ + LOCK(cs_args); + mapArgs[strArg] = strValue; +} + + + +static const int screenWidth = 79; +static const int optIndent = 2; +static const int msgIndent = 7; + +std::string HelpMessageGroup(const std::string &message) { + return std::string(message) + std::string("\n\n"); +} + +std::string HelpMessageOpt(const std::string &option, const std::string &message) { + return std::string(optIndent,' ') + std::string(option) + + std::string("\n") + std::string(msgIndent,' ') + + FormatParagraph(message, screenWidth - msgIndent, msgIndent) + + std::string("\n\n"); +} + +static std::string FormatException(const std::exception* pex, const char* pszThread) +{ +#ifdef WIN32 + char pszModule[MAX_PATH] = ""; + GetModuleFileNameA(NULL, pszModule, sizeof(pszModule)); +#else + const char* pszModule = "bitcoin"; +#endif + if (pex) + return strprintf( + "EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread); + else + return strprintf( + "UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread); +} + +void PrintExceptionContinue(const std::exception* pex, const char* pszThread) +{ + std::string message = FormatException(pex, pszThread); + LogPrintf("\n\n************************\n%s\n", message); + fprintf(stderr, "\n\n************************\n%s\n", message.c_str()); +} + +boost::filesystem::path GetDefaultDataDir() +{ + namespace fs = boost::filesystem; + // Windows < Vista: C:\Documents and Settings\Username\Application Data\Bitcoin + // Windows >= Vista: C:\Users\Username\AppData\Roaming\Bitcoin + // Mac: ~/Library/Application Support/Bitcoin + // Unix: ~/.bitcoin +#ifdef WIN32 + // Windows + return GetSpecialFolderPath(CSIDL_APPDATA) / "IPChain"; +#else + fs::path pathRet; + char* pszHome = getenv("HOME"); + if (pszHome == NULL || strlen(pszHome) == 0) + pathRet = fs::path("/"); + else + pathRet = fs::path(pszHome); +#ifdef MAC_OSX + // Mac + return pathRet / "Library/Application Support/IPChain"; +#else + // Unix + return pathRet / ".IPChain"; +#endif +#endif +} + +static boost::filesystem::path pathCached; +static boost::filesystem::path pathCachedNetSpecific; +static CCriticalSection csPathCached; + +const boost::filesystem::path &GetDataDir(bool fNetSpecific) +{ + namespace fs = boost::filesystem; + + LOCK(csPathCached); + + fs::path &path = fNetSpecific ? pathCachedNetSpecific : pathCached; + + // This can be called during exceptions by LogPrintf(), so we cache the + // value so we don't have to do memory allocations after that. + if (!path.empty()) + return path; + + if (IsArgSet("-datadir")) { + path = fs::system_complete(GetArg("-datadir", "")); + if (!fs::is_directory(path)) { + path = ""; + return path; + } + } else { + path = GetDefaultDataDir(); + } + if (fNetSpecific) + path /= BaseParams().DataDir(); + + fs::create_directories(path); + + return path; +} + +void ClearDatadirCache() +{ + LOCK(csPathCached); + + pathCached = boost::filesystem::path(); + pathCachedNetSpecific = boost::filesystem::path(); +} + +boost::filesystem::path GetConfigFile(const std::string& confPath) +{ + boost::filesystem::path pathConfigFile(confPath); + if (!pathConfigFile.is_complete()) + pathConfigFile = GetDataDir(false) / pathConfigFile; + + return pathConfigFile; +} + +void ReadConfigFile(const std::string& confPath) +{ + boost::filesystem::ifstream streamConfig(GetConfigFile(confPath)); + if (!streamConfig.good()) + return; // No ipchain.conf file is OK + + { + LOCK(cs_args); + set setOptions; + setOptions.insert("*"); + + for (boost::program_options::detail::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it) + { + // Don't overwrite existing settings so command line settings override ipchain.conf + string strKey = string("-") + it->string_key; + string strValue = it->value[0]; + InterpretNegativeSetting(strKey, strValue); + if (mapArgs.count(strKey) == 0) + mapArgs[strKey] = strValue; + _mapMultiArgs[strKey].push_back(strValue); + } + } + // If datadir is changed in .conf file: + ClearDatadirCache(); +} + +#ifndef WIN32 +boost::filesystem::path GetPidFile() +{ + boost::filesystem::path pathPidFile(GetArg("-pid", BITCOIN_PID_FILENAME)); + if (!pathPidFile.is_complete()) pathPidFile = GetDataDir() / pathPidFile; + return pathPidFile; +} + +void CreatePidFile(const boost::filesystem::path &path, pid_t pid) +{ + FILE* file = fopen(path.string().c_str(), "w"); + if (file) + { + fprintf(file, "%d\n", pid); + fclose(file); + } +} +#endif + +bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest) +{ +#ifdef WIN32 + return MoveFileExA(src.string().c_str(), dest.string().c_str(), + MOVEFILE_REPLACE_EXISTING) != 0; +#else + int rc = std::rename(src.string().c_str(), dest.string().c_str()); + return (rc == 0); +#endif /* WIN32 */ +} + +/** + * Ignores exceptions thrown by Boost's create_directory if the requested directory exists. + * Specifically handles case where path p exists, but it wasn't possible for the user to + * write to the parent directory. + */ +bool TryCreateDirectory(const boost::filesystem::path& p) +{ + try + { + return boost::filesystem::create_directory(p); + } catch (const boost::filesystem::filesystem_error&) { + if (!boost::filesystem::exists(p) || !boost::filesystem::is_directory(p)) + throw; + } + + // create_directory didn't create the directory, it had to have existed already + return false; +} + +void FileCommit(FILE *file) +{ + fflush(file); // harmless if redundantly called +#ifdef WIN32 + HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file)); + FlushFileBuffers(hFile); +#else + #if defined(__linux__) || defined(__NetBSD__) + fdatasync(fileno(file)); + #elif defined(__APPLE__) && defined(F_FULLFSYNC) + fcntl(fileno(file), F_FULLFSYNC, 0); + #else + fsync(fileno(file)); + #endif +#endif +} + +bool TruncateFile(FILE *file, unsigned int length) { +#if defined(WIN32) + return _chsize(_fileno(file), length) == 0; +#else + return ftruncate(fileno(file), length) == 0; +#endif +} + +/** + * this function tries to raise the file descriptor limit to the requested number. + * It returns the actual file descriptor limit (which may be more or less than nMinFD) + */ +int RaiseFileDescriptorLimit(int nMinFD) { +#if defined(WIN32) + return 2048; +#else + struct rlimit limitFD; + if (getrlimit(RLIMIT_NOFILE, &limitFD) != -1) { + if (limitFD.rlim_cur < (rlim_t)nMinFD) { + limitFD.rlim_cur = nMinFD; + if (limitFD.rlim_cur > limitFD.rlim_max) + limitFD.rlim_cur = limitFD.rlim_max; + setrlimit(RLIMIT_NOFILE, &limitFD); + getrlimit(RLIMIT_NOFILE, &limitFD); + } + return limitFD.rlim_cur; + } + return nMinFD; // getrlimit failed, assume it's fine +#endif +} + +/** + * this function tries to make a particular range of a file allocated (corresponding to disk space) + * it is advisory, and the range specified in the arguments will never contain live data + */ +void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length) { +#if defined(WIN32) + // Windows-specific version + HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file)); + LARGE_INTEGER nFileSize; + int64_t nEndPos = (int64_t)offset + length; + nFileSize.u.LowPart = nEndPos & 0xFFFFFFFF; + nFileSize.u.HighPart = nEndPos >> 32; + SetFilePointerEx(hFile, nFileSize, 0, FILE_BEGIN); + SetEndOfFile(hFile); +#elif defined(MAC_OSX) + // OSX specific version + fstore_t fst; + fst.fst_flags = F_ALLOCATECONTIG; + fst.fst_posmode = F_PEOFPOSMODE; + fst.fst_offset = 0; + fst.fst_length = (off_t)offset + length; + fst.fst_bytesalloc = 0; + if (fcntl(fileno(file), F_PREALLOCATE, &fst) == -1) { + fst.fst_flags = F_ALLOCATEALL; + fcntl(fileno(file), F_PREALLOCATE, &fst); + } + ftruncate(fileno(file), fst.fst_length); +#elif defined(__linux__) + // Version using posix_fallocate + off_t nEndPos = (off_t)offset + length; + posix_fallocate(fileno(file), 0, nEndPos); +#else + // Fallback version + // TODO: just write one byte per block + static const char buf[65536] = {}; + fseek(file, offset, SEEK_SET); + while (length > 0) { + unsigned int now = 65536; + if (length < now) + now = length; + fwrite(buf, 1, now, file); // allowed to fail; this function is advisory anyway + length -= now; + } +#endif +} + +void ShrinkDebugFile() +{ + // Amount of debug.log to save at end when shrinking (must fit in memory) + constexpr size_t RECENT_DEBUG_HISTORY_SIZE = 10 * 1000000; + // Scroll debug.log if it's getting too big + boost::filesystem::path pathLog = GetDataDir() / "debug.log"; + FILE* file = fopen(pathLog.string().c_str(), "r"); + // If debug.log file is more than 10% bigger the RECENT_DEBUG_HISTORY_SIZE + // trim it down by saving only the last RECENT_DEBUG_HISTORY_SIZE bytes + if (file && boost::filesystem::file_size(pathLog) > 11 * (RECENT_DEBUG_HISTORY_SIZE / 10)) + { + // Restart the file with some of the end + std::vector vch(RECENT_DEBUG_HISTORY_SIZE, 0); + fseek(file, -((long)vch.size()), SEEK_END); + int nBytes = fread(vch.data(), 1, vch.size(), file); + fclose(file); + + file = fopen(pathLog.string().c_str(), "w"); + if (file) + { + fwrite(vch.data(), 1, nBytes, file); + fclose(file); + } + } + else if (file != NULL) + fclose(file); +} + +#ifdef WIN32 +boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate) +{ + namespace fs = boost::filesystem; + + char pszPath[MAX_PATH] = ""; + + if(SHGetSpecialFolderPathA(NULL, pszPath, nFolder, fCreate)) + { + return fs::path(pszPath); + } + + LogPrintf("SHGetSpecialFolderPathA() failed, could not obtain requested path.\n"); + return fs::path(""); +} +#endif + +void runCommand(const std::string& strCommand) +{ + int nErr = ::system(strCommand.c_str()); + if (nErr) + LogPrintf("runCommand error: system(%s) returned %d\n", strCommand, nErr); +} + +void RenameThread(const char* name) +{ +#if defined(PR_SET_NAME) + // Only the first 15 characters are used (16 - NUL terminator) + ::prctl(PR_SET_NAME, name, 0, 0, 0); +#elif (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)) + pthread_set_name_np(pthread_self(), name); + +#elif defined(MAC_OSX) + pthread_setname_np(name); +#else + // Prevent warnings for unused parameters... + (void)name; +#endif +} + +void SetupEnvironment() +{ +#ifdef HAVE_MALLOPT_ARENA_MAX + // glibc-specific: On 32-bit systems set the number of arenas to 1. + // By default, since glibc 2.10, the C library will create up to two heap + // arenas per core. This is known to cause excessive virtual address space + // usage in our usage. Work around it by setting the maximum number of + // arenas to 1. + if (sizeof(void*) == 4) { + mallopt(M_ARENA_MAX, 1); + } +#endif + // On most POSIX systems (e.g. Linux, but not BSD) the environment's locale + // may be invalid, in which case the "C" locale is used as fallback. +#if !defined(WIN32) && !defined(MAC_OSX) && !defined(__FreeBSD__) && !defined(__OpenBSD__) + try { + std::locale(""); // Raises a runtime error if current locale is invalid + } catch (const std::runtime_error&) { + setenv("LC_ALL", "C", 1); + } +#endif + // The path locale is lazy initialized and to avoid deinitialization errors + // in multithreading environments, it is set explicitly by the main thread. + // A dummy locale is used to extract the internal default locale, used by + // boost::filesystem::path, which is then used to explicitly imbue the path. + std::locale loc = boost::filesystem::path::imbue(std::locale::classic()); + boost::filesystem::path::imbue(loc); +} + +bool SetupNetworking() +{ +#ifdef WIN32 + // Initialize Windows Sockets + WSADATA wsadata; + int ret = WSAStartup(MAKEWORD(2,2), &wsadata); + if (ret != NO_ERROR || LOBYTE(wsadata.wVersion ) != 2 || HIBYTE(wsadata.wVersion) != 2) + return false; +#endif + return true; +} + +int GetNumCores() +{ +#if BOOST_VERSION >= 105600 + return boost::thread::physical_concurrency(); +#else // Must fall back to hardware_concurrency, which unfortunately counts virtual cores + return boost::thread::hardware_concurrency(); +#endif +} + +std::string CopyrightHolders(const std::string& strPrefix) +{ + std::string strCopyrightHolders = strPrefix + strprintf(_(COPYRIGHT_HOLDERS), _(COPYRIGHT_HOLDERS_SUBSTITUTION)); + + // Check for untranslated substitution to make sure Bitcoin Core copyright is not removed by accident + if (strprintf(COPYRIGHT_HOLDERS, COPYRIGHT_HOLDERS_SUBSTITUTION).find("Bitcoin Core") == std::string::npos) { + strCopyrightHolders += "\n" + strPrefix + "The Bitcoin Core developers"; + } + return strCopyrightHolders; +} + diff --git a/.svn/pristine/22/22c8a083e531f4eee04d64de0adb6e311f84cfea.svn-base b/.svn/pristine/22/22c8a083e531f4eee04d64de0adb6e311f84cfea.svn-base new file mode 100644 index 0000000..a6ad929 --- /dev/null +++ b/.svn/pristine/22/22c8a083e531f4eee04d64de0adb6e311f84cfea.svn-base @@ -0,0 +1,471 @@ + + + unionaccountcreate + + + + 0 + 0 + 964 + 772 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 962 + 655 + + + + + + + + 0 + 103 + + + + + 16777215 + 103 + + + + font-size : 28px; +color: rgb(51, 51, 51); + + + CreateUnionAccount + + + + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + name + + + + + + + 8 + + + name + + + + + + + + + + Qt::Horizontal + + + + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + num + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + ConNum + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + achieve a confirmed number , transactions will send successfully + + + + + + + + + + Qt::Horizontal + + + + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + + 0 + 0 + + + + MyKey + + + + + + + MyKey + + + + + + + + 100 + 30 + + + + + 100 + 30 + + + + background-image: url(:/icons/res/png/ioport.png);border:none + + + genkey + + + + + + + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + otherkey1 + + + + + + + otherkey1 + + + + + + + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + otherkey2 + + + + + + + otherkey2 + + + + + + + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + otherkey3 + + + + + + + otherkey3 + + + + + + + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + otherkey4 + + + + + + + otherkey4 + + + + + + + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 334 + 20 + + + + + + + + + 421 + 50 + + + + + 421 + 50 + + + + background-image: url(:/res/png/buttons/421_50.png);border:none;color: rgb(255,255,255); + + + create + + + + + + + Qt::Horizontal + + + + 333 + 20 + + + + + + + + + + + + diff --git a/.svn/pristine/23/2313013a825a0898a5cc6e16a619c5e7b952ad6d.svn-base b/.svn/pristine/23/2313013a825a0898a5cc6e16a619c5e7b952ad6d.svn-base new file mode 100644 index 0000000..b04587b --- /dev/null +++ b/.svn/pristine/23/2313013a825a0898a5cc6e16a619c5e7b952ad6d.svn-base @@ -0,0 +1,606 @@ + + + ipcconfirmauthorizationtransaction + + + + 0 + 0 + 674 + 636 + + + + + 0 + 0 + + + + Form + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + background-image: url(:/res/png/back.png);border:none + + + + + + + + + + + + + 0 + 40 + + + + + 16777215 + 40 + + + + + -1 + + + + color: rgb(51, 51, 51);font-size : 28px; + + + Authorization confirmation + + + + + + + Qt::Horizontal + + + + 298 + 17 + + + + + + + + + + + 9 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 0 + 80 + + + + + + + + 100 + 80 + + + + + 100 + 16777215 + + + + IPCName + + + + + + + + 0 + 0 + + + + + 0 + 80 + + + + + 16777215 + 16777215 + + + + font-size : 14px; +color: rgb(51, 51, 51); + + + TextLabel + + + true + + + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + IPCAddress + + + + + + + font-size : 14px; +color: rgb(51, 51, 51); + + + TextLabel + + + + + + + Qt::Horizontal + + + + 528 + 20 + + + + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + AuthType + + + + + + + font-size : 14px; +color: rgb(51, 51, 51); + + + TextLabel + + + + + + + Qt::Horizontal + + + + 528 + 20 + + + + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + AuthTo + + + + + + + font-size : 14px; +color: rgb(51, 51, 51); + + + TextLabel + + + + + + + Qt::Horizontal + + + + 528 + 20 + + + + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + IPCTime + + + + + + + font-size : 14px; +color: rgb(51, 51, 51); + + + TextLabel + + + + + + + Qt::Horizontal + + + + 528 + 20 + + + + + + + + + + + Qt::Horizontal + + + + + + + + + + Qt::Horizontal + + + + + + + + 16777215 + 30 + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + + + + + + + + Qt::Horizontal + + + + 453 + 20 + + + + + + + + + + + + 0 + 70 + + + + + 16777215 + 70 + + + + + + + Qt::Horizontal + + + + 285 + 20 + + + + + + + + + 421 + 50 + + + + + 421 + 50 + + + + border:none; +color: rgb(255, 255, 255); +background-image: url(:/res/png/buttons/421_50.png); + + + confirm transaction + + + + + + + Qt::Horizontal + + + + 285 + 20 + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/.svn/pristine/23/233365f8f4323b4381ebc6380275b85e3c0bc1ed.svn-base b/.svn/pristine/23/233365f8f4323b4381ebc6380275b85e3c0bc1ed.svn-base new file mode 100644 index 0000000..e4fbaf8 --- /dev/null +++ b/.svn/pristine/23/233365f8f4323b4381ebc6380275b85e3c0bc1ed.svn-base @@ -0,0 +1,718 @@ + + + sendhistory + + + + 0 + 0 + 807 + 630 + + + + Form + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + QFrame::NoFrame + + + 0 + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 807 + 630 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + + 0 + 191 + + + + + 16777215 + 191 + + + + border:none + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 30 + + + + + + + + + + 41 + 41 + + + + + 41 + 41 + + + + background-image: url(:/res/png/sendico.png); + + + + + + + + + + + 0 + 0 + + + + + 0 + 76 + + + + + 16777215 + 76 + + + + + + + IsSend + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 0 + 82 + + + + + 16777215 + 82 + + + + + + + + 13 + + + + background-color: rgb(242, 241, 240); + + + true + + + + + + + + + + + + + + + + 0 + 3 + + + + + 16777215 + 3 + + + + Qt::Horizontal + + + + + + + + 0 + 103 + + + + + 16777215 + 103 + + + + border:none + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 30 + + + 0 + + + 15 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 29 + 29 + + + + + 29 + 29 + + + + background-image: url(:/res/png/smalllogo.png); + + + + + + + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAsNeeded + + + true + + + + + 0 + 0 + 731 + 86 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + Qt::TextSelectableByMouse + + + + + + + + + + + + + + + + + SenderAdd + + + + + + + + + + + 0 + 3 + + + + + 16777215 + 3 + + + + Qt::Horizontal + + + + + + + + 0 + 61 + + + + + 16777215 + 61 + + + + border:none + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 30 + + + + + + + + + + date + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Qt::RightToLeft + + + + + + TextLabel + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + 0 + 3 + + + + + 16777215 + 3 + + + + Qt::Horizontal + + + + + + + + 0 + 61 + + + + + 16777215 + 61 + + + + border:none + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 30 + + + + + + + + + + + + + PayFee + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + TextLabel + + + + + + + + + + + + + 0 + 3 + + + + + 16777215 + 3 + + + + Qt::Horizontal + + + + + + + + 0 + 61 + + + + + 16777215 + 61 + + + + border:none + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 30 + + + + + + + + + + + + + payinfo + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + TextLabel + + + + + + + + + + + + + 0 + 3 + + + + Qt::Horizontal + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + diff --git a/.svn/pristine/27/271044d6be167ecab2335866830634b71b16fa68.svn-base b/.svn/pristine/27/271044d6be167ecab2335866830634b71b16fa68.svn-base new file mode 100644 index 0000000..f8125e9 --- /dev/null +++ b/.svn/pristine/27/271044d6be167ecab2335866830634b71b16fa68.svn-base @@ -0,0 +1,40 @@ +#ifndef EXPORTDIALOG_H +#define EXPORTDIALOG_H + +#include + +namespace Ui { +class exportdialog; +} +class WalletModel; +class exportdialog : public QWidget +{ + Q_OBJECT + +public: + explicit exportdialog(QWidget *parent = 0); + ~exportdialog(); + WalletModel *walletModel; + void setWalletModel(WalletModel * model){walletModel = model;} + void clearInfo(); + + QString setDestSourcePath(QString path); +public Q_SLOTS: + void on_pushButton_back_pressed(); +Q_SIGNALS: + void back(); + void confirm(int); +private Q_SLOTS: + void on_pushButton_confirm_pressed(); + void on_pushButton_other_pressed(); + void on_pushButton_browse_pressed(); + +private: + Ui::exportdialog *ui; + bool showother; + void showorhideother(); + QString m_file_full; + QString m_file_path; +}; + +#endif // EXPORTDIALOG_H diff --git a/.svn/pristine/27/27fdf827447df64e57272f750204b2ee72c18bbb.svn-base b/.svn/pristine/27/27fdf827447df64e57272f750204b2ee72c18bbb.svn-base new file mode 100644 index 0000000..2214227 --- /dev/null +++ b/.svn/pristine/27/27fdf827447df64e57272f750204b2ee72c18bbb.svn-base @@ -0,0 +1,153 @@ +// Copyright (c) 2011-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_QT_WALLETFRAME_H +#define BITCOIN_QT_WALLETFRAME_H + +#include +#include + +#include + +#include +#include +#include + +class BitcoinGUI; +class ClientModel; +class PlatformStyle; +class SendCoinsRecipient; +class WalletModel; +class WalletView; + +class Settingwidget; +class SendCoinsAffrimWidget; +class AddressTableModel; +class InfoWidget; +class sendhistory; +class RecvHistory; +class sendipchistory; +class recvipchistory; +class SendTokenHistory; +class RecvTokenHistory; +class SendResultWidget; + +class walletpagebuttons; +class ipcSelectAddress; +QT_BEGIN_NAMESPACE +class QStackedWidget; +QT_END_NAMESPACE + +/** + * A container for embedding all wallet-related + * controls into BitcoinGUI. The purpose of this class is to allow future + * refinements of the wallet controls with minimal need for further + * modifications to BitcoinGUI, thus greatly simplifying merges while + * reducing the risk of breaking top-level stuff. + */ + +class WalletFrame : public QFrame +{ + Q_OBJECT + +public: + + explicit WalletFrame(const PlatformStyle *platformStyle, BitcoinGUI *_gui = 0); + ~WalletFrame(); + + + enum TabTypes { + TAB_sendipc = 1, + TAB_recvipc = 2, + TAB_sendtoken = 5, + TAB_recvtoken = 6, + TAB_send = 7, + TAB_recv = 8 + }; + + QStackedWidget* getwaletstack(); + void setClientModel(ClientModel *clientModel); + + bool addWallet(const QString& name, WalletModel *walletModel); + bool setCurrentWallet(const QString& name); + bool removeWallet(const QString &name); + void removeAllWallets(); + void headshowchaininfo(int concount,int count, bool header); + +Q_SIGNALS: + /** Notify that the user has requested more information about the out-of-sync warning */ + void requestedSyncWarningInfo(); + void requestoverwidget(); + +private: + QTimer *pollTimer =NULL; + QStackedWidget *walletStack; + QStackedWidget *walletStackBranchPage; + QWidget * pwalletStackwidget; + + walletpagebuttons* walletpagebuttonswidget; + + Settingwidget* settingwidgetPage; + + InfoWidget* ChainInfoPage; + + SendCoinsAffrimWidget* SendCoinsAffrimPage; + + sendhistory* sendpage =NULL; + + RecvHistory* recvpage = NULL; + + sendipchistory* sendipcpage= NULL; + + recvipchistory* recvipcpage= NULL; + + SendTokenHistory* sendtokenpage= NULL ; + RecvTokenHistory* recvtokenpage= NULL; + + BitcoinGUI *gui; + ClientModel *clientModel; + WalletModel *walletmd; + ClientModel *clientmd; + QModelIndex sel = QModelIndex(); + int selid; + QMap mapWalletViews; + + bool bOutOfSync; + + const PlatformStyle *platformStyle; + + WalletView *currentWalletView(); + +public Q_SLOTS: + + void StatusInfoUpdate(); + /** Switch to overview (home) page */ + void gotoOverviewPage(); + /** Switch to receive coins page */ + void gotoReceiveCoinsPage(); + /** Switch to send coins page */ + void gotoSendCoinsPage(QString addr = ""); + /** Switch to ipc page */ + void gotoIpcPage(); + /** Switch to set page */ + void gotoSetPage(); + void gotoUnionAccountPage(); + void gotoTallyPage(); + void gotoeCoinPage(); + void showwwDetails(QModelIndex index,quint8 t); + void GoToChainInfoPage(); + + /** Encrypt the wallet */ + void encryptWallet(bool status); + /** Backup the wallet */ + void backupWallet(); + + /** Ask for passphrase to unlock wallet temporarily */ + void unlockWallet(); + + /** Pass on signal over requested out-of-sync-warning information */ + void outOfSyncWarningClicked(); +}; + +#endif // BITCOIN_QT_WALLETFRAME_H diff --git a/.svn/pristine/28/280af82fe3cca449a8656c5784e34a1e51180b8f.svn-base b/.svn/pristine/28/280af82fe3cca449a8656c5784e34a1e51180b8f.svn-base new file mode 100644 index 0000000..bb13fac --- /dev/null +++ b/.svn/pristine/28/280af82fe3cca449a8656c5784e34a1e51180b8f.svn-base @@ -0,0 +1,66 @@ +#ifndef SETDIALOG_H +#define SETDIALOG_H + +#include +#include "walletmodel.h" +#include +#include +class exportdialog; +class SetRecovery; +class SetMessageAuthenticationTab; +class SetMessageSignature; +class SuccessfulTrade; +class PasswordSettingWidget; +class AddBookWidget; +namespace Ui { +class setdialog; +} + +class setdialog : public QWidget +{ + Q_OBJECT + +public: + explicit setdialog(QWidget *parent = 0); + ~setdialog(); + + void setModel(WalletModel *_model); + void setPsdSetSuccess(); + void setPsdshow(PasswordSettingWidget *PasswordSettingPage); + void setAddpageshow(AddBookWidget *Addbookpage); + void setButtonPic(QPushButton*); + void gotoSetMessageAuthenticationTabPage(); + void gotoSetMessageSignaturePage(); +public Q_SLOTS: + void on_pushButton_export_pressed(); + void on_pushButton_recovery_pressed(); + void on_pushButton_msgauthentication_pressed(); + void on_pushButton_addressbook_pressed(); + void on_pushButton_setpwd_pressed(); + void gotoExportPageSlot(); + void gotoSetRecoveryPageSlot(); + void gotoMessageAuthenticationPageSlot(); + void gotoSuccessfulTradePageSlot(int type); + void on_pushButton_aboutwallet_pressed(); + void on_pushButton_verification_pressed(); + +Q_SIGNALS: + void openexportdialog(); + void gotoSetRecoveryPage(); + void gotoMessageAuthenticationPage(); + void openAddBookPagewidget(int tag); + void openPasswordSetwidget(int tag); + +private: + Ui::setdialog *ui; + WalletModel *model; + exportdialog* exportdialogPage; + SetRecovery* SetRecoveryPage; + QStackedWidget *walletStackBranchPage; + SuccessfulTrade* SuccessfulTradePage; + SetMessageAuthenticationTab *SetMessageAuthenticationTabPage; + SetMessageSignature *SetMessageSignaturePage; + +}; + +#endif // SETDIALOG_H diff --git a/.svn/pristine/28/28562672cc8ffd81735c781fc351ca08b1228981.svn-base b/.svn/pristine/28/28562672cc8ffd81735c781fc351ca08b1228981.svn-base new file mode 100644 index 0000000..4f09a17 --- /dev/null +++ b/.svn/pristine/28/28562672cc8ffd81735c781fc351ca08b1228981.svn-base @@ -0,0 +1,343 @@ + + + unionacounthistorydetail + + + + 0 + 0 + 900 + 733 + + + + Form + + + + + + + 0 + + + + + + 21 + 21 + + + + + 21 + 21 + + + + background-image: url(:/res/png/back.png);border:none + + + + + + + + + + Qt::Horizontal + + + + 731 + 20 + + + + + + + + + + + + + + + 41 + 41 + + + + + 41 + 41 + + + + background-image: url(:/res/png/sendico.png); + + + + + + + + + + IsSend + + + + + + + Qt::Horizontal + + + + 679 + 20 + + + + + + + + + + + + 0 + 100 + + + + + 15678887 + 100 + + + + + + + + 0 + 83 + + + + + 16777215 + 83 + + + + + Ubuntu + 17 + 50 + false + false + + + + font-size : 14px;background-color: rgb(242, 241, 240);border:none; +font: 17pt "Ubuntu"; + + + + + + + true + + + + + + + + + + Qt::Horizontal + + + + + + + + + + address + + + + + + + Qt::Horizontal + + + + 679 + 20 + + + + + + + + TextLabel + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + + + + Qt::Horizontal + + + + + + + + + + date + + + + + + + Qt::Horizontal + + + + 679 + 20 + + + + + + + + TextLabel + + + + + + + + + + Qt::Horizontal + + + + + + + + + + fee + + + + + + + Qt::Horizontal + + + + 679 + 20 + + + + + + + + TextLabel + + + + + + + + + + Qt::Horizontal + + + + + + + + + + info + + + + + + + Qt::Horizontal + + + + 726 + 20 + + + + + + + + TextLabel + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/.svn/pristine/2a/2a55673f78fcd2056316e688d7894c482ec76dff.svn-base b/.svn/pristine/2a/2a55673f78fcd2056316e688d7894c482ec76dff.svn-base new file mode 100644 index 0000000..7d1fd5a Binary files /dev/null and b/.svn/pristine/2a/2a55673f78fcd2056316e688d7894c482ec76dff.svn-base differ diff --git a/.svn/pristine/2b/2b88895a7494bf140df36bab4828b51bebf74e73.svn-base b/.svn/pristine/2b/2b88895a7494bf140df36bab4828b51bebf74e73.svn-base new file mode 100644 index 0000000..f8d0b66 --- /dev/null +++ b/.svn/pristine/2b/2b88895a7494bf140df36bab4828b51bebf74e73.svn-base @@ -0,0 +1,40 @@ +#ifndef UNIONACCOUNTGENKEY_H +#define UNIONACCOUNTGENKEY_H + +#include +#include "wallet/wallet.h" +class WalletModel; +namespace Ui { +class unionaccountgenkey; +} + +class unionaccountgenkey : public QWidget +{ + Q_OBJECT + +public: + explicit unionaccountgenkey(QWidget *parent = 0); + ~unionaccountgenkey(); + void setModel(WalletModel *_model); + + void setaddress(QString address); + + void clearinfo(); + void clearData(); + void showEvent(QShowEvent *event); + +Q_SIGNALS: + void opensuccessgenkeyPage(); + void selectaddress(); +private Q_SLOTS: + void on_genkey_pressed(); + + void on_selectadd_btn_pressed(); + +private: + Ui::unionaccountgenkey *ui; + WalletModel *model; + QString m_address; +}; + +#endif // UNIONACCOUNTGENKEY_H diff --git a/.svn/pristine/2d/2d82ca52db1392ed2619fa981cc044243a0aaa5b.svn-base b/.svn/pristine/2d/2d82ca52db1392ed2619fa981cc044243a0aaa5b.svn-base new file mode 100644 index 0000000..ee47d69 --- /dev/null +++ b/.svn/pristine/2d/2d82ca52db1392ed2619fa981cc044243a0aaa5b.svn-base @@ -0,0 +1,140 @@ +#include "setrecovery.h" +#include "ui_setrecovery.h" +#include +#include +#include "walletmodel.h" +#include "log/log.h" +#include "intro.h" +#include +QString g_CreateWalletFromPath; +SetRecovery::SetRecovery(QWidget *parent) : + QWidget(parent), + ui(new Ui::SetRecovery),walletModel(NULL) +{ + ui->setupUi(this); + ui->lineEdit_pwd->hide(); + ui->label_pwd->hide(); + ui->frame->hide(); + ui->label_error->setText(tr("")); +} + +SetRecovery::~SetRecovery() +{ + delete ui; +} + +void SetRecovery::on_pushButton_back_pressed() +{ + Q_EMIT back(); +} + +void SetRecovery::on_pushButton_select_pressed() +{ + ui->label_error->setText(tr("")); + + + QString file_full, file_name, file_path; + QFileInfo fi; + file_full = QFileDialog::getOpenFileName(this); + if(file_full == "") + { + return; + } + fi = QFileInfo(file_full); + file_name = fi.fileName(); + file_path = fi.absolutePath(); + m_file_path = file_path; + m_file_full = file_full; + ui->label_filename->setText(file_name); + +} + +void SetRecovery::on_pushButton_import_pressed() +{ + if(m_file_full.isEmpty())return; + std::cout<exists(toDir); + if (exist){ + if(coverFileIfExist){ + createfile->remove(toDir); + } + } + printf("%s %s \n",sourceDir.toStdString().c_str(),toDir.toStdString().c_str()); + if(!QFile::copy(sourceDir, toDir)) + { + printf("false\n"); + return false; + } + return true; +} + +bool SetRecovery::isDirExist(QString fullPath) +{ + QDir dir(fullPath); + if(dir.exists()) + { + return true; + } + else + { + bool ok = dir.mkdir(fullPath); + return ok; + } +} + +void SetRecovery::setDestSourcePath(QString path) +{ + m_desPath = path; + isDirExist(m_desPath); + if("IPChain" != m_desPath.right(7)) + m_desPath += "/IPChain"; + isDirExist(m_desPath); + + if(Intro::m_clienttype == "test"){ + m_desPath+="/testnet3"; + isDirExist(m_desPath); + } + m_desPath += "/wallet.dat"; + +} diff --git a/.svn/pristine/2e/2e5ff9b9dd738efb8ec030a9cabc2d3ee2001159.svn-base b/.svn/pristine/2e/2e5ff9b9dd738efb8ec030a9cabc2d3ee2001159.svn-base new file mode 100644 index 0000000..5423dd1 --- /dev/null +++ b/.svn/pristine/2e/2e5ff9b9dd738efb8ec030a9cabc2d3ee2001159.svn-base @@ -0,0 +1,79 @@ +// Copyright (c) 2011-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_QT_SENDCOINSDIALOG_H +#define BITCOIN_QT_SENDCOINSDIALOG_H + +#include "walletmodel.h" + +#include +#include +#include +#include + +class ClientModel; +class OptionsModel; +class PlatformStyle; +class SendCoinsRecipient; + +namespace Ui { +class SendCoinsDialog; +} + +QT_BEGIN_NAMESPACE +class QUrl; +QT_END_NAMESPACE + +/** Dialog for sending bitcoins */ +class SendCoinsDialog : public QDialog +{ + Q_OBJECT +public: + enum coinper + { + IPC, + mIPC, + uIPC, + zhi + }; + explicit SendCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent = 0); + ~SendCoinsDialog(); + + void setClientModel(ClientModel *clientModel); + void setModel(WalletModel *model); + + QWidget *setupTabChain(QWidget *prev); + + void setAddress(const QString &address,const QString &label); + void clearInfo(); + +private: + Ui::SendCoinsDialog *ui; + ClientModel *clientModel; + WalletModel *model; + bool fNewRecipientAllowed; + bool fFeeMinimized; + const PlatformStyle *platformStyle; + int eTag = 0; + + void processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, const QString &msgArg = QString()); + void minimizeFeeSection(bool fMinimize); + void updateFeeMinimizedLabel(); + + +private Q_SLOTS: + void on_AddAdsButton_pressed(); + // void on_scanBtn_pressed(); + void on_GoSettingBtn_pressed(); + void coinUpdate(int idx); + +Q_SIGNALS: + // Fired when a message should be reported to the user + void message(const QString &title, const QString &message, unsigned int style); + void openSettingwidget(QString a,QString b,QString label,int tag); + void openSendAffrimwidget(QString a,QString b,QString label,int tag); + void openAddBookPagewidget(int tag); +}; + +#endif // BITCOIN_QT_SENDCOINSDIALOG_H diff --git a/.svn/pristine/32/32b5581361d481011a69e45fc295086580bbc58a.svn-base b/.svn/pristine/32/32b5581361d481011a69e45fc295086580bbc58a.svn-base new file mode 100644 index 0000000..8724a89 --- /dev/null +++ b/.svn/pristine/32/32b5581361d481011a69e45fc295086580bbc58a.svn-base @@ -0,0 +1,104 @@ +#include "sendipchistory.h" +#include "ui_sendipchistory.h" +#include "transactiontablemodel.h" +#include +#include "log/log.h" +sendipchistory::sendipchistory(QWidget *parent) : + QWidget(parent), + ui(new Ui::sendipchistory) +{ + ui->setupUi(this); + this->setWindowFlags(Qt::FramelessWindowHint); + ui->scrollArea->setFrameShape(QFrame::NoFrame); +} +void sendipchistory::setinfo(const QModelIndex &idx) +{ + QString m_txid = idx.data(TransactionTableModel::TxIDRole).toString(); + LOG_WRITE(LOG_INFO,"sendipchistory++hashid",m_txid.toStdString().c_str()); + + QString add = idx.data(TransactionTableModel::AddressRole).toString(); + qint64 dex1 = idx.data(TransactionTableModel::AmountRole).toLongLong(); + + QString add1 = idx.data(TransactionTableModel::ToAddress).toString(); + QString fee = idx.data(TransactionTableModel::feeAmount).toString(); + QString feeText = BitcoinUnits::formatWithUnit(BitcoinUnit::IPC, dex1, true, BitcoinUnits::separatorAlways); + QString ipctitle = idx.data(TransactionTableModel::IPCTitle).toString(); + qint64 ipctype = idx.data(TransactionTableModel::IPCType).toLongLong(); + + QString Authlimit = idx.data(TransactionTableModel::AuthLimit).toString(); + QString Authtype = idx.data(TransactionTableModel::AuthType).toString(); + QString Authtime = idx.data(TransactionTableModel::AuthTime).toString(); + QString lang = idx.data(TransactionTableModel::LanguageRole).toString(); + + + QString m_status = idx.data(TransactionTableModel::InfoStatus).toString(); + QString m_time = idx.data(TransactionTableModel::InfoTime).toString(); + + qint64 txfee = idx.data(TransactionTableModel::feeAmount).toLongLong(); + QString m_txfee = BitcoinUnits::formatWithUnit(BitcoinUnit::IPC, txfee, false, BitcoinUnits::separatorAlways); + + ui->AddEdit->setText(add); + ui->ipcnameEdit->setText(ipctitle); + if(Authtime == "forever") + { + ui->authdate->setText(tr("forever")); + }else + { + if(Authtime.indexOf("forever") != -1) + { + int t = Authtime.indexOf("--"); + QString X = Authtime.mid(0,t); + Authtime = X + tr("--")+tr("forever"); + ui->authdate->setText(Authtime); + } + else + { + ui->authdate->setText(Authtime); + } + } + if("ownership"==Authtype){ + ui->authtype->setText(tr("ownership")); + }else{ + ui->authtype->setText(tr("Use right")); + } + if("can authorization"==Authlimit){ + ui->authlimit->setText(tr("can authorization")); + }else{ + ui->authlimit->setText(tr("cannot authorization")); + } + QStringList type = QStringList()<=0&&ipctype<8) + { + IPCType = type.at(ipctype); + } + else + { + IPCType =tr("patent"); + } + + ui->ipctypelabel->setText(IPCType); + ui->ipctimelabel->setText(m_time); + ui->ipcinfolabel->setText(m_status); + ui->ipcfeelabel->setText(m_txfee); +} + +sendipchistory::~sendipchistory() +{ + delete ui; +} +void sendipchistory::updateInfo(QString status) +{ + ui->ipcinfolabel->setText(status); +} +void sendipchistory::showVisual(bool visual) +{ + if(visual) + { + setVisible(true); + } + else + { + setVisible(false); + } +} diff --git a/.svn/pristine/37/37e89bbdbb39b85f3795e006da9f3572d487b7cb.svn-base b/.svn/pristine/37/37e89bbdbb39b85f3795e006da9f3572d487b7cb.svn-base new file mode 100644 index 0000000..a913dcb --- /dev/null +++ b/.svn/pristine/37/37e89bbdbb39b85f3795e006da9f3572d487b7cb.svn-base @@ -0,0 +1,44 @@ +#ifndef UNIONACCOUNTTRANSACTION_H +#define UNIONACCOUNTTRANSACTION_H + +#include +#include "wallet/wallet.h" +class WalletModel; +namespace Ui { +class unionaccounttransaction; +} + +class unionaccounttransaction : public QWidget +{ + Q_OBJECT + +public: + explicit unionaccounttransaction(QWidget *parent = 0); + ~unionaccounttransaction(); + void setModel(WalletModel *_model); + void setinfo(QString s1,QString s2,CAmount s3,std::string s4,QString confirmnum,QString allmnum); + std::string getAddress(); + void timerEvent( QTimerEvent *event ); + + + +Q_SIGNALS: + void gosendPage(QString s); + void gosignPage(); + void jumptohistorypage(CAmount num,std::string add, std::map s); +private Q_SLOTS: + void on_signbtn_pressed(); + void on_sendbtn_pressed(); + + void on_btn_history_pressed(); + + void on_btn_export_pressed(); + +private: + Ui::unionaccounttransaction *ui; + WalletModel *model; + QString m_addfrom; + int m_nTimerId; +}; + +#endif // UNIONACCOUNTTRANSACTION_H diff --git a/.svn/pristine/38/38e32f38b7a91b478e76328ca602f0ce5babcae9.svn-base b/.svn/pristine/38/38e32f38b7a91b478e76328ca602f0ce5babcae9.svn-base new file mode 100644 index 0000000..a058f81 --- /dev/null +++ b/.svn/pristine/38/38e32f38b7a91b478e76328ca602f0ce5babcae9.svn-base @@ -0,0 +1,26 @@ +#ifndef RECVIPCHISTORY_H +#define RECVIPCHISTORY_H + +#include +QT_BEGIN_NAMESPACE +class QModelIndex; +QT_END_NAMESPACE +namespace Ui { +class recvipchistory; +} + +class recvipchistory : public QWidget +{ + Q_OBJECT + +public: + explicit recvipchistory(QWidget *parent = 0); + ~recvipchistory(); + void showVisual(bool visual); + void updateInfo(QString status); + void setinfo(const QModelIndex &idx); +private: + Ui::recvipchistory *ui; +}; + +#endif // RECVIPCHISTORY_H diff --git a/.svn/pristine/39/39c7df774e264574241e1be6da6adc49e12b0d38.svn-base b/.svn/pristine/39/39c7df774e264574241e1be6da6adc49e12b0d38.svn-base new file mode 100644 index 0000000..eeaaab8 --- /dev/null +++ b/.svn/pristine/39/39c7df774e264574241e1be6da6adc49e12b0d38.svn-base @@ -0,0 +1,182 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_SCRIPT_INTERPRETER_H +#define BITCOIN_SCRIPT_INTERPRETER_H + +#include "script_error.h" +#include "primitives/transaction.h" + +#include +#include +#include + +class CPubKey; +class CScript; +class CTransaction; +class uint256; + +/** Signature hash types/flags */ +enum +{ + SIGHASH_ALL = 1, + SIGHASH_NONE = 2, + SIGHASH_SINGLE = 3, + SIGHASH_ANYONECANPAY = 0x80, +}; + +/** Script verification flags */ +enum +{ + SCRIPT_VERIFY_NONE = 0, + + // Evaluate P2SH subscripts (softfork safe, BIP16). + SCRIPT_VERIFY_P2SH = (1U << 0), + + // Passing a non-strict-DER signature or one with undefined hashtype to a checksig operation causes script failure. + // Evaluating a pubkey that is not (0x04 + 64 bytes) or (0x02 or 0x03 + 32 bytes) by checksig causes script failure. + // (softfork safe, but not used or intended as a consensus rule). + SCRIPT_VERIFY_STRICTENC = (1U << 1), + + // Passing a non-strict-DER signature to a checksig operation causes script failure (softfork safe, BIP62 rule 1) + SCRIPT_VERIFY_DERSIG = (1U << 2), + + // Passing a non-strict-DER signature or one with S > order/2 to a checksig operation causes script failure + // (softfork safe, BIP62 rule 5). + SCRIPT_VERIFY_LOW_S = (1U << 3), + + // verify dummy stack item consumed by CHECKMULTISIG is of zero-length (softfork safe, BIP62 rule 7). + SCRIPT_VERIFY_NULLDUMMY = (1U << 4), + + // Using a non-push operator in the scriptSig causes script failure (softfork safe, BIP62 rule 2). + SCRIPT_VERIFY_SIGPUSHONLY = (1U << 5), + + // Require minimal encodings for all push operations (OP_0... OP_16, OP_1NEGATE where possible, direct + // pushes up to 75 bytes, OP_PUSHDATA up to 255 bytes, OP_PUSHDATA2 for anything larger). Evaluating + // any other push causes the script to fail (BIP62 rule 3). + // In addition, whenever a stack element is interpreted as a number, it must be of minimal length (BIP62 rule 4). + // (softfork safe) + SCRIPT_VERIFY_MINIMALDATA = (1U << 6), + + // Discourage use of NOPs reserved for upgrades (NOP1-10) + // + // Provided so that nodes can avoid accepting or mining transactions + // containing executed NOP's whose meaning may change after a soft-fork, + // thus rendering the script invalid; with this flag set executing + // discouraged NOPs fails the script. This verification flag will never be + // a mandatory flag applied to scripts in a block. NOPs that are not + // executed, e.g. within an unexecuted IF ENDIF block, are *not* rejected. + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1U << 7), + + // Require that only a single stack element remains after evaluation. This changes the success criterion from + // "At least one stack element must remain, and when interpreted as a boolean, it must be true" to + // "Exactly one stack element must remain, and when interpreted as a boolean, it must be true". + // (softfork safe, BIP62 rule 6) + // Note: CLEANSTACK should never be used without P2SH or WITNESS. + SCRIPT_VERIFY_CLEANSTACK = (1U << 8), + + // Verify CHECKLOCKTIMEVERIFY + // + // See BIP65 for details. + SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), + + // support CHECKSEQUENCEVERIFY opcode + // + // See BIP112 for details + SCRIPT_VERIFY_CHECKSEQUENCEVERIFY = (1U << 10), + + // Support segregated witness + // + SCRIPT_VERIFY_WITNESS = (1U << 11), + + // Making v1-v16 witness program non-standard + // + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM = (1U << 12), + + // Segwit script only: Require the argument of OP_IF/NOTIF to be exactly 0x01 or empty vector + // + SCRIPT_VERIFY_MINIMALIF = (1U << 13), + + // Signature(s) must be empty vector if an CHECK(MULTI)SIG operation failed + // + SCRIPT_VERIFY_NULLFAIL = (1U << 14), + + // Public keys in segregated witness scripts must be compressed + // + SCRIPT_VERIFY_WITNESS_PUBKEYTYPE = (1U << 15), +}; + +bool CheckSignatureEncoding(const std::vector &vchSig, unsigned int flags, ScriptError* serror); + +struct PrecomputedTransactionData +{ + uint256 hashPrevouts, hashSequence, hashOutputs; + + PrecomputedTransactionData(const CTransaction& tx); +}; + +enum SigVersion +{ + SIGVERSION_BASE = 0, + SIGVERSION_WITNESS_V0 = 1, +}; + +uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache = NULL); + +class BaseSignatureChecker +{ +public: + virtual bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const + { + return false; + } + + virtual bool CheckLockTime(const CScriptNum& nLockTime) const + { + return false; + } + + virtual bool CheckSequence(const CScriptNum& nSequence) const + { + return false; + } + + virtual ~BaseSignatureChecker() {} +}; + +class TransactionSignatureChecker : public BaseSignatureChecker +{ +private: + const CTransaction* txTo; + unsigned int nIn; + const CAmount amount; + const PrecomputedTransactionData* txdata; + +protected: + virtual bool VerifySignature(const std::vector& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; + +public: + TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(NULL) {} + TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, const PrecomputedTransactionData& txdataIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {} + bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const; + bool CheckLockTime(const CScriptNum& nLockTime) const; + bool CheckSequence(const CScriptNum& nSequence) const; +}; + +class MutableTransactionSignatureChecker : public TransactionSignatureChecker +{ +private: + const CTransaction txTo; + +public: + MutableTransactionSignatureChecker(const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amount) : TransactionSignatureChecker(&txTo, nInIn, amount), txTo(*txToIn) {} +}; + +bool EvalScript(std::vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* error = NULL); + +bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror = NULL); +size_t CountWitnessSigOps(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags); + +#endif // BITCOIN_SCRIPT_INTERPRETER_H diff --git a/.svn/pristine/3a/3a5bc66a3134e1f3adb091d92c83c06878f89c99.svn-base b/.svn/pristine/3a/3a5bc66a3134e1f3adb091d92c83c06878f89c99.svn-base new file mode 100644 index 0000000..8fc886a --- /dev/null +++ b/.svn/pristine/3a/3a5bc66a3134e1f3adb091d92c83c06878f89c99.svn-base @@ -0,0 +1,1095 @@ +// Copyright (c) 2011-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "transactionrecord.h" +#include +#include "base58.h" +#include "consensus/consensus.h" +#include "validation.h" +#include "timedata.h" +#include "wallet/wallet.h" +#include +#include +#include +#include +#include +#include "timedata.h" +#include "util.h" +#include +#include +#include +#include +#include "log/log.h" +#include "ipcdialog.h" +#include "ecoindialog.h" + +/* Return positive answer if transaction should be shown in list. + */ + + +QString IntTimeToQStringTime(int inttime) +{ + QDateTime timedate = QDateTime::fromTime_t(inttime); + QDate dateqdate = timedate.date(); + QString timestr = dateqdate.toString("yyyy/MM/dd"); + return timestr; +} + +int TransactionRecord::GetAccuracySymbol(std::string tokensymbol) +{ + uint8_t uback = wallet_->GetAccuracyBySymbol(tokensymbol); + QString temp = QString::number(uback,16); + return temp.toInt(); +} +QString TransactionRecord::getAccuracyNumstr(QString name ,QString num) +{ + std::string stdname = name.toStdString(); + int acc = GetAccuracySymbol(stdname); + if(acc>0){ + if(num.size()>acc){ + num=num.insert(num.size()-acc,"."); + }else{ + QString temp = "0"; + for(int i=0;i0){ + if(num.size()>acc){ + num=num.insert(num.size()-acc,"."); + }else{ + QString temp = "0"; + for(int i=0;inLockTime < LOCKTIME_THRESHOLD) + { + return QObject::tr("Open for %n more block(s)", "", wtx.tx->nLockTime - chainActive.Height()); + } + else + { + return QObject::tr("Open until %1").arg(GUIUtil::dateTimeStr(wtx.tx->nLockTime)); + } + } + else + { + int nDepth = wtx.GetDepthInMainChain(); + if (nDepth < 0) + { + return QObject::tr("conflicted with a transaction with %1 confirmations").arg(-nDepth); + } + else if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) + { + return QObject::tr("%1/offline").arg(wtx.GetDepthInMainChain()); + // return tr("%1/offline").arg(nDepth); + } + else if (nDepth == 0) + { + return QObject::tr("0/unconfirmed, %1").arg((wtx.InMempool() ? QObject::tr("in memory pool") : QObject::tr("not in memory pool"))) + (wtx.isAbandoned() ? ", "+QObject::tr("abandoned") : ""); + } + else if (nDepth < 8) + { + return QObject::tr("%1/unconfirmed").arg(wtx.GetDepthInMainChain()); + + //return tr("%1/unconfirmed").arg(nDepth); + } + else + { + return QObject::tr("%1 confirmations").arg(wtx.GetDepthInMainChain()); + + // return tr("%1 confirmations").arg(nDepth); + } + } +} +QString TransactionRecord::FormatTxTime(const CWalletTx& wtx) +{ + int64_t nTime = wtx.GetTxTime(); + QString m_time=QDateTime::fromTime_t(nTime).toString("yyyy-MM-dd hh:mm:ss");; + + + return m_time; +} + +void TransactionRecord::markLastInfo(std::string add,CAmount mount) +{ + QList parts; + TransactionRecord sub(m_traninfo.nhash, m_traninfo.ntime); + sub.credit=mount; + sub.type = TransactionRecord::Recvdeposit; + sub.address = CBitcoinAddress(add).ToString(); + + sub.involvesWatchAddress = true; + sub.strstatus = m_traninfo.status; + sub.strtime =m_traninfo.time; + parts.append(sub); +} +void TransactionRecord::saveInfo(TranInfo traninfo) +{ + m_traninfo.add = traninfo.add; + m_traninfo.status = traninfo.status; + m_traninfo.time = traninfo.time; + m_traninfo.nhash = traninfo.nhash; + m_traninfo.ntime = traninfo.ntime; +} + +QList TransactionRecord::decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx) +{ + wallet_=const_cast(wallet); + if( nullptr== wallet_) + { + printf("never happende \n\n\n\n"); + } + + QList parts; + QList m_parts; + int64_t nTime = wtx.GetTxTime(); + CAmount nCredit = wtx.GetCredit(ISMINE_ALL); + CAmount nDebit = wtx.GetDebit(ISMINE_ALL); + CAmount nNet = nCredit - nDebit; + uint256 hash = wtx.GetHash(); + bool isTag = false; + bool isMarked = false; + std::map mapValue = wtx.mapValue; + if (wtx.IsCoinBase()) + { + // mapmarkAdd.clear(); + for(unsigned int i = 0; i < wtx.tx->vout.size(); i++) + { + const CTxOut& txout = wtx.tx->vout[i]; + isminetype mine = wallet->IsMine(txout); + if(mine) + { + TransactionRecord sub(hash, nTime); + CTxDestination address; + + sub.idx = i; // vout index + sub.credit = txout.nValue; + sub.involvesWatchAddress = mine & ISMINE_WATCH_ONLY; + sub.strstatus = FormatTxStatus(wtx); + sub.strtime =FormatTxTime(wtx); + if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address)) + { + + if(0==txout.txType) + { + // sub.type = TransactionRecord::RecvCoin; + } + else if(1== txout.txType && 4 == txout.devoteLabel.ExtendType) + { + + CAmount markbill; + std::string add_ = CBitcoinAddress(address).ToString(); + + sub.involvesWatchAddress = false; + sub.credit = wallet->GetDeposit(); + LOG_WRITE(LOG_INFO,"mark bill0000000",QString::number(sub.credit).toStdString().c_str(),sub.strtime.toStdString().c_str(),add_.c_str()); + + sub.credit = 0; + sub.debit = 0; + sub.type = TransactionRecord::Recvdeposit; + sub.address = CBitcoinAddress(address).ToString(); + parts.append(sub); + + LOG_WRITE(LOG_INFO,"mark bill",QString::number(sub.credit).toStdString().c_str(),sub.strtime.toStdString().c_str(),add_.c_str()); + } + } + } + } + + } + else + { + bool involvesWatchAddress = false; + isminetype fAllFromMe = ISMINE_SPENDABLE; + BOOST_FOREACH(const CTxIn& txin, wtx.tx->vin) + { + isminetype mine = wallet->IsMine(txin); + CTxDestination address; + std::string add; + + ExtractDestination(txin.scriptSig, address); + add= CBitcoinAddress(address).ToString(); + + if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true; + if(fAllFromMe > mine) fAllFromMe = mine; + } + + isminetype fAllToMe = ISMINE_SPENDABLE; + bool m_isAllToMe = true; + isminetype m_lastfAllToMe = ISMINE_WATCH_UNSOLVABLE; + int m_allis = 0; + BOOST_FOREACH(const CTxOut& txout, wtx.tx->vout) + { + isminetype mine = wallet->IsMine(txout); + + CTxDestination address; + std::string add; + if (ExtractDestination(txout.scriptPubKey, address)) + add= CBitcoinAddress(address).ToString(); + + if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true; + if(fAllToMe > mine) fAllToMe = mine; + if(fAllFromMe && (wtx.tx->vout.size() >2)) + { + if(0 == txout.txType) + { + // if((m_lastfAllToMe != ISMINE_WATCH_UNSOLVABLE) && (m_lastfAllToMe != fAllToMe)) + { + m_isAllToMe = false; + + } + m_lastfAllToMe = fAllToMe; + m_allis++; + } + + } + + } + if((m_allis != wtx.tx->vout.size()) && (m_allis != 0)) + { + + LOG_WRITE(LOG_INFO,"m_isAllToMe = true",QString::number(m_allis).toStdString().c_str()); + m_isAllToMe = true; + } + + + LOG_WRITE(LOG_INFO,"m_isAllToMe = true00000",QString::number(fAllFromMe).toStdString().c_str(),\ + QString::number(m_isAllToMe).toStdString().c_str(),\ + QString::number(fAllToMe).toStdString().c_str()); + + if (fAllFromMe && fAllToMe && m_isAllToMe) + { + LOG_WRITE(LOG_INFO,"m_isAllToMe = true1",QString::number(fAllFromMe).toStdString().c_str(),\ + QString::number(m_isAllToMe).toStdString().c_str(),\ + QString::number(fAllToMe).toStdString().c_str()); + CAmount nChange = wtx.GetChange(); + bool isSpecileTran = false; + + CAmount nTxFee = nDebit - wtx.tx->GetValueOut(); + + for (unsigned int nOut = 0; nOut < wtx.tx->vout.size(); nOut++) + { + + const CTxOut& txout = wtx.tx->vout[nOut]; + if(2==txout.txType || 3==txout.txType){ + + ipcdialog::updatalist(); + ipcdialog::m_bNeedUpdateLater = true; + CTxDestination address; + std::string add; + if (ExtractDestination(txout.scriptPubKey, address)) + add= CBitcoinAddress(address).ToString(); + int typenum = txout.ipcLabel.ExtendType; + int ipcType; + + ipcType = typenum; + QString AuthType; + QString AuthLimit; + QString AuthTime; + if(2 == txout.txType) + AuthType =QObject::tr("ownership"); + else + AuthType = QObject::tr("Use right"); + if(1 == txout.ipcLabel.reAuthorize) //if(1== txout.ipcLabel.uniqueAuthorize)//5 + { + AuthLimit = QObject::tr("can authorization"); + } + else + { + AuthLimit = QObject::tr("cannot authorization"); + } + + uint32_t start = txout.ipcLabel.startTime; + uint32_t stop = txout.ipcLabel.stopTime; + + + QString starttime=IntTimeToQStringTime(start);//2 + QString stoptime = IntTimeToQStringTime(stop);//3 + if(starttime == "1970/01/01" && stoptime == "1970/01/01") + { + AuthTime =QObject::tr("forever"); + } + else + { + if(stoptime == "1970/01/01") + { + AuthTime = starttime+ "--" +QObject::tr("forever"); + } + else + { + AuthTime = starttime+ "--" +stoptime; + + } + } + QString m_status=FormatTxStatus(wtx); + QString m_strtime =FormatTxTime(wtx); + CAmount m_fee = nDebit - wtx.tx->GetValueOut(); + parts.append(TransactionRecord(hash, nTime, TransactionRecord::RecvIPC,add, + -(nDebit - nChange), nCredit - nChange,txout.ipcLabel.labelTitle,ipcType,AuthType,AuthLimit,AuthTime,m_status,m_strtime,m_fee)); + parts.last().involvesWatchAddress = involvesWatchAddress;// maybe pass to TransactionRecord as constructor argument + isSpecileTran = true; + break; + + } + else if(0==txout.txType) + { + + } + else if(4==txout.txType || 5==txout.txType) + { + ECoinDialog::updatalist(); + ECoinDialog::m_bNeedUpdateLater = true; + const CTxOut& txout = wtx.tx->vout[nOut]; + std::string y; + QString num; + if(4 == txout.txType){ + y =(char*)(txout.tokenRegLabel.TokenSymbol); + num=QString::number(txout.tokenRegLabel.totalCount);//444 + int vacc = txout.tokenRegLabel.accuracy; + num = getAccuracyNum(vacc,num); + } + else{ + y=(char*)(txout.tokenLabel.TokenSymbol); + num=QString::number(txout.tokenLabel.value);//555 + int vacc = txout.tokenLabel.accuracy; + num = getAccuracyNum(vacc,num); + } + + isSpecileTran = true; + CTxDestination address; + std::string add; + if (ExtractDestination(txout.scriptPubKey, address)) + add= CBitcoinAddress(address).ToString(); + QString m_status=FormatTxStatus(wtx); + QString m_strtime =FormatTxTime(wtx); + CAmount m_fee = nDebit - wtx.tx->GetValueOut(); + parts.append(TransactionRecord(hash, nTime, TransactionRecord::RecveCoin, add, + -(nDebit - nChange), nCredit - nChange,y,num,m_status,m_strtime,m_fee)); + parts.last().involvesWatchAddress = involvesWatchAddress;// maybe pass to TransactionRecord as constructor argument + break; + } + else if(1 == txout.txType) + { + CTxDestination address; + std::string add; + if(ExtractDestination(txout.scriptPubKey, address)) + add= CBitcoinAddress(address).ToString(); + + QString m_status=FormatTxStatus(wtx); + QString m_strtime =FormatTxTime(wtx); + + CAmount m_fee = nDebit - wtx.tx->GetValueOut(); + + parts.append(TransactionRecord(hash, nTime, TransactionRecord::Senddeposit,add, + -(nDebit - nChange), nChange - nCredit ,m_status,m_strtime,m_fee));//txout.ipcLabel.labelTitle,txout.ipcLabel.ExtendType, + + parts.last().involvesWatchAddress = involvesWatchAddress;// maybe pass to TransactionRecord as constructor argument + + isSpecileTran = true; + break; + } + + } + if(false == isSpecileTran) + { + + mapAdd.clear(); + for (unsigned int nOut = 0; nOut < wtx.tx->vout.size(); nOut++) + { + + const CTxOut& txout = wtx.tx->vout[nOut]; + + if(0 == txout.txType )//|| 1==txout.txType) + { + CTxDestination address; + std::string add; + if(ExtractDestination(txout.scriptPubKey, address)) + { + add= CBitcoinAddress(address).ToString(); + mapAdd.insert(std::pair(txout.nValue, add)); + } + + } + } + for (unsigned int nOut = 0; nOut < (wtx.tx->vout.size()-1); nOut++) + { + const CTxOut& txout = wtx.tx->vout[nOut]; + + if(0 == txout.txType )//|| 1==txout.txType) + { + CTxDestination address; + std::string add; + if(ExtractDestination(txout.scriptPubKey, address)) + add= CBitcoinAddress(address).ToString(); + if( wtx.tx->vout.size() > 2) + { + add = add+"..."; + } + + QString m_status=FormatTxStatus(wtx); + + QString m_strtime =FormatTxTime(wtx); + + CAmount m_fee = nDebit - wtx.tx->GetValueOut(); + if(nOut == wtx.tx->vout.size()-2) + { + parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf,add, + -(nDebit - nChange), nChange - nCredit ,m_status,m_strtime,m_fee));//txout.ipcLabel.labelTitle,txout.ipcLabel.ExtendType, + + parts.last().involvesWatchAddress = involvesWatchAddress;// maybe pass to TransactionRecord as constructor argument + } + // break; + + } + } + } + } + else if (fAllFromMe && !fAllToMe && m_isAllToMe) + { + LOG_WRITE(LOG_INFO,"m_isAllToMe = true2",QString::number(fAllFromMe).toStdString().c_str(),\ + QString::number(m_isAllToMe).toStdString().c_str(),\ + QString::number(fAllToMe).toStdString().c_str()); + bool isSpecileTran = false; + CAmount nTxFee = nDebit - wtx.tx->GetValueOut(); + for (unsigned int nOut = 0; nOut < wtx.tx->vout.size(); nOut++) + { + const CTxOut& txout = wtx.tx->vout[nOut]; + + TransactionRecord sub(hash, nTime); + sub.idx = nOut; + sub.involvesWatchAddress = involvesWatchAddress; + if(wallet->IsMine(txout)) + { + continue; + } + + CTxDestination address; + if (ExtractDestination(txout.scriptPubKey, address)) + { + + if(2==txout.txType|| 3==txout.txType) + { + + ipcdialog::updatalist(); + ipcdialog::m_bNeedUpdateLater = true; + sub.type = TransactionRecord::SendIPC; + + sub.ipcTitle = txout.ipcLabel.labelTitle; + int typenum = txout.ipcLabel.ExtendType; + + sub.ipcType = typenum; + sub.authType = txout.ipcLabel.reAuthorize; + sub.authLimit =txout.ipcLabel.uniqueAuthorize ; + + + if(2 == txout.txType) + sub.authType =QObject::tr("ownership"); + else + sub.authType = QObject::tr("Use right"); + if(1 == txout.ipcLabel.reAuthorize) + { + sub.authLimit = QObject::tr("can authorization"); + } + else + { + sub.authLimit = QObject::tr("cannot authorization"); + } + + uint32_t start = txout.ipcLabel.startTime; + uint32_t stop = txout.ipcLabel.stopTime; + + + QString starttime=IntTimeToQStringTime(start);//2 + QString stoptime = IntTimeToQStringTime(stop);//3 + if(starttime == "1970/01/01" && stoptime == "1970/01/01") + { + sub.authTime =QObject::tr("forever"); + } + else + { + if(stoptime == "1970/01/01") + { + sub.authTime = starttime+ "--" +QObject::tr("forever"); + } + else + { + sub.authTime = starttime+ "--" +stoptime; + + } + } + + sub.address = CBitcoinAddress(address).ToString(); + sub.strstatus=FormatTxStatus(wtx); + sub.strtime =FormatTxTime(wtx); + CAmount nValue = txout.nValue; + if (nTxFee > 0) + { + nValue += nTxFee; + nTxFee = 0; + } + sub.debit = -nValue; + + CAmount m_fee = nDebit - wtx.tx->GetValueOut(); + sub.TxFee = m_fee; + isSpecileTran = true; + parts.append(sub); + + break; + + } + // Sent to Bitcoin Address + else if(0==txout.txType) + { + + } + else if(1==txout.txType) + { + + break; + + } + + + else if(4==txout.txType || 5==txout.txType) + { + ECoinDialog::updatalist(); + ECoinDialog::m_bNeedUpdateLater = true; + sub.type = TransactionRecord::SendeCoin; + const CTxOut& txout = wtx.tx->vout[nOut]; + std::string y =(char*)(txout.tokenLabel.TokenSymbol); + //sub.amount = txout.tokenRegLabel.totalCount; + sub.ecoinType = y; + sub.ecoinNum =QString::number(txout.tokenLabel.value); + int vacc = txout.tokenLabel.accuracy; + sub.ecoinNum = getAccuracyNum(vacc,sub.ecoinNum); + sub.address = CBitcoinAddress(address).ToString(); + CAmount nValue = txout.nValue; + if (nTxFee > 0) + { + nValue += nTxFee; + nTxFee = 0; + } + sub.debit = -nValue; + + CAmount m_fee = nDebit - wtx.tx->GetValueOut(); + sub.TxFee = m_fee; + + sub.strstatus=FormatTxStatus(wtx); + sub.strtime =FormatTxTime(wtx); + + isSpecileTran = true; + parts.append(sub); + break; + } + else + { + } + + } + + } + if(false == isSpecileTran) + { + + CAmount nvalueplus = 0; + for (unsigned int nOut = 0; nOut < (wtx.tx->vout.size()-1); nOut++) + { + const CTxOut& txout = wtx.tx->vout[nOut]; + TransactionRecord sub(hash, nTime); + sub.idx = nOut; + sub.involvesWatchAddress = involvesWatchAddress; + + + + if(wallet->IsMine(txout)) + { + // Ignore parts sent to self, as this is usually the change + // from a transaction sent back to our own address. + continue; + } + + + CTxDestination address; + if (ExtractDestination(txout.scriptPubKey, address)) + { + + if(0==txout.txType) + { + + sub.strstatus=FormatTxStatus(wtx); + sub.strtime =FormatTxTime(wtx); + sub.type = TransactionRecord::SendCoin; + sub.address = CBitcoinAddress(address).ToString(); + if(wtx.tx->vout.size() >2) + { + sub.address = sub.address+"..."; + } + CAmount nValue = txout.nValue; + nvalueplus += -nValue; + sub.debit = nvalueplus; + + CAmount m_fee = nDebit - wtx.tx->GetValueOut(); + sub.TxFee = m_fee; + + if(nOut == wtx.tx->vout.size()-2) + { + parts.append(sub); + } + // break; + + } + } + + } + } + } + else if(fAllFromMe && !m_isAllToMe) + { + LOG_WRITE(LOG_INFO,"m_isAllToMe = true3",QString::number(fAllFromMe).toStdString().c_str(),\ + QString::number(m_isAllToMe).toStdString().c_str(),\ + QString::number(fAllToMe).toStdString().c_str()); + CAmount nChange = wtx.GetChange(); + bool isSpecileTran = false; + CAmount nvalueplus_ = 0; + CAmount nTxFee = nDebit - wtx.tx->GetValueOut(); + + for (unsigned int nOut = 0; nOut < wtx.tx->vout.size(); nOut++) + { + + const CTxOut& txout = wtx.tx->vout[nOut]; + if(2==txout.txType || 3==txout.txType){ + LOG_WRITE(LOG_INFO,"error date2"); + break; + } + else if(0==txout.txType) + { + } + else if(4==txout.txType || 5==txout.txType) + { + LOG_WRITE(LOG_INFO,"error date4"); + break; + } + else if(1 == txout.txType) + { + LOG_WRITE(LOG_INFO,"error date1"); + break; + } + + } + if(false == isSpecileTran) + { + for (unsigned int nOut = 0; nOut < (wtx.tx->vout.size()-1); nOut++) + { + const CTxOut& txout = wtx.tx->vout[nOut]; + + if(0 == txout.txType )//|| 1==txout.txType) + { + CTxDestination address; + std::string add; + if(ExtractDestination(txout.scriptPubKey, address)) + add= CBitcoinAddress(address).ToString(); + if( wtx.tx->vout.size() > 2) + { + add = add+"..."; + } + + QString m_status=FormatTxStatus(wtx); + QString m_strtime =FormatTxTime(wtx); + CAmount nValue = txout.nValue; + nvalueplus_ += -nValue; + CAmount m_fee = nDebit - wtx.tx->GetValueOut(); + + if(nOut == wtx.tx->vout.size()-2) + { + LOG_WRITE(LOG_INFO,"SENDMANY"); + parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf,add, + 0, nvalueplus_ ,m_status,m_strtime,m_fee));//txout.ipcLabel.labelTitle,txout.ipcLabel.ExtendType, + + parts.last().involvesWatchAddress = involvesWatchAddress;// maybe pass to TransactionRecord as constructor argument + } + // break; + + } + } + } + + + } + else + { + LOG_WRITE(LOG_INFO,"m_isAllToMe = true4",QString::number(fAllFromMe).toStdString().c_str(),\ + QString::number(m_isAllToMe).toStdString().c_str(),\ + QString::number(fAllToMe).toStdString().c_str()); + CAmount nTxFee = nDebit - wtx.tx->GetValueOut(); + CAmount m_plusmoney = 0; + std::string m_plusadd = ""; + int m_plusnOut = 0; + int m_newplusOut = 0; + int m_isplusnOut = 0; + int m_notplusnOut = 0; + + int m_newisplusnOut = 0; + int m_newnotplusnOut = 0; + for (unsigned int nOut = 0; nOut < wtx.tx->vout.size(); nOut++) + { + const CTxOut& txout = wtx.tx->vout[nOut]; + TransactionRecord sub(hash, nTime); + sub.idx = nOut; + sub.involvesWatchAddress = involvesWatchAddress; + m_plusnOut++; + ++m_newplusOut; + if(!wallet->IsMine(txout)) + { + // Ignore parts sent to self, as this is usually the change + // from a transaction sent back to our own address. + m_notplusnOut++; + ++m_newnotplusnOut; + + if(0 == parts.size() &&(m_notplusnOut == (wtx.tx->vout.size()-m_isplusnOut)) ) + { + LOG_WRITE(LOG_INFO,"new push <<>1-2",QString::number(m_plusnOut).toStdString().c_str(),QString::number(wtx.tx->vout.size()).toStdString().c_str(),QString::number(m_isplusnOut).toStdString().c_str() ,QString::number(m_notplusnOut).toStdString().c_str()); + + parts.append(m_parts); + m_parts.clear(); + } + + continue; + } + + CTxDestination address; + if (ExtractDestination(txout.scriptPubKey, address)) + { + + if( 2==txout.txType||3==txout.txType) + { + ipcdialog::updatalist(); + ipcdialog::m_bNeedUpdateLater = true; + + sub.type = TransactionRecord::RecvIPC; + sub.address = CBitcoinAddress(address).ToString(); + CAmount nValue = txout.nValue; + sub.credit = nValue; + std::string title = txout.ipcLabel.labelTitle; + sub.ipcTitle=txout.ipcLabel.labelTitle; + sub.strstatus=FormatTxStatus(wtx); + sub.strtime =FormatTxTime(wtx); + int typenum = txout.ipcLabel.ExtendType; + sub.ipcType = typenum; + sub.authType = txout.ipcLabel.reAuthorize; + sub.authLimit =txout.ipcLabel.uniqueAuthorize ; + + + if(2 == txout.txType) + sub.authType =QObject::tr("ownership"); + else + sub.authType = QObject::tr("Use right"); + if(1 == txout.ipcLabel.reAuthorize) + { + sub.authLimit = QObject::tr("can authorization"); + } + else + { + sub.authLimit = QObject::tr("cannot authorization"); + } + + uint32_t start = txout.ipcLabel.startTime; + uint32_t stop = txout.ipcLabel.stopTime; + + + QString starttime=IntTimeToQStringTime(start);//2 + QString stoptime = IntTimeToQStringTime(stop);//3 + if(starttime == "1970/01/01" && stoptime == "1970/01/01") + { + sub.authTime =QObject::tr("forever"); + } + else + { + if(stoptime == "1970/01/01") + { + sub.authTime = starttime+ "--" +QObject::tr("forever"); + } + else + { + sub.authTime = starttime+ "--" +stoptime; + + } + } + + sub.TxFee = 0; + parts.append(sub); + break; + + } + // Sent to Bitcoin Address + else if(0==txout.txType) + { + m_isplusnOut++; + sub.strtime = FormatTxTime(wtx); + sub.strstatus = FormatTxStatus(wtx); + sub.type = TransactionRecord::RecvCoin; + + LOG_WRITE(LOG_INFO,"recv is mine1"); + + m_plusadd = CBitcoinAddress(address).ToString(); + sub.address=m_plusadd; + //if(wtx.tx->vout.size()>2) + if(m_isplusnOut > 1) + { + sub.address +="..."; + } + CAmount nValue = txout.nValue; + m_plusmoney += nValue; + sub.credit = m_plusmoney; + m_parts.clear(); + m_parts.append(sub); + if((m_plusnOut == (wtx.tx->vout.size()-1))) + { + parts.append(sub); + m_parts.clear(); + } + if(wtx.tx->vout.size()==1) + { + parts.append(sub); + m_parts.clear(); + } + LOG_WRITE(LOG_INFO,"msg read",sub.address.c_str(),"num",QString::number(sub.credit).toStdString().c_str()); + + + LOG_WRITE(LOG_INFO,"m_plusnOut = 2 && wtx.tx->vout.size()",QString::number(m_plusnOut).toStdString().c_str(),QString::number(wtx.tx->vout.size()).toStdString().c_str()); + + + LOG_WRITE(LOG_INFO,"parts.size() = 0 ",QString::number(parts.size()).toStdString().c_str(),QString::number(wtx.tx->vout.size()).toStdString().c_str()); + + if(0== parts.size()&& 2== wtx.tx->vout.size() && m_plusnOut==wtx.tx->vout.size() ) + { + LOG_WRITE(LOG_INFO,"new push"); + parts.append(sub); + m_parts.clear(); + } + //LOG_WRITE(LOG_INFO,"new push >>>>2",QString::number(m_isplusnOut).toStdString().c_str() ); + if(0 == parts.size() && wtx.tx->vout.size() > 2 && m_plusnOut==wtx.tx->vout.size() ) + { + LOG_WRITE(LOG_INFO,"new push >2",QString::number(m_isplusnOut).toStdString().c_str() ); + parts.append(sub); + m_parts.clear(); + } + + + + // break; + } + else if(1==txout.txType) + { + } + else if(4==txout.txType || 5==txout.txType) + { + ECoinDialog::updatalist(); + ECoinDialog::m_bNeedUpdateLater = true; + sub.type = TransactionRecord::RecveCoin; + std::string y; + int vacc=0; + if(4==txout.txType){ + y=(char*)(txout.tokenRegLabel.TokenSymbol); + sub.ecoinNum =QString::number(txout.tokenRegLabel.totalCount); + vacc = txout.tokenRegLabel.accuracy; + } + else{ + y=(char*)(txout.tokenLabel.TokenSymbol); + sub.ecoinNum =QString::number(txout.tokenLabel.value); + vacc = txout.tokenLabel.accuracy; + } + sub.ecoinType =y; + sub.ecoinNum = getAccuracyNum(vacc,sub.ecoinNum); + sub.strstatus = FormatTxStatus(wtx); + sub.strtime =FormatTxTime(wtx); + sub.address = CBitcoinAddress(address).ToString(); + CAmount nValue = txout.nValue; + sub.credit = nValue; + sub.TxFee = 0; + parts.append(sub); + break; + } + } + + else + { + // m_notplusnOut++; + // if(m_notplusnOut == (wtx.tx->vout.size()-m_isplusnOut)) + { + // parts.append(m_parts); + } + + } + } + } + } + + + return parts; +} + +void TransactionRecord::updateStatus(const CWalletTx &wtx) +{ + AssertLockHeld(cs_main); + // Determine transaction status + + // Find the block the tx is in + CBlockIndex* pindex = NULL; + BlockMap::iterator mi = mapBlockIndex.find(wtx.hashBlock); + if (mi != mapBlockIndex.end()) + pindex = (*mi).second; + + // Sort order, unrecorded transactions sort to the top + status.sortKey = strprintf("%010d-%01d-%010u-%03d", + (pindex ? pindex->nHeight : std::numeric_limits::max()), + (wtx.IsCoinBase() ? 1 : 0), + wtx.nTimeReceived, + idx); + status.countsForBalance = wtx.IsTrusted() && !(wtx.GetBlocksToMaturity() > 0); + status.depth = wtx.GetDepthInMainChain(); + status.cur_num_blocks = chainActive.Height(); + + if (!CheckFinalTx(wtx)) + { + if (wtx.tx->nLockTime < LOCKTIME_THRESHOLD) + { + status.status = TransactionStatus::OpenUntilBlock; + status.open_for = wtx.tx->nLockTime - chainActive.Height(); + } + else + { + status.status = TransactionStatus::OpenUntilDate; + status.open_for = wtx.tx->nLockTime; + } + } + // For generated transactions, determine maturity + else if(type == TransactionRecord::Generated) + { + if (wtx.GetBlocksToMaturity() > 0) + { + status.status = TransactionStatus::Immature; + + if (wtx.IsInMainChain()) + { + status.matures_in = wtx.GetBlocksToMaturity(); + + // Check if the block was requested by anyone + if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) + status.status = TransactionStatus::MaturesWarning; + } + else + { + status.status = TransactionStatus::NotAccepted; + } + } + else + { + status.status = TransactionStatus::Confirmed; + } + } + else + { + if (status.depth < 0) + { + status.status = TransactionStatus::Conflicted; + } + else if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) + { + status.status = TransactionStatus::Offline; + } + else if (status.depth == 0) + { + status.status = TransactionStatus::Unconfirmed; + if (wtx.isAbandoned()) + status.status = TransactionStatus::Abandoned; + } + else if (status.depth < RecommendedNumConfirmations) + { + status.status = TransactionStatus::Confirming; + } + else + { + status.status = TransactionStatus::Confirmed; + } + } + +} + +bool TransactionRecord::statusUpdateNeeded() +{ + AssertLockHeld(cs_main); + return status.cur_num_blocks != chainActive.Height(); +} + +QString TransactionRecord::getTxID() const +{ + return QString::fromStdString(hash.ToString()); +} + +int TransactionRecord::getOutputIndex() const +{ + return idx; +} +//QString TransactionRecord::getstrStatus() +//int TransactionRecord::getstrStatus() +QString TransactionRecord::getstrStatus() +{ + return strstatus;//QString::fromStdString(strstatus); +} + +QString TransactionRecord::getecoinType() +{ + return QString::fromStdString(ecoinType); +} +QString TransactionRecord::getIPCTitle() +{ + return QString::fromStdString(ipcTitle); +} +uint8_t TransactionRecord::getIPCType() +{ + return ipcType; +} + +uint8_t TransactionRecord::getType() +{ + return type; +} diff --git a/.svn/pristine/3d/3dc97ad78933564188ac87bec75a8a9b1ff2f1b7.svn-base b/.svn/pristine/3d/3dc97ad78933564188ac87bec75a8a9b1ff2f1b7.svn-base new file mode 100644 index 0000000..146c16b --- /dev/null +++ b/.svn/pristine/3d/3dc97ad78933564188ac87bec75a8a9b1ff2f1b7.svn-base @@ -0,0 +1,81 @@ +#include "unionacounthistorydetail.h" +#include "forms/ui_unionacounthistorydetail.h" +#include "ipchainunits.h" +#include "util.h" +#include "log/log.h" +#include "walletmodel.h" +extern std::map vCoins; +unionacounthistorydetail::unionacounthistorydetail(QWidget *parent) : + QWidget(parent), + ui(new Ui::unionacounthistorydetail) +{ + ui->setupUi(this); +} + +unionacounthistorydetail::~unionacounthistorydetail() +{ + delete ui; +} +void unionacounthistorydetail::setinfo(std::string add, CAmount fee,bool isSend,CAmount num,QString status,QString strtime,QString txid) +{ + m_txid = txid; + ui->label_add->setText(QString::fromStdString(add)); + ui->textEdit->setText("-"+BitcoinUnits::formatWithUnit(0, num, false, BitcoinUnits::separatorAlways)); + ui->label_date->setText(strtime); + uint256 rv; + rv.SetHex(m_txid.toStdString()); + auto itor = vCoins.find(rv); + if(itor!= vCoins.end()){ + status = m_walletmodel->FormatTxStatus(*(itor->second)); + } + onmessagetra(status); + //ui->label_info->setText(QString::fromStdString(_(status.toStdString().c_str()))); + ui->label_fee->setText(BitcoinUnits::formatWithUnit(0, fee, false, BitcoinUnits::separatorAlways)); + +} + +void unionacounthistorydetail::onmessagetra(QString &status) +{ + LOG_WRITE(LOG_INFO,"STATUS",status.toStdString().c_str()); + if(status.indexOf("Open")!=-1) + { + int i = status.indexOf("Open until"); + QString s1= status.mid(i,-1); + ui->label_info->setText(tr("Open until") + s1); + } + else if(status.indexOf("conflicted")!=-1) + { + int i = status.indexOf("conflicted with a transaction with"); + QString s1= status.mid(i,-1); + ui->label_info->setText(tr("conflicted with a transaction with") + s1); + } + else if(status.indexOf("offline")!=-1) + { + int i = status.indexOf("offline"); + QString s1= status.mid(0,i); + ui->label_info->setText(s1+ tr("offline")); + } + else if(status.indexOf("unconfirmed") !=-1) + { + int i = status.indexOf("unconfirmed"); + QString s1= status.mid(0,i); + ui->label_info->setText(s1+ tr("unconfirmed")); + } + else if(status.indexOf("confirmations") != -1) + { + int i = status.indexOf("confirmations"); + QString s1= status.mid(0,i); + LOG_WRITE(LOG_INFO,"confirmations",s1.toStdString().c_str()); + ui->label_info->setText(s1+ tr("confirmations")); + } + else + ui->label_info->setText(tr("unconfirmed")); +} +void unionacounthistorydetail::on_btn_back_pressed() +{ + Q_EMIT unionPage_back(); +} +void unionacounthistorydetail::setModel(WalletModel *_model) +{ + this->m_walletmodel = _model; +} diff --git a/.svn/pristine/42/4223454f6920d449cb69984f4fbd79239be45116.svn-base b/.svn/pristine/42/4223454f6920d449cb69984f4fbd79239be45116.svn-base new file mode 100644 index 0000000..bcf2f23 --- /dev/null +++ b/.svn/pristine/42/4223454f6920d449cb69984f4fbd79239be45116.svn-base @@ -0,0 +1,188 @@ +#include "unionaccounttrasign.h" +#include "ui_unionaccounttrasign.h" +#include "log/log.h" +#include +#include "util.h" +#include "ipchainunits.h" +#ifdef ENABLE_WALLET +#include "walletmodel.h" +#endif +unionaccounttrasign::unionaccounttrasign(QWidget *parent) : + QWidget(parent), + ui(new Ui::unionaccounttrasign) +{ + ui->setupUi(this); +} + +unionaccounttrasign::~unionaccounttrasign() +{ + delete ui; +} +void unionaccounttrasign::set0Text() +{ + ui->label_newsignaturestring->hide(); + ui->textEdit_newsignaturestring->hide(); + ui->textEdit->clear(); + ui->signBtn->show(); + ui->label_err->setText(""); + ui->label_tip->setText(""); + ui->label_add->setVisible(false); + ui->label_num->setVisible(false); + ui->m_address->setVisible(false); + ui->m_num->setVisible(false); + ui->m_address->setText(""); + ui->m_num->setText(""); +} +void unionaccounttrasign::setModel(WalletModel *_model) +{ + this->model = _model; +} +void unionaccounttrasign::setMsgDlgPlace(CMessageBox* pmsgdlg) +{ + QDesktopWidget* desktopWidget = QApplication::desktop(); + QRect applicationRect = desktopWidget->screenGeometry(); + QRect rectgeometry = QApplication::desktop()->geometry(); + QPoint xy = mapToGlobal(mapToParent(mapToParent(this->pos()))); + pmsgdlg->move(applicationRect.x()+1000/2-524/2+xy.x(),applicationRect.y()+660/2-287/2+xy.y()); + + +} +void unionaccounttrasign::on_signBtn_pressed() +{ + ui->label_err->setText(""); + ui->label_tip->setText(""); + if(!getSignInfo()){ + return; + } + std::string strtx = ui->textEdit->document()->toPlainText().toStdString().c_str(); + if("" == strtx) + { + ui->label_err->setText(tr("input info")); + return; + } + if(!model->CheckPassword()) + { + ui->label_err->setText(tr("Password error.")); + LOG_WRITE(LOG_INFO,"on_signBtn_pressed Password error."); + return; + } + WalletModel::UnlockContext ctx(model, true, true); + std::string strFailReason; + ScriptError serror; + std::string strtxout; + CMutableTransaction mergedTx; + if(model->commitUnionaccounttra( strtx, strFailReason,serror,strtxout,mergedTx)) + { + if(serror == SCRIPT_ERR_OK) + { + CMessageBox msg; + setMsgDlgPlace(&msg); + msg.setIsClose(false); + msg.setMessage(5); + msg.exec(); + if(0 == msg.m_issend) + { + LOG_WRITE(LOG_INFO,"return"); + //return; + } + else + { + if(model->commitUnionaccounttra_plus(mergedTx,strFailReason)) + { + ui->label_err->setText(tr("success")); + ui->label_tip->setText(tr("txid")+(" ")+ QString::fromStdString(strtxout)); + LOG_WRITE(LOG_INFO,"SIGN sign commitUnionaccounttra OK ",strFailReason.c_str()); + // Q_EMIT opensignsuccessPage(); + ui->signBtn->hide(); + } + else + { + LOG_WRITE(LOG_INFO,"commitUnionaccounttra_plus FAILED",strFailReason.c_str()); + if("bad-txns-inputs-spent"==strFailReason) + ui->label_err->setText(tr("sign error")+(" ")+tr("bad-txns-inputs-spent")); + else if("txn-already-in-mempool"==strFailReason) + ui->label_err->setText(tr("sign error")+(" ")+tr("txn-already-in-mempool")); + else if("txn-already-known"==strFailReason) + ui->label_err->setText(tr("sign error")+(" ")+tr("txn-already-known")); + else + ui->label_err->setText(tr("sign error")+(" ")+QString::fromStdString(strFailReason)); + } + } + } + else + { + ui->label_err->setText(tr("sign successful send the newly signature to next friend.")); + ui->textEdit_newsignaturestring->setText(QString::fromStdString(strtxout)); + ui->label_newsignaturestring->show(); + ui->textEdit_newsignaturestring->show(); + ui->signBtn->hide(); + //ui->textEdit->setText(tr("sign string")+ QString::fromStdString(strtxout)); + LOG_WRITE(LOG_INFO,"SIGN commitUnionaccounttra error"); + } + } + else + { + ui->label_err->setText(tr("sign error")); + } + +} + + + +void unionaccounttrasign::on_backbtn_pressed() +{ + Q_EMIT backtotraPage(); +} + +void unionaccounttrasign::on_btn_sign_pressed() +{ + getSignInfo(); +} +bool unionaccounttrasign::getSignInfo() +{ + ui->label_err->setText(tr("")); + std::string strFailReason = ""; + std::string address = ""; + CAmount money = 0; + int haveSigned =0; + std::string sourceaddress = ""; + std::string strtx = ui->textEdit->document()->toPlainText().toStdString().c_str(); + + if(model->analyTransaction(strtx,strFailReason,address,money,haveSigned,sourceaddress)) + { + ui->label_add->setVisible(true); + ui->label_num->setVisible(true); + ui->m_address->setVisible(true); + ui->m_num->setVisible(true); + ui->m_address->setText(QString::fromStdString(address)); + ui->m_num->setText(BitcoinUnits::formatWithUnit(0, money, false, BitcoinUnits::separatorAlways)); + LOG_WRITE(LOG_INFO,"getSignInfo sourceaddress:",sourceaddress.c_str(),\ + " m_strSourceaddress:",m_strSourceaddress.c_str()); + if(sourceaddress!=""&&m_strSourceaddress!=""&&m_strSourceaddress!=sourceaddress){ + ui->label_err->setText(tr("Account mismatch.")); + return false; + } + return true; + } + else + { + if("DecodeHexTx failed" == strFailReason) + { + ui->label_err->setText(tr("DecodeHexTx failed")); + } + else if("vout.size too larger" == strFailReason) + { + ui->label_err->setText(tr("vout.size too larger")); + } + else if("vout.size failed" == strFailReason) + { + ui->label_err->setText(tr("vout.size failed")); + } + else + { + ui->label_err->setText(tr("resolve failed")); + } + return false; + } +} + diff --git a/.svn/pristine/42/42e825cf50bffc05a7dadc8efaee1cb14abb4586.svn-base b/.svn/pristine/42/42e825cf50bffc05a7dadc8efaee1cb14abb4586.svn-base new file mode 100644 index 0000000..31ca849 --- /dev/null +++ b/.svn/pristine/42/42e825cf50bffc05a7dadc8efaee1cb14abb4586.svn-base @@ -0,0 +1,5597 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2009-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "amount.h" +#include "base58.h" +#include "chain.h" +#include "consensus/validation.h" +#include "core_io.h" +#include "init.h" +#include "validation.h" +#include "net.h" +#include "policy/policy.h" +#include "policy/rbf.h" +#include "rpc/server.h" +#include "script/sign.h" +#include "timedata.h" +#include "util.h" +#include "utilmoneystr.h" +#include "wallet.h" +#include "walletdb.h" + +#include + +#include + +#include + +#include "script/ismine.h" +#include "dpoc/DpocInfo.h" +#include "dpoc/ConsensusAccountPool.h" + + +using namespace std; + +int64_t nWalletUnlockTime; +static CCriticalSection cs_nWalletUnlockTime; +extern bool b_TestTxLarge; +std::string HelpRequiringPassphrase() +{ + return pwalletMain && pwalletMain->IsCrypted() + ? "\nRequires wallet passphrase to be set with walletpassphrase call." + : ""; +} + +bool EnsureWalletIsAvailable(bool avoidException) +{ + if (!pwalletMain) + { + if (!avoidException) + throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)"); + else + return false; + } + return true; +} + +void EnsureWalletIsUnlocked() +{ + if (pwalletMain->IsLocked()) + throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first."); +} + +void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) +{ + int confirms = wtx.GetDepthInMainChain(); + entry.push_back(Pair("confirmations", confirms)); + if (wtx.IsCoinBase()) + entry.push_back(Pair("generated", true)); + if (confirms > 0) + { + entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex())); + entry.push_back(Pair("blockindex", wtx.nIndex)); + entry.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime())); + } else { + entry.push_back(Pair("trusted", wtx.IsTrusted())); + } + uint256 hash = wtx.GetHash(); + entry.push_back(Pair("txid", hash.GetHex())); + UniValue conflicts(UniValue::VARR); + BOOST_FOREACH(const uint256& conflict, wtx.GetConflicts()) + conflicts.push_back(conflict.GetHex()); + entry.push_back(Pair("walletconflicts", conflicts)); + entry.push_back(Pair("time", wtx.GetTxTime())); + entry.push_back(Pair("timereceived", (int64_t)wtx.nTimeReceived)); + + // Add opt-in RBF status + std::string rbfStatus = "no"; + if (confirms <= 0) { + LOCK(mempool.cs); + RBFTransactionState rbfState = IsRBFOptIn(wtx, mempool); + if (rbfState == RBF_TRANSACTIONSTATE_UNKNOWN) + rbfStatus = "unknown"; + else if (rbfState == RBF_TRANSACTIONSTATE_REPLACEABLE_BIP125) + rbfStatus = "yes"; + } + entry.push_back(Pair("bip125-replaceable", rbfStatus)); + + BOOST_FOREACH(const PAIRTYPE(string,string)& item, wtx.mapValue) + entry.push_back(Pair(item.first, item.second)); +} + +string AccountFromValue(const UniValue& value) +{ + string strAccount = value.get_str(); + if (strAccount == "*") + throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Invalid account name"); + return strAccount; +} + +UniValue getnewaddress(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() > 1) + throw runtime_error( + "getnewaddress ( \"account\" )\n" + "\nReturns a new ipchain address for receiving payments.\n" + "If 'account' is specified (DEPRECATED), it is added to the address book \n" + "so payments received with the address will be credited to 'account'.\n" + "\nArguments:\n" + "1. \"account\" (string, optional) \"\" \n" + "\nResult:\n" + "\"address\" (string) The new ipchain address\n" + "\nExamples:\n" + + HelpExampleCli("getnewaddress", "") + + HelpExampleRpc("getnewaddress", "") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + // Parse the account first so we don't generate a key if there's an error + string strAccount; + if (request.params.size() > 0) + strAccount = AccountFromValue(request.params[0]); + + if (!pwalletMain->IsLocked()) + pwalletMain->TopUpKeyPool(); + + // Generate a new key that is added to wallet + CPubKey newKey; + if (!pwalletMain->GetKeyFromPool(newKey)) + throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); + CKeyID keyID = newKey.GetID(); + + pwalletMain->SetAddressBook(keyID, "", "receive"); + + return CBitcoinAddress(keyID).ToString(); +} + + +CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) +{ + CPubKey pubKey; + if (!pwalletMain->GetAccountPubkey(pubKey, strAccount, bForceNew)) { + throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); + } + + return CBitcoinAddress(pubKey.GetID()); +} + +UniValue getaccountaddress(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "getaccountaddress \"account\"\n" + "\nDEPRECATED. Returns the current IPChain address for receiving payments to this account.\n" + "\nArguments:\n" + "1. \"account\" (string, required) The account name for the address. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created and a new address created if there is no account by the given name.\n" + "\nResult:\n" + "\"address\" (string) The account IPChain address\n" + "\nExamples:\n" + + HelpExampleCli("getaccountaddress", "") + + HelpExampleCli("getaccountaddress", "\"\"") + + HelpExampleCli("getaccountaddress", "\"myaccount\"") + + HelpExampleRpc("getaccountaddress", "\"myaccount\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + // Parse the account first so we don't generate a key if there's an error + string strAccount = AccountFromValue(request.params[0]); + + UniValue ret(UniValue::VSTR); + + ret = GetAccountAddress(strAccount).ToString(); + return ret; +} + + +UniValue getrawchangeaddress(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() > 1) + throw runtime_error( + "getrawchangeaddress\n" + "\nReturns a new Ipchain address, for receiving change.\n" + "This is for use with raw transactions, NOT normal use.\n" + "\nResult:\n" + "\"address\" (string) The address\n" + "\nExamples:\n" + + HelpExampleCli("getrawchangeaddress", "") + + HelpExampleRpc("getrawchangeaddress", "") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + if (!pwalletMain->IsLocked()) + pwalletMain->TopUpKeyPool(); + + CReserveKey reservekey(pwalletMain); + CPubKey vchPubKey; + if (!reservekey.GetReservedKey(vchPubKey)) + throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); + + reservekey.KeepKey(); + + CKeyID keyID = vchPubKey.GetID(); + + return CBitcoinAddress(keyID).ToString(); +} + + +UniValue setaccount(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) + throw runtime_error( + "setaccount \"address\" \"account\"\n" + "\nDEPRECATED. Sets the account associated with the given address.\n" + "\nArguments:\n" + "1. \"address\" (string, required) The ipchain address to be associated with an account.\n" + "2. \"account\" (string, required) The account to assign the address to.\n" + "\nExamples:\n" + + HelpExampleCli("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"tabby\"") + + HelpExampleRpc("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"tabby\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + CBitcoinAddress address(request.params[0].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Ipchain address"); + + string strAccount; + if (request.params.size() > 1) + strAccount = AccountFromValue(request.params[1]); + + // Only add the account if the address is yours. + if (IsMine(*pwalletMain, address.Get())) + { + // Detect when changing the account of an address that is the 'unused current key' of another account: + if (pwalletMain->mapAddressBook.count(address.Get())) + { + string strOldAccount = pwalletMain->mapAddressBook[address.Get()].name; + if (address == GetAccountAddress(strOldAccount)) + GetAccountAddress(strOldAccount, true); + } + pwalletMain->SetAddressBook(address.Get(), strAccount, "receive"); + } + else + throw JSONRPCError(RPC_MISC_ERROR, "setaccount can only be used with own address"); + + return NullUniValue; +} + + +UniValue getaccount(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "getaccount \"address\"\n" + "\nDEPRECATED. Returns the account associated with the given address.\n" + "\nArguments:\n" + "1. \"address\" (string, required) The ipchain address for account lookup.\n" + "\nResult:\n" + "\"accountname\" (string) the account address\n" + "\nExamples:\n" + + HelpExampleCli("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"") + + HelpExampleRpc("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + CBitcoinAddress address(request.params[0].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Ipchain address"); + + string strAccount; + map::iterator mi = pwalletMain->mapAddressBook.find(address.Get()); + if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.name.empty()) + strAccount = (*mi).second.name; + return strAccount; +} + + +UniValue getaddressesbyaccount(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "getaddressesbyaccount \"account\"\n" + "\nDEPRECATED. Returns the list of addresses for the given account.\n" + "\nArguments:\n" + "1. \"account\" (string, required) The account name.\n" + "\nResult:\n" + "[ (json array of string)\n" + " \"address\" (string) a ipchain address associated with the given account\n" + " ,...\n" + "]\n" + "\nExamples:\n" + + HelpExampleCli("getaddressesbyaccount", "\"tabby\"") + + HelpExampleRpc("getaddressesbyaccount", "\"tabby\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + string strAccount = AccountFromValue(request.params[0]); + + // Find all addresses that have the given account + UniValue ret(UniValue::VARR); + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwalletMain->mapAddressBook) + { + const CBitcoinAddress& address = item.first; + const string& strName = item.second.name; + if (strName == strAccount) + ret.push_back(address.ToString()); + } + return ret; +} + +UniValue setTesttx(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + if (b_TestTxLarge) + b_TestTxLarge = false; + else + b_TestTxLarge = true; + + return b_TestTxLarge; +} +static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew) +{ + CAmount curBalance = pwalletMain->GetBalance(); + + // Check amount + if (nValue <= 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount"); + + if (nValue > curBalance) + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds"); + + if (pwalletMain->GetBroadcastTransactions() && !g_connman) + throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); + + // Parse Ipchain address + CScript scriptPubKey = GetScriptForDestination(address); + + // Create and send the transaction + CReserveKey reservekey(pwalletMain); + CAmount nFeeRequired; + std::string strError; + vector vecSend; + int nChangePosRet = -1; + CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount}; + vecSend.push_back(recipient); + if (!pwalletMain->CreateNormalTransaction(vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError)) { + if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance) + strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired)); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } + CValidationState state; + if (!pwalletMain->CommitTransaction(wtxNew, reservekey, g_connman.get(), state)) { + std::cout << "error transaction id=" << wtxNew.GetHash().GetHex() << "\n"; + strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason()); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } +} + +UniValue sendtoaddress(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 2 || request.params.size() > 5) + throw runtime_error( + "sendtoaddress \"address\" amount ( \"comment\" \"comment_to\" subtractfeefromamount )\n" + "\nSend an amount to a given address.\n" + + HelpRequiringPassphrase() + + "\nArguments:\n" + "1. \"address\" (string, required) The ipchain address to send to.\n" + "2. \"amount\" (numeric or string, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n" + "3. \"comment\" (string, optional) A comment used to store what the transaction is for. \n" + " This is not part of the transaction, just kept in your wallet.\n" + "4. \"comment_to\" (string, optional) A comment to store the name of the person or organization \n" + " to which you're sending the transaction. This is not part of the \n" + " transaction, just kept in your wallet.\n" + "5. subtractfeefromamount (boolean, optional, default=false) The fee will be deducted from the amount being sent.\n" + " The recipient will receive less ipchains than you enter in the amount field.\n" + "\nResult:\n" + "\"txid\" (string) The transaction id.\n" + "\nExamples:\n" + + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1") + + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"") + + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"\" \"\" true") + + HelpExampleRpc("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + CBitcoinAddress address(request.params[0].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Ipchain address"); + + // Amount + CAmount nAmount = AmountFromValue(request.params[1]); + if (nAmount <= 0) + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); + + // Wallet comments + CWalletTx wtx; + if (request.params.size() > 2 && !request.params[2].isNull() && !request.params[2].get_str().empty()) + wtx.mapValue["comment"] = request.params[2].get_str(); + if (request.params.size() > 3 && !request.params[3].isNull() && !request.params[3].get_str().empty()) + wtx.mapValue["to"] = request.params[3].get_str(); + + bool fSubtractFeeFromAmount = false; + if (request.params.size() > 4) + fSubtractFeeFromAmount = request.params[4].get_bool(); + + EnsureWalletIsUnlocked(); + + SendMoney(address.Get(), nAmount, fSubtractFeeFromAmount, wtx); + + return wtx.GetHash().GetHex(); +} + +//add by xxy +//General trading +static void NormalSendMoney(const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew) +{ + CAmount curBalance = pwalletMain->GetBalance(); + + // Check amount + if (nValue <= 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount"); + + if (nValue > curBalance) + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds"); + + if (pwalletMain->GetBroadcastTransactions() && !g_connman) + throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); + + // Parse Ipchain address + CScript scriptPubKey = GetScriptForDestination(address); + + // Create and send the transaction + CReserveKey reservekey(pwalletMain); + CAmount nFeeRequired; + std::string strError; + vector vecSend; + int nChangePosRet = -1; + CRecipient recipient = { scriptPubKey, nValue, fSubtractFeeFromAmount }; + vecSend.push_back(recipient); + if (!pwalletMain->CreateNormalTransaction(vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError)) { + if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance) + { + std::cout << "nFeeRequired" << nFeeRequired << std::endl; + strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired)); + } + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } + CValidationState state; + if (!pwalletMain->CommitTransaction(wtxNew, reservekey, g_connman.get(), state)) { + strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason()); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } +} + + +UniValue NormalSendToAddress(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 2 || request.params.size() > 5) + throw runtime_error( + "NormalSendToAddress \"address\" amount ( \"comment\" \"comment_to\" subtractfeefromamount )\n" + "\nSend an amount to a given address.\n" + + HelpRequiringPassphrase() + + "\nArguments:\n" + "1. \"address\" (string, required) The ipchain address to send to.\n" + "2. \"amount\" (numeric or string, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n" + "3. \"comment\" (string, optional) A comment used to store what the transaction is for. \n" + " This is not part of the transaction, just kept in your wallet.\n" + "4. \"comment_to\" (string, optional) A comment to store the name of the person or organization \n" + " to which you're sending the transaction. This is not part of the \n" + " transaction, just kept in your wallet.\n" + "5. subtractfeefromamount (boolean, optional, default=false) The fee will be deducted from the amount being sent.\n" + " The recipient will receive less ipchains than you enter in the amount field.\n" + "\nResult:\n" + "\"txid\" (string) The transaction id.\n" + "\nExamples:\n" + + HelpExampleCli("NormalSendToAddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1") + + HelpExampleCli("NormalSendToAddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"") + + HelpExampleCli("NormalSendToAddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"\" \"\" true") + + HelpExampleRpc("NormalSendToAddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + CBitcoinAddress address(request.params[0].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Ipchain address"); + + // Amount + CAmount nAmount = AmountFromValue(request.params[1]); + if (nAmount <= 0) + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); + + // Wallet comments + CWalletTx wtx; + if (request.params.size() > 2 && !request.params[2].isNull() && !request.params[2].get_str().empty()) + wtx.mapValue["comment"] = request.params[2].get_str(); + if (request.params.size() > 3 && !request.params[3].isNull() && !request.params[3].get_str().empty()) + wtx.mapValue["to"] = request.params[3].get_str(); + + bool fSubtractFeeFromAmount = false; + if (request.params.size() > 4) + fSubtractFeeFromAmount = request.params[4].get_bool(); + + EnsureWalletIsUnlocked(); + + NormalSendMoney(address.Get(), nAmount, fSubtractFeeFromAmount, wtx); + + return wtx.GetHash().GetHex(); +} +static void MultiNormalSendMoney(const CTxDestination &address, std::string& straddress, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew, ScriptError& serror, std::string& strtx) +{ + std::map moneynums; + moneynums.clear(); + CAmount namount = 0; + moneynums.insert(pair(straddress, namount)); + pwalletMain->AvailableUnionCoins(moneynums); + CAmount curBalance = moneynums[straddress]; + std::cout << "curBalance = " << straddress << "/" << curBalance << std::endl; + + // Check amount + if (nValue <= 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount"); + + if (nValue > curBalance) + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds"); + + if (pwalletMain->GetBroadcastTransactions() && !g_connman) + throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); + + // Parse Bitcoin address + CScript scriptPubKey = GetScriptForDestination(address); + + // Create and send the transaction + CReserveKey reservekey(pwalletMain); + CAmount nFeeRequired; + std::string strError; + + vector vecSend; + int nChangePosRet = -1; + CRecipient recipient = { scriptPubKey, nValue, fSubtractFeeFromAmount }; + vecSend.push_back(recipient); + if (!pwalletMain->CreateMultiTransaction(straddress, vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError, serror, strtx)) { + if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance) + { + std::cout << "nFeeRequired" << nFeeRequired << std::endl; + strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired)); + } + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } + if (SCRIPT_ERR_OK != serror) + return; + CValidationState state; + if (!pwalletMain->CommitTransaction(wtxNew, reservekey, g_connman.get(), state)) { + strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason()); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } +} +UniValue sendtomultiaddress(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 3 || request.params.size() > 6) + throw runtime_error( + "sendtomultiaddress \"address\" amount ( \"comment\" \"comment_to\" subtractfeefromamount )\n" + "\nSend an amount to a given address.\n" + + HelpRequiringPassphrase() + + "\nArguments:\n" + "1. \"toaddress\" (string, required) The bitcoin address where want to send to.\n" + "2. \"fromaddress\" (string, required) The bitcoin address(p2sh) send from.\n" + "3. \"amount\" (numeric or string, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n" + "4. \"comment\" (string, optional) A comment used to store what the transaction is for. \n" + " This is not part of the transaction, just kept in your wallet.\n" + "5. \"comment_to\" (string, optional) A comment to store the name of the person or organization \n" + " to which you're sending the transaction. This is not part of the \n" + " transaction, just kept in your wallet.\n" + "6. subtractfeefromamount (boolean, optional, default=false) The fee will be deducted from the amount being sent.\n" + " The recipient will receive less bitcoins than you enter in the amount field.\n" + "\nResult:\n" + "\"txid\" (string) The transaction id.\n" + "\nExamples:\n" + + HelpExampleCli("sendtomultiaddress", "\"2M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1") + + HelpExampleCli("sendtomultiaddress", "\"2M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"") + + HelpExampleCli("sendtomultiaddress", "\"2M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"\" \"\" true") + + HelpExampleRpc("sendtomultiaddress", "\"2M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + std::string strmultiaddress = request.params[1].get_str(); + CBitcoinAddress address(request.params[0].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); + + // Amount + CAmount nAmount = AmountFromValue(request.params[2]); + if (nAmount <= 0) + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); + + // Wallet comments + CWalletTx wtx; + if (request.params.size() > 3 && !request.params[3].isNull() && !request.params[2].get_str().empty()) + wtx.mapValue["comment"] = request.params[3].get_str(); + if (request.params.size() > 4 && !request.params[4].isNull() && !request.params[3].get_str().empty()) + wtx.mapValue["to"] = request.params[4].get_str(); + + bool fSubtractFeeFromAmount = false; + if (request.params.size() > 5) + fSubtractFeeFromAmount = request.params[5].get_bool(); + + ScriptError serror = SCRIPT_ERR_ERROR_COUNT; + std::string strtx; + EnsureWalletIsUnlocked(); + + MultiNormalSendMoney(address.Get(), strmultiaddress, nAmount, fSubtractFeeFromAmount, wtx, serror,strtx); + + std::cout << "serror = " << serror << std::endl; + if (SCRIPT_ERR_OK == serror) + { + return wtx.GetHash().GetHex(); + } + else + return strtx; + +} + +UniValue signmultitx(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() > 1) + throw runtime_error( + "signmultitx \"strtx\" \n" + "\nSign the hexstr of the multitx.\n" + + HelpRequiringPassphrase() + + "\nArguments:\n" + "1. \"strtx\" (string, required) The hexstr of the multitx.\n" + "\nResult:\n" + "\"txid\" (string) The transaction id or strtxout.\n" + "\nExamples:\n" + + HelpExampleCli("signmultitx", "\"000000000000000000000000000000000000000000000000000000000000\" ") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + std::string strtx = request.params[0].get_str(); + ScriptError serror = SCRIPT_ERR_ERROR_COUNT; + std::string strError; + std::string strtxout; + CMutableTransaction mergedTx; + if (!pwalletMain->SignMultiTransaction(strtx, strError, serror, strtxout,mergedTx,1)) + { + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } + + return strtxout; +} + +//IPC Reg Tx +static void IPCRegSendMoney(std::string strReglabel,const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew) +{ + CAmount curBalance = pwalletMain->GetBalance(); + + // Check amount + if (nValue < 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount"); + + if (nValue > curBalance) + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds"); + + if (pwalletMain->GetBroadcastTransactions() && !g_connman) + throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); + + // Parse Ipchain address + CScript scriptPubKey = GetScriptForDestination(address); + + // Create and send the transaction + CReserveKey reservekey(pwalletMain); + CAmount nFeeRequired; + std::string strError; + vector vecSend; + int nChangePosRet = -1; + CRecipient recipient = { scriptPubKey, nValue, fSubtractFeeFromAmount }; + vecSend.push_back(recipient); + if (!pwalletMain->CreateIPCRegTransaction(strReglabel, vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError)) { + if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance) + strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired)); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } + CValidationState state; + if (!pwalletMain->CommitTransaction(wtxNew, reservekey, g_connman.get(), state)) { + strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason()); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } +} + + +UniValue IPCRegisterToAddress(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 2 || request.params.size() > 2) + throw runtime_error( + "IPCRegisterToAddress \"address\" \"icplabel\" \n" + "\nSend an amount to a given address.\n" + + HelpRequiringPassphrase() + + "\nArguments:\n" + "1. \"address\" (string, required) The ipchain address to send to.\n" + "2. \"icplabel\" (string) ipclabel...\n" + "\nResult:\n" + "\"txid\" (string) The transaction id.\n" + "\nExamples:\n" + + HelpExampleCli("IPCRegisterToAddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" \"{\"ExtendType\":1,\"startTime\":0,\"stopTime\":0,\"reAuthorize\":1,\"uniqueAuthorize\":0,\"hashLen\":16,\"hash\":\"cec3144f63c09aa6e2dc03c370f339c1\",\"labelTitle\":\"Animals\",\"txLabel\":\"zhichan\"}\"") + + HelpExampleRpc("IPCRegisterToAddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" \"{\"ExtendType\":1,\"startTime\":0,\"stopTime\":0,\"reAuthorize\":1,\"uniqueAuthorize\":0,\"hashLen\":16,\"hash\":\"cec3144f63c09aa6e2dc03c370f339c1\",\"labelTitle\":\"Animals\",\"txLabel\":\"zhichan\"}\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + CBitcoinAddress address(request.params[0].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Ipchain address"); + + // Amount + CAmount nAmount = 0; + CWalletTx wtx; + std::string strReglabel = ""; + if (request.params.size() > 1 && !request.params[1].isNull() && !request.params[1].get_str().empty()) + strReglabel = request.params[1].get_str(); + + bool fSubtractFeeFromAmount = false; + + EnsureWalletIsUnlocked(); + + IPCRegSendMoney(strReglabel, address.Get(), nAmount, fSubtractFeeFromAmount, wtx); + + return wtx.GetHash().GetHex(); +} + +//IPCSend Transaction +static void IPCSdSendMoney(std::string& txid,int Index,const CTxDestination &address,CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew) +{ + CAmount curBalance = pwalletMain->GetBalance(); + + // Check amount + if (nValue < 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount"); + + if (nValue > curBalance) + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds"); + + if (pwalletMain->GetBroadcastTransactions() && !g_connman) + throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); + + // Parse Ipchain address + CScript scriptPubKey = GetScriptForDestination(address); + + // Create and send the transaction + CReserveKey reservekey(pwalletMain); + CAmount nFeeRequired; + std::string strError; + vector vecSend; + int nChangePosRet = -1; + CRecipient recipient = { scriptPubKey, nValue, fSubtractFeeFromAmount }; + vecSend.push_back(recipient); + + if (!pwalletMain->CreateIPCSendTransaction(txid,Index,vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError)) { + if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance) + strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired)); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } + CValidationState state; + if (!pwalletMain->CommitTransaction(wtxNew, reservekey, g_connman.get(), state)) { + strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason()); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } +} + + +UniValue IPCSendToAddress(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 3 || request.params.size() > 3) + throw runtime_error( + "IPCSendToAddress \"txid\" \"index\" \"address\" \n" + "\nSend an amount to a given address.\n" + + HelpRequiringPassphrase() + + "\nArguments:\n" + "1. \"txid\" (string) The transaction id of putin.\n" + "2. \"index\" (string)The id of preVout.\n" + "3. \"address\" (string, required) The ipchain address to send to.\n" + "\nResult:\n" + "\"txid\" (string) The transaction id.\n" + "\nExamples:\n" + + HelpExampleCli("IPCSendToAddress", "6c923f68ec77f8bc013c4fbac06400935ef5f4f6555c8daf23c0a87dad3a7e06" "0" "\"TCBLXa2cUaEJXjcNSRTqNHocZ7up4YitRF6r\" ") + + HelpExampleRpc("IPCSendToAddress", "6c923f68ec77f8bc013c4fbac06400935ef5f4f6555c8daf23c0a87dad3a7e06" "0" "\"TCBLXa2cUaEJXjcNSRTqNHocZ7up4YitRF6r\" ") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + std::string TXid = request.params[0].get_str(); + uint256 hash = ParseHashV(request.params[0], "parameter 1"); + if (hash.IsNull()) + { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid Ipchain txid"); + } + std::string iIndex = request.params[1].get_str(); + int Index = std::atoi(iIndex.c_str()); + if (Index < 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid prevout index"); + CBitcoinAddress address(request.params[2].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Ipchain address"); + + // Amount + CAmount nAmount = 0; + // Wallet comments + CWalletTx wtx; + bool fSubtractFeeFromAmount = false; + + + EnsureWalletIsUnlocked(); + + IPCSdSendMoney(TXid, Index, address.Get(), nAmount, fSubtractFeeFromAmount, wtx); + + return wtx.GetHash().GetHex(); +} +//IPC Authorize Transaction +static void IPCAuthorSendMoney(std::string& txid, int Index, const CTxDestination &address,std::string& strLabel, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew) +{ + CAmount curBalance = pwalletMain->GetBalance(); + + // Check amount + if (nValue <0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount"); + + if (nValue > curBalance) + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds"); + + if (pwalletMain->GetBroadcastTransactions() && !g_connman) + throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); + + // Parse Ipchain address + CScript scriptPubKey = GetScriptForDestination(address); + + // Create and send the transaction + CReserveKey reservekey(pwalletMain); + CAmount nFeeRequired; + std::string strError; + vector vecSend; + int nChangePosRet = -1; + CRecipient recipient = { scriptPubKey, nValue, fSubtractFeeFromAmount }; + vecSend.push_back(recipient); + if (!pwalletMain->CreateIPCAuthorizationTransaction(txid, Index, vecSend, strLabel, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError)) { + if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance) + strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired)); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } + CValidationState state; + if (!pwalletMain->CommitTransaction(wtxNew, reservekey, g_connman.get(), state)) { + strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason()); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } +} + + +UniValue IPCAuthorToAddress(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 4 || request.params.size() > 4) + throw runtime_error( + "IPCAuthorToAddress \"txid\" \"index\" \"address\" \"ipclabel\"\n" + "\nSend an amount to a given address.\n" + + HelpRequiringPassphrase() + + "\nArguments:\n" + "1.\"txid\" (string) The transaction id of putin.\n" + "2. \"index\" (string)The id of preVout.\n" + "3. \"address\" (string, required) The ipchain address to send to.\n" + "4. \"ipclabel\" (string).The ipclabel of IPCAuthorToAddress.\n" + "\nResult:\n" + "\"txid\" (string) The transaction id.\n" + "\nExamples:\n" + + HelpExampleCli("IPCAuthorToAddress", "6c923f68ec77f8bc013c4fbac06400935ef5f4f6555c8daf23c0a87dad3a7e06" "0" "\"TCBLXa2cUaEJXjcNSRTqNHocZ7up4YitRF6r \"" "\"{\"reAuthorize\":1,\"uniqueAuthorize\":0,\"startTime\":1508931832,\"stopTime\":1607444935}\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + std::string TXid = request.params[0].get_str(); + uint256 hash = ParseHashV(request.params[0], "parameter 1"); + if (hash.IsNull()) + { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid Ipchain txid"); + } + std::string iIndex = request.params[1].get_str(); + int Index = std::atoi(iIndex.c_str()); + if (Index < 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid prevout index"); + CBitcoinAddress address(request.params[2].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Ipchain address"); + + std::string strIPClabel = request.params[3].get_str(); + // Amount + CAmount nAmount = 0; + // Wallet comments + CWalletTx wtx; + bool fSubtractFeeFromAmount = false; + + + EnsureWalletIsUnlocked(); + + IPCAuthorSendMoney(TXid, Index, address.Get(), strIPClabel,nAmount, fSubtractFeeFromAmount, wtx); + + return wtx.GetHash().GetHex(); +} + +static void JoinCampaignCommand(const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew) +{ + CAmount curBalance = pwalletMain->GetBalance(); + + // Check amount + if (nValue <= 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount"); + + if (nValue > curBalance) + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds"); + + if (pwalletMain->GetBroadcastTransactions() && !g_connman) + throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); + + // Parse Ipchain address + //CScript scriptPubKey = GetScriptForDestination(address); + + // Create and send the transaction + CReserveKey reservekey(pwalletMain); + CAmount nFeeRequired = 0; + std::string strError; + int nChangePosRet = -1; + if (!pwalletMain->JoinCampaign(address, nValue, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError)) { + if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance) + strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired)); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } + CValidationState state; + if (!pwalletMain->CommitJoinCampaignTransaction(address, wtxNew, reservekey, g_connman.get(), state)) { + strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason()); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } +} +UniValue decodeinfobyaddress(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "decodeinfobyaddress \"address\"\n" + "\ndecode info by a address .\n" + "\nArguments:\n" + "1. \"address\" (string) The wallet address\n" + "\nExamples:\n" + "\ndecode the address\n" + + HelpExampleCli("decodeinfobyaddress", "\"address\"") + ); + CBitcoinAddress address(request.params[0].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid IPChain address"); + CKeyID keyid; + if (!address.GetKeyID(keyid)) + throw JSONRPCError(RPC_WALLET_ERROR, "Can't get CKeyID of the address£¡"); + uint160 pkhash = keyid; + CKey vchPrivKey; + if (pwalletMain->IsLocked()) + throw JSONRPCError(RPC_WALLET_ERROR, "Error: Please enter the wallet passphrase with walletpassphrase first."); + if (!pwalletMain->GetKey(keyid, vchPrivKey)) + throw JSONRPCError(RPC_WALLET_ERROR, "Can't get CKey of the address£¡"); + CPubKey pubkey = vchPrivKey.GetPubKey(); + assert(vchPrivKey.VerifyPubKey(pubkey)); + + UniValue result(UniValue::VOBJ); + result.push_back(Pair("address", address.ToString())); + result.push_back(Pair("pkhash160", pkhash.GetHex())); + result.push_back(Pair("privatekey", CBitcoinSecret(vchPrivKey).ToString())); + return result; +} +UniValue getcurdeposit(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() > 0) + throw runtime_error( + "getcurdeposit \"\" \n" + "\nget the current deposit.\n" + + HelpRequiringPassphrase() + + "\nArguments:\n" + "\nResult:\n" + "\"amount\" (string) The deposit amount.\n" + "\nExamples:\n" + + HelpExampleCli("getcurdeposit","") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + CAmount deposit = pwalletMain->GetDeposit(); + + return ValueFromAmount(deposit); +} + + +UniValue joincampaign(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() !=2) + throw runtime_error( + "joincampaign \"address\" \"amount\" \n" + "\nSend an amount to a given address.\n" + + HelpRequiringPassphrase() + + "\nArguments:\n" + "1. \"address\" (string, required) The ipchain address to send to.\n" + "2. \"amount\" (numeric or string, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n" + "\nResult:\n" + "\"txid\" (string) The transaction id.\n" + "\nExamples:\n" + + HelpExampleCli("joincampaign", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 50") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + CBitcoinAddress address(request.params[0].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Ipchain address"); + + // Amount + CAmount nAmount = AmountFromValue(request.params[1]); + if (nAmount <= 0) + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); + + // Wallet comments + CWalletTx wtx; + + bool fSubtractFeeFromAmount = false; + + EnsureWalletIsUnlocked(); + + JoinCampaignCommand(address.Get(), nAmount, fSubtractFeeFromAmount, wtx); + + return wtx.GetHash().GetHex(); +} + +static void ExitCampaignCommand(bool fSubtractFeeFromAmount, CWalletTx& wtxNew) +{ + CAmount curBalance = pwalletMain->GetBalance(); + CAmount nValue = 0; + + if (pwalletMain->GetBroadcastTransactions() && !g_connman) + throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); + + // Parse Ipchain address + // Create and send the transaction + CReserveKey reservekey(pwalletMain); + CAmount nFeeRequired; + std::string strError; + int nChangePosRet = -1; + if (!pwalletMain->ExitCampaign(wtxNew, reservekey, nFeeRequired, nChangePosRet, strError)) { + if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance) + strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired)); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } + CValidationState state; + if (!pwalletMain->CommitTransaction(wtxNew, reservekey, g_connman.get(), state)) { + strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason()); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } +} + +static void PunishRequestCommand(const CTxDestination &address, const std::string evidence, bool fSubtractFeeFromAmount, CWalletTx& wtxNew) +{ + CAmount curBalance = pwalletMain->GetBalance(); + + // Check amount + + if (pwalletMain->GetBroadcastTransactions() && !g_connman) + throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); + + // Parse Ipchain address + //CScript scriptPubKey = GetScriptForDestination(address); + + // Create and send the transaction + CReserveKey reservekey(pwalletMain); + CAmount nFeeRequired = 0; + std::string strError; + int nChangePosRet = -1; + //std::cout << "PunishRequestCommand:evidence=" << evidence << std::endl; + if (!pwalletMain->PunishRequest(address, evidence, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError)) { + if (!fSubtractFeeFromAmount && nFeeRequired > curBalance) + strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired)); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } + CValidationState state; + if (!pwalletMain->CommitTransaction(wtxNew, reservekey, g_connman.get(), state)) { + strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason()); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } +} + +UniValue punishrequest(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() != 2) + throw runtime_error( + "punishrequest \"address\" \n" + "\nSend an punish request to a given address.\n" + + HelpRequiringPassphrase() + + "\nArguments:\n" + "1. \"address\" (string, required) The ipchain address to punish to.\n" + "2. \"evidence\" (string, required) the evidence.\n" + "\nResult:\n" + "\"txid\" (string) The transaction id.\n" + "\nExamples:\n" + + HelpExampleCli("punishrequest", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" \"{¡°badblockpubtexthex¡±:¡±Reconstructs the bad block signature plaintext hex string¡±,¡°badblocksign¡±:¡±The signature field of the bad block¡±}\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + CBitcoinAddress address(request.params[0].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Ipchain address"); + + const std::string evidence = request.params[1].get_str(); + if (evidence.empty()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Evidence"); + + std::cout << "punishrequest:evidence=" << evidence << std::endl; + + // Wallet comments + CWalletTx wtx; + + bool fSubtractFeeFromAmount = false; + + EnsureWalletIsUnlocked(); + + PunishRequestCommand(address.Get(), evidence, fSubtractFeeFromAmount, wtx); + + return wtx.GetHash().GetHex(); +} + +UniValue exitcampaign(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 0) + throw runtime_error( + "exitcampaign \n" + "\exitcampaign from the address.\n" + "\nResult:\n" + "\"txid\" (string) The transaction id.\n" + "\nExamples:\n" + + HelpExampleCli("exitcampaign" ," ") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + // Wallet comments + CWalletTx wtx; + + bool fSubtractFeeFromAmount = false; + + EnsureWalletIsUnlocked(); + + ExitCampaignCommand(fSubtractFeeFromAmount, wtx); + + return wtx.GetHash().GetHex(); +} + +UniValue isdepositabled(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() < 2 || request.params.size() > 2) + throw runtime_error( + "isdepositabled \"txid\" \"index\" \n" + "\n Isadled or not of the deposit.\n" + + HelpRequiringPassphrase() + + "\nArguments:\n" + "1. \"txid\" (string) The transaction id of putin.\n" + "2. \"index\" (string)The id of preVout.\n" + "\nResult:\n" + "\"bool\" (bool) able disable.\n" + "\nExamples:\n" + + HelpExampleCli("isdepositabled", "txid" "index" ) + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + // Wallet comments + std::string TXid = request.params[0].get_str(); + uint256 hash = ParseHashV(request.params[0], "parameter 1"); + if (hash.IsNull()) + { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid Ipchain txid"); + } + std::string iIndex = request.params[1].get_str(); + int Index = std::atoi(iIndex.c_str()); + if (Index < 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid prevout index"); + CTransactionRef tx; + uint256 hashBlock; + if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string(fTxIndex ? "No such mempool or blockchain transaction" + : "No such mempool transaction. Use -txindex to enable blockchain transaction queries") + + ". Use gettransaction for wallet transactions."); + if (tx->vout[Index].txType != TXOUT_CAMPAIGN || tx->vout[Index].devoteLabel.ExtendType != TYPE_CONSENSUS_REGISTER) + throw JSONRPCError(RPC_INVALID_PARAMETER, "This is not a deposit"); + bool isAbled = CConsensusAccountPool::Instance().IsAviableUTXO(tx->GetHash()); + UniValue results(UniValue::VARR); + results.push_back(isAbled); + + return results; +} + +UniValue listreward(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + if (request.fHelp || request.params.size() != 0) + throw runtime_error( + "listreward \n" + "\nlistreward .\n" + "\nResult:\n" + "\"\" (string) the list.\n" + "\nExamples:\n" + + HelpExampleCli("listreward", " ") + ); + UniValue results(UniValue::VARR); + vector rewardtimelist; + vector rewardvaluelist; + + assert(pwalletMain != NULL); + LOCK2(cs_main, pwalletMain->cs_wallet); + { + pwalletMain->GetCurrentRewards(rewardtimelist, rewardvaluelist); + } + int listcount = rewardvaluelist.size(); + for (int i = 0; i < listcount; i++) + { + UniValue entry(UniValue::VOBJ); + entry.push_back(Pair("Time", rewardtimelist.at(i))); + entry.push_back(Pair("Reward", rewardvaluelist.at(i))); + results.push_back(entry); + } + + return results; +} + +//Tokens Reg Transaction +static void IPCTokenRegSendMoney(std::string strReglabel, const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew) +{ + CAmount curBalance = pwalletMain->GetBalance(); + + // Check amount + if (nValue < 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount"); + + if (nValue > curBalance) + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds"); + + if (pwalletMain->GetBroadcastTransactions() && !g_connman) + throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); + + // Parse Ipchain address + CScript scriptPubKey = GetScriptForDestination(address); + + // Create and send the transaction + CReserveKey reservekey(pwalletMain); + CAmount nFeeRequired; + std::string strError; + vector vecSend; + int nChangePosRet = -1; + CRecipient recipient = { scriptPubKey, nValue, fSubtractFeeFromAmount }; + vecSend.push_back(recipient); + if (!pwalletMain->CreateTokenRegTransaction(strReglabel, vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError)) { + if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance) + strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired)); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } + CValidationState state; + if (!pwalletMain->CommitTransaction(wtxNew, reservekey, g_connman.get(), state)) { + strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason()); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } +} + + + +UniValue IPCTokenRegToAddress(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 2 || request.params.size() > 2) + throw runtime_error( + "IPCTokenRegToAddress \"address\" \"icplabel\" \n" + "\nSend an amount to a given address.\n" + + HelpRequiringPassphrase() + + "\nArguments:\n" + "1. \"address\" (string, required) The ipchain address to send to.\n" + "2. \"tokenlabel\" (string) ipclabel...\n" + "\nResult:\n" + "\"txid\" (string) The transaction id.\n" + "\nExamples:\n" + + HelpExampleCli("IPCTokenRegToAddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" \"{\"TokenSymbol\":\"flycoin\",\"value\":1000,\"hash\":\"cec3144f63c09aa6e2dc03c370f339c1\",\"label\":\"NewCoin\",\"issueDate\":1508234422,\"totalCount\":10000000,\"accuracy\":2,\"txLabel\":\" \"}\" ") + + + HelpExampleRpc("IPCTokenRegToAddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", \"{\"TokenSymbol\":\"flycoin\",\"value\":1000,\"hash\":\"cec3144f63c09aa6e2dc03c370f339c1\",\"label\":\"NewCoin\",\"issueDate\":1508234422,\"totalCount\":10000000,\"accuracy\":2,\"txLabel\":\" \"}\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + CBitcoinAddress address(request.params[0].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Ipchain address"); + + // Amount + CAmount nAmount = 0; + CWalletTx wtx; + std::string strReglabel = ""; + if (request.params.size() > 1 && !request.params[1].isNull() && !request.params[1].get_str().empty()) + strReglabel = request.params[1].get_str(); + + bool fSubtractFeeFromAmount = false; + + EnsureWalletIsUnlocked(); + + IPCTokenRegSendMoney(strReglabel, address.Get(), nAmount, fSubtractFeeFromAmount, wtx); + + return wtx.GetHash().GetHex(); +} + +//Tokens trading +static void IPCTokenSendMoney(std::string& tokensymbol, uint64_t value, const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew) +{ + CAmount curBalance = pwalletMain->GetBalance(); + + if (nValue < 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount"); + + if (nValue > curBalance) + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds"); + + if (pwalletMain->GetBroadcastTransactions() && !g_connman) + throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); + + // Parse Ipchain address + CScript scriptPubKey = GetScriptForDestination(address); + + // Create and send the transaction + CReserveKey reservekey(pwalletMain); + CAmount nFeeRequired; + std::string strError; + vector vecSend; + int nChangePosRet = -1; + CRecipient recipient = { scriptPubKey, nValue, fSubtractFeeFromAmount }; + vecSend.push_back(recipient); + + if (!pwalletMain->CreateTokenTransaction(tokensymbol, value, vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError)) { + if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance) + strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired)); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } + CValidationState state; + if (!pwalletMain->CommitTransaction(wtxNew, reservekey, g_connman.get(), state)) { + strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason()); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } +} +static void IPCTokenSendMoneyForCross(std::string& tokensymbol, uint64_t value, const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew,const std::string& txLabel) +{ + CAmount curBalance = pwalletMain->GetBalance(); + + if (nValue < 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount"); + + if (nValue > curBalance) + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds"); + + if (pwalletMain->GetBroadcastTransactions() && !g_connman) + throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); + + // Parse Ipchain address + CScript scriptPubKey = GetScriptForDestination(address); + + // Create and send the transaction + CReserveKey reservekey(pwalletMain); + CAmount nFeeRequired; + std::string strError; + vector vecSend; + int nChangePosRet = -1; + CRecipient recipient = { scriptPubKey, nValue, fSubtractFeeFromAmount }; + vecSend.push_back(recipient); + + if (!pwalletMain->CreateTokenTransactionForCross(tokensymbol, txLabel, value, vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError)) { + if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance) + strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired)); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } + CValidationState state; + if (!pwalletMain->CommitTransaction(wtxNew, reservekey, g_connman.get(), state)) { + strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason()); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } +} + + +UniValue IPCTokenSendToAddress(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 3 || request.params.size() > 3) + throw runtime_error( + "IPCTokenSendToAddress \"tokensymbol\" \"address\" \"value\" \n" + "\nSend an amount to a given address.\n" + + HelpRequiringPassphrase() + + "\nArguments:\n" + "1. \"tokensymbol\" (string) The tokensymbol of what you want to send.\n" + "2. \"address\" (string, required) The ipchain address to send to.\n" + "3. \"value\" (int)The value of Tokentransaction.\n" + "\nResult:\n" + "\"txid\" (string) The transaction id.\n" + "\nExamples:\n" + + HelpExampleCli("IPCTokenSendToAddress", "tokensymbol \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 1 ") + + HelpExampleCli("IPCTokenSendToAddress", "tokensymbol \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 1 ") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + std::string tokensymbol = request.params[0].get_str(); + + CBitcoinAddress address(request.params[1].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Ipchain address"); + + int nacc = (int)tokenDataMap[tokensymbol].accuracy; + int64_t TokenValue = TCoinsFromValue(request.params[2], nacc); + if (TokenValue <= 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Tokentransaction value"); + // Amount + CAmount nAmount = 0; + uint64_t nTokenCount = TokenValue; + // Wallet comments + CWalletTx wtx; + bool fSubtractFeeFromAmount = false; + + EnsureWalletIsUnlocked(); + + IPCTokenSendMoney(tokensymbol, nTokenCount, address.Get(), nAmount, fSubtractFeeFromAmount, wtx); + + return wtx.GetHash().GetHex(); +} + +UniValue IPCTokenSendToAddressForCross(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 4 || request.params.size() > 4) + throw runtime_error( + "IPCTokenSendToAddressForCross \"tokensymbol\" \"address\" value \"txLabel\" \n" + "\nSend an amount to a given address.\n" + + HelpRequiringPassphrase() + + "\nArguments:\n" + "1. \"tokensymbol\" (string) The tokensymbol of what you want to send.\n" + "2. \"address\" (string, required) The ipchain address to send to.\n" + "3. \"value\" (string,int)The value of Tokentransaction.\n" + "4. \"txLabel\" (string)The string of txLabel.\n" + "\nResult:\n" + "\"txid\" (string) The transaction id.\n" + "\nExamples:\n" + + HelpExampleCli("IPCTokenSendToAddressForCross", "tokensymbol \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 1 \"0x360fd3534ccb10671140fe16cb8d5e04349df0d1\"") + + HelpExampleCli("IPCTokenSendToAddressForCross", "tokensymbol \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 1 \"0x360fd3534ccb10671140fe16cb8d5e04349df0d1\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + std::string tokensymbol = request.params[0].get_str(); + + CBitcoinAddress address(request.params[1].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Ipchain address"); + + int nacc = (int)tokenDataMap[tokensymbol].accuracy; + int64_t TokenValue = TCoinsFromValue(request.params[2], nacc); + if (TokenValue <= 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Tokentransaction value"); + std::string txLabel = ""; + if (request.params.size() > 3) + txLabel = request.params[3].get_str(); + std::cout << "txLabel : " << txLabel << std::endl; + // Amount + CAmount nAmount = 0; + uint64_t nTokenCount = TokenValue; + // Wallet comments + CWalletTx wtx; + bool fSubtractFeeFromAmount = false; + + EnsureWalletIsUnlocked(); + + IPCTokenSendMoneyForCross(tokensymbol, nTokenCount, address.Get(), nAmount, fSubtractFeeFromAmount, wtx,txLabel); + + return wtx.GetHash().GetHex(); +} +//end + + + +UniValue listaddressgroupings(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp) + throw runtime_error( + "listaddressgroupings\n" + "\nLists groups of addresses which have had their common ownership\n" + "made public by common use as inputs or as the resulting change\n" + "in past transactions\n" + "\nResult:\n" + "[\n" + " [\n" + " [\n" + " \"address\", (string) The ipchain address\n" + " amount, (numeric) The amount in " + CURRENCY_UNIT + "\n" + " \"account\" (string, optional) DEPRECATED. The account\n" + " ]\n" + " ,...\n" + " ]\n" + " ,...\n" + "]\n" + "\nExamples:\n" + + HelpExampleCli("listaddressgroupings", "") + + HelpExampleRpc("listaddressgroupings", "") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + UniValue jsonGroupings(UniValue::VARR); + map balances = pwalletMain->GetAddressBalances(); + BOOST_FOREACH(set grouping, pwalletMain->GetAddressGroupings()) + { + UniValue jsonGrouping(UniValue::VARR); + BOOST_FOREACH(CTxDestination address, grouping) + { + UniValue addressInfo(UniValue::VARR); + addressInfo.push_back(CBitcoinAddress(address).ToString()); + addressInfo.push_back(ValueFromAmount(balances[address])); + { + if (pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get()) != pwalletMain->mapAddressBook.end()) + addressInfo.push_back(pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get())->second.name); + } + jsonGrouping.push_back(addressInfo); + } + jsonGroupings.push_back(jsonGrouping); + } + return jsonGroupings; +} + +UniValue signmessage(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() != 2) + throw runtime_error( + "signmessage \"address\" \"message\"\n" + "\nSign a message with the private key of an address" + + HelpRequiringPassphrase() + "\n" + "\nArguments:\n" + "1. \"address\" (string, required) The ipchain address to use for the private key.\n" + "2. \"message\" (string, required) The message to create a signature of.\n" + "\nResult:\n" + "\"signature\" (string) The signature of the message encoded in base 64\n" + "\nExamples:\n" + "\nUnlock the wallet for 30 seconds\n" + + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") + + "\nCreate the signature\n" + + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") + + "\nVerify the signature\n" + + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") + + "\nAs json rpc\n" + + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + EnsureWalletIsUnlocked(); + + string strAddress = request.params[0].get_str(); + string strMessage = request.params[1].get_str(); + + CBitcoinAddress addr(strAddress); + if (!addr.IsValid()) + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address"); + + CKeyID keyID; + if (!addr.GetKeyID(keyID)) + throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); + + CKey key; + if (!pwalletMain->GetKey(keyID, key)) + throw JSONRPCError(RPC_WALLET_ERROR, "Private key not available"); + + CHashWriter ss(SER_GETHASH, 0); + ss << strMessageMagic; + ss << strMessage; + + vector vchSig; + if (!key.SignCompact(ss.GetHash(), vchSig)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed"); + + return EncodeBase64(&vchSig[0], vchSig.size()); +} + +//Debug the interface to generate the package person's signature in Coinbase +UniValue dpocsign(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "dpocsign \"hexdata\"\n" + "\nSign a hexdata with the private key of current dpoc account" + + HelpRequiringPassphrase() + "\n" + "\nArguments:\n" + "1. \"hexdata\" (string, required) The hexstring of data to create a signature of.\n" + "\nResult:\n" + "\"signature\" (string) The signature of the message with the format in coinbase\n" + "\nExamples:\n" + "\nTo Do\n" + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + EnsureWalletIsUnlocked(); + + string hexdata = request.params[0].get_str(); + if (!IsHex(hexdata)) + { + return false; + } + + std::string pubkeyhex; + if (!CDpocInfo::Instance().GetLocalAccount(pubkeyhex)) + return false; + + uint160 devoterhash; + devoterhash.SetHex(pubkeyhex); + + CKeyID publickeyID(devoterhash); + CPubKey vchPubKeyOut; + if (pwalletMain->GetPubKey(publickeyID, vchPubKeyOut)) { + //LogPrintf("[addRulersToCoinbase] public keyhash=%s", vchPubKeyOut.GetHash().ToString().c_str()); + } + else { + //LogPrintf("[addSignToCoinBase] don't find public key "); + return false; + } + + CKey vchPrivKeyOut; + if (pwalletMain->GetKey(publickeyID, vchPrivKeyOut)) { + } + else { + //LogPrintf("[addSignToCoinBase] don't find private key"); + return false; + } + + uint256 hash; + std::vector data = ParseHex(hexdata); + CHash256 hashoperator; + for (std::vector::iterator it = data.begin(); it != data.end(); it++) + { + hashoperator.Write((unsigned char*)&(*it), sizeof(unsigned char)); + } + hashoperator.Finalize(hash.begin()); + + std::vector vchSig; + vchPrivKeyOut.Sign(hash, vchSig); + + // Generate signature cache + std::vector vchSigSend; + vchSigSend.resize(2 + vchPubKeyOut.size() + vchSig.size()); + + //Cached signature + unsigned char vchSigLen = (unsigned char)vchSig.size(); + vchSigSend[0] = vchSigLen; + for (std::vector::size_type ix = 0; ix < vchSig.size(); ++ix) { + vchSigSend[ix + 1] = vchSig[ix]; + } + + //The cache of public key + vchSigSend[vchSigLen + 1] = (unsigned char)vchPubKeyOut.size(); + for (std::vector::size_type ix = 0; ix < vchPubKeyOut.size(); ++ix) { + vchSigSend[ix + 2 + vchSigLen] = vchPubKeyOut[ix]; + } + + // std::cout << "vchSig.size=" << vchSig.size() << " vchPubKeyOut.size=" << vchPubKeyOut.size() << " vchSigSend.size=" << vchSigSend.size() << std::endl; + std::string strSin2Publickey = EncodeBase58(vchSigSend); + + return strSin2Publickey; +} + +UniValue getreceivedbyaddress(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) + throw runtime_error( + "getreceivedbyaddress \"address\" ( minconf )\n" + "\nReturns the total amount received by the given address in transactions with at least minconf confirmations.\n" + "\nArguments:\n" + "1. \"address\" (string, required) The ipchain address for transactions.\n" + "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n" + "\nResult:\n" + "amount (numeric) The total amount in " + CURRENCY_UNIT + " received at this address.\n" + "\nExamples:\n" + "\nThe amount from transactions with at least 1 confirmation\n" + + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"") + + "\nThe amount including unconfirmed transactions, zero confirmations\n" + + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" 0") + + "\nThe amount with at least 6 confirmation, very safe\n" + + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" 6") + + "\nAs a json rpc call\n" + + HelpExampleRpc("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", 6") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + // Ipchain address + CBitcoinAddress address = CBitcoinAddress(request.params[0].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid ipchain address"); + CScript scriptPubKey = GetScriptForDestination(address.Get()); + if (!IsMine(*pwalletMain, scriptPubKey)) + return ValueFromAmount(0); + + // Minimum confirmations + int nMinDepth = 1; + if (request.params.size() > 1) + nMinDepth = request.params[1].get_int(); + + // Tally + CAmount nAmount = 0; + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx)) + continue; + + BOOST_FOREACH(const CTxOut& txout, wtx.tx->vout) + if (txout.scriptPubKey == scriptPubKey) + if (wtx.GetDepthInMainChain() >= nMinDepth) + nAmount += txout.nValue; + } + + return ValueFromAmount(nAmount); +} + + +UniValue getreceivedbyaccount(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) + throw runtime_error( + "getreceivedbyaccount \"account\" ( minconf )\n" + "\nDEPRECATED. Returns the total amount received by addresses with in transactions with at least [minconf] confirmations.\n" + "\nArguments:\n" + "1. \"account\" (string, required) The selected account, may be the default account using \"\".\n" + "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n" + "\nResult:\n" + "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n" + "\nExamples:\n" + "\nAmount received by the default account with at least 1 confirmation\n" + + HelpExampleCli("getreceivedbyaccount", "\"\"") + + "\nAmount received at the tabby account including unconfirmed amounts with zero confirmations\n" + + HelpExampleCli("getreceivedbyaccount", "\"tabby\" 0") + + "\nThe amount with at least 6 confirmation, very safe\n" + + HelpExampleCli("getreceivedbyaccount", "\"tabby\" 6") + + "\nAs a json rpc call\n" + + HelpExampleRpc("getreceivedbyaccount", "\"tabby\", 6") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + // Minimum confirmations + int nMinDepth = 1; + if (request.params.size() > 1) + nMinDepth = request.params[1].get_int(); + + // Get the set of pub keys assigned to account + string strAccount = AccountFromValue(request.params[0]); + set setAddress = pwalletMain->GetAccountAddresses(strAccount); + + // Tally + CAmount nAmount = 0; + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx)) + continue; + + BOOST_FOREACH(const CTxOut& txout, wtx.tx->vout) + { + CTxDestination address; + if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwalletMain, address) && setAddress.count(address)) + if (wtx.GetDepthInMainChain() >= nMinDepth) + nAmount += txout.nValue; + } + } + + return ValueFromAmount(nAmount); +} + + +UniValue getbalance(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() > 0) + throw runtime_error( + "getbalance \n" +// "\nIf account is not specified, returns the server's total available balance.\n" +// "If account is specified (DEPRECATED), returns the balance in the account.\n" +// "Note that the account \"\" is not the same as leaving the parameter out.\n" +// "The server total may be different to the balance in the default \"\" account.\n" +// "\nArguments:\n" +// "1. \"account\" (string, optional) DEPRECATED. The account string may be given as a\n" +// " specific account name to find the balance associated with wallet keys in\n" +// " a named account, or as the empty string (\"\") to find the balance\n" +// " associated with wallet keys not in any named account, or as \"*\" to find\n" +// " the balance associated with all wallet keys regardless of account.\n" +// " When this option is specified, it calculates the balance in a different\n" +// " way than when it is not specified, and which can count spends twice when\n" +// " there are conflicting pending transactions (such as those created by\n" +// " the bumpfee command), temporarily resulting in low or even negative\n" +// " balances. In general, account balance calculation is not considered\n" +// " reliable and has resulted in confusing outcomes, so it is recommended to\n" +// " avoid passing this argument.\n" +// "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n" +// "3. include_watchonly (bool, optional, default=false) Also include balance in watch-only addresses (see 'importaddress')\n" + "\nResult:\n" + "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for \"*\" account.\n" + "\nExamples:\n" + "\nThe total amount in the wallet\n" + + HelpExampleCli("getbalance", "") + +// "\nThe total amount in the wallet at least 5 blocks confirmed\n" +// + HelpExampleCli("getbalance", "\"*\" 6") + + "\nAs a json rpc call\n" + + HelpExampleRpc("getbalance", "" /*"\"*\", 6"*/) + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + if (request.params.size() == 0) + return ValueFromAmount(pwalletMain->GetBalance()); + + int nMinDepth = 8; + if (request.params.size() > 1) + nMinDepth = request.params[1].get_int(); + isminefilter filter = ISMINE_SPENDABLE; + if(request.params.size() > 2) + if(request.params[2].get_bool()) + filter = filter | ISMINE_WATCH_ONLY; + + if (request.params[0].get_str() == "*") { + // Calculate total balance in a very different way from GetBalance(). + // The biggest difference is that GetBalance() sums up all unspent + // TxOuts paying to the wallet, while this sums up both spent and + // unspent TxOuts paying to the wallet, and then subtracts the values of + // TxIns spending from the wallet. This also has fewer restrictions on + // which unconfirmed transactions are considered trusted. + CAmount nBalance = 0; + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + if (!CheckFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < 0) + continue; + + CAmount allFee; + string strSentAccount; + list listReceived; + list listSent; + wtx.GetAmounts(listReceived, listSent, allFee, strSentAccount, filter); + if (wtx.GetDepthInMainChain() >= nMinDepth) + { + BOOST_FOREACH(const COutputEntry& r, listReceived) + nBalance += r.amount; + } + BOOST_FOREACH(const COutputEntry& s, listSent) + nBalance -= s.amount; + nBalance -= allFee; + } + return ValueFromAmount(nBalance); + } + + string strAccount = AccountFromValue(request.params[0]); + + CAmount nBalance = pwalletMain->GetAccountBalance(strAccount, nMinDepth, filter); + + return ValueFromAmount(nBalance); +} + +UniValue getunconfirmedbalance(const JSONRPCRequest &request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() > 0) + throw runtime_error( + "getunconfirmedbalance\n" + "Returns the server's total unconfirmed balance\n"); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + return ValueFromAmount(pwalletMain->GetUnconfirmedBalance()); +} + + +UniValue movecmd(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 3 || request.params.size() > 5) + throw runtime_error( + "move \"fromaccount\" \"toaccount\" amount ( minconf \"comment\" )\n" + "\nDEPRECATED. Move a specified amount from one account in your wallet to another.\n" + "\nArguments:\n" + "1. \"fromaccount\" (string, required) The name of the account to move funds from. May be the default account using \"\".\n" + "2. \"toaccount\" (string, required) The name of the account to move funds to. May be the default account using \"\".\n" + "3. amount (numeric) Quantity of " + CURRENCY_UNIT + " to move between accounts.\n" + "4. (dummy) (numeric, optional) Ignored. Remains for backward compatibility.\n" + "5. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n" + "\nResult:\n" + "true|false (boolean) true if successful.\n" + "\nExamples:\n" + "\nMove 0.01 " + CURRENCY_UNIT + " from the default account to the account named tabby\n" + + HelpExampleCli("move", "\"\" \"tabby\" 0.01") + + "\nMove 0.01 " + CURRENCY_UNIT + " timotei to akiko with a comment and funds have 6 confirmations\n" + + HelpExampleCli("move", "\"timotei\" \"akiko\" 0.01 6 \"happy birthday!\"") + + "\nAs a json rpc call\n" + + HelpExampleRpc("move", "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + string strFrom = AccountFromValue(request.params[0]); + string strTo = AccountFromValue(request.params[1]); + CAmount nAmount = AmountFromValue(request.params[2]); + if (nAmount <= 0) + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); + if (request.params.size() > 3) + // unused parameter, used to be nMinDepth, keep type-checking it though + (void)request.params[3].get_int(); + string strComment; + if (request.params.size() > 4) + strComment = request.params[4].get_str(); + + if (!pwalletMain->AccountMove(strFrom, strTo, nAmount, strComment)) + throw JSONRPCError(RPC_DATABASE_ERROR, "database error"); + + return true; +} + + +UniValue sendfrom(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 3 || request.params.size() > 6) + throw runtime_error( + "sendfrom \"fromaccount\" \"toaddress\" amount ( minconf \"comment\" \"comment_to\" )\n" + "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a ipchain address." + + HelpRequiringPassphrase() + "\n" + "\nArguments:\n" + "1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n" + " Specifying an account does not influence coin selection, but it does associate the newly created\n" + " transaction with the account, so the account's balance computation and transaction history can reflect\n" + " the spend.\n" + "2. \"toaddress\" (string, required) The ipchain address to send funds to.\n" + "3. amount (numeric or string, required) The amount in " + CURRENCY_UNIT + " (transaction fee is added on top).\n" + "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n" + "5. \"comment\" (string, optional) A comment used to store what the transaction is for. \n" + " This is not part of the transaction, just kept in your wallet.\n" + "6. \"comment_to\" (string, optional) An optional comment to store the name of the person or organization \n" + " to which you're sending the transaction. This is not part of the transaction, \n" + " it is just kept in your wallet.\n" + "\nResult:\n" + "\"txid\" (string) The transaction id.\n" + "\nExamples:\n" + "\nSend 0.01 " + CURRENCY_UNIT + " from the default account to the address, must have at least 1 confirmation\n" + + HelpExampleCli("sendfrom", "\"\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01") + + "\nSend 0.01 from the tabby account to the given address, funds must have at least 6 confirmations\n" + + HelpExampleCli("sendfrom", "\"tabby\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01 6 \"donation\" \"seans outpost\"") + + "\nAs a json rpc call\n" + + HelpExampleRpc("sendfrom", "\"tabby\", \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.01, 6, \"donation\", \"seans outpost\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + string strAccount = AccountFromValue(request.params[0]); + CBitcoinAddress address(request.params[1].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Ipchain address"); + CAmount nAmount = AmountFromValue(request.params[2]); + if (nAmount <= 0) + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); + int nMinDepth = 1; + if (request.params.size() > 3) + nMinDepth = request.params[3].get_int(); + + CWalletTx wtx; + wtx.strFromAccount = strAccount; + if (request.params.size() > 4 && !request.params[4].isNull() && !request.params[4].get_str().empty()) + wtx.mapValue["comment"] = request.params[4].get_str(); + if (request.params.size() > 5 && !request.params[5].isNull() && !request.params[5].get_str().empty()) + wtx.mapValue["to"] = request.params[5].get_str(); + + EnsureWalletIsUnlocked(); + + // Check funds + CAmount nBalance = pwalletMain->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); + if (nAmount > nBalance) + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds"); + + SendMoney(address.Get(), nAmount, false, wtx); + + return wtx.GetHash().GetHex(); +} + + +UniValue sendmany(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 2 || request.params.size() > 2) + throw runtime_error( + "sendmany \"fromaccount\" {\"address\":amount,...} \n" + "\nSend multiple times. Amounts are double-precision floating point numbers." + + HelpRequiringPassphrase() + "\n" + "\nArguments:\n" + "1. \"fromaccount\" (string, required) DEPRECATED. The account to send the funds from. Should be \"\" for the default account\n" + "2. \"amounts\" (string, required) A json object with addresses and amounts\n" + " {\n" + " \"address\":amount (numeric or string) The ipchain address is the key, the numeric amount (can be string) in " + CURRENCY_UNIT + " is the value\n" + " ,...\n" + " }\n" +// "3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n" +// "4. \"comment\" (string, optional) A comment\n" +// "5. subtractfeefrom (array, optional) A json array with addresses.\n" +// " The fee will be equally deducted from the amount of each selected address.\n" +// " Those recipients will receive less ipchains than you enter in their corresponding amount field.\n" +// " If no addresses are specified here, the sender pays the fee.\n" +// " [\n" +// " \"address\" (string) Subtract fee from this address\n" +// " ,...\n" +// " ]\n" + "\nResult:\n" + "\"txid\" (string) The transaction id for the send. Only 1 transaction is created regardless of \n" + " the number of addresses.\n" + "\nExamples:\n" + "\nSend two amounts to two different addresses:\n" + + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") + +// "\nSend two amounts to two different addresses setting the confirmation and comment:\n" +// + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") + +// "\nSend two amounts to two different addresses, subtract fee from amount:\n" +// + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 1 \"\" \"[\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\",\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\"]\"") + + "\nAs a json rpc call\n" + + HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + if (pwalletMain->GetBroadcastTransactions() && !g_connman) + throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); + + string strAccount = AccountFromValue(request.params[0]); + strAccount = ""; + UniValue sendTo = request.params[1].get_obj(); + int nMinDepth = 1; + if (request.params.size() > 2) + nMinDepth = request.params[2].get_int(); + + CWalletTx wtx; + wtx.strFromAccount = strAccount; + if (request.params.size() > 3 && !request.params[3].isNull() && !request.params[3].get_str().empty()) + wtx.mapValue["comment"] = request.params[3].get_str(); + + UniValue subtractFeeFromAmount(UniValue::VARR); + if (request.params.size() > 4) + subtractFeeFromAmount = request.params[4].get_array(); + + set setAddress; + vector vecSend; + + CAmount totalAmount = 0; + vector keys = sendTo.getKeys(); + BOOST_FOREACH(const string& name_, keys) + { + CBitcoinAddress address(name_); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Ipchain address: ")+name_); + + if (setAddress.count(address)) + throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+name_); + setAddress.insert(address); + + CScript scriptPubKey = GetScriptForDestination(address.Get()); + CAmount nAmount = AmountFromValue(sendTo[name_]); + if (nAmount <= 0) + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); + totalAmount += nAmount; + + bool fSubtractFeeFromAmount = false; + for (unsigned int idx = 0; idx < subtractFeeFromAmount.size(); idx++) { + const UniValue& addr = subtractFeeFromAmount[idx]; + if (addr.get_str() == name_) + fSubtractFeeFromAmount = true; + } + + CRecipient recipient = {scriptPubKey, nAmount, fSubtractFeeFromAmount}; + vecSend.push_back(recipient); + } + + EnsureWalletIsUnlocked(); + + // Check funds + // CAmount nBalance = pwalletMain->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); + CAmount nBalance = pwalletMain->GetBalance(); + if (totalAmount > nBalance) + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds"); + + // Send + CReserveKey keyChange(pwalletMain); + CAmount nFeeRequired = 0; + int nChangePosRet = -1; + string strFailReason; + bool fCreated = pwalletMain->CreateNormalTransaction(vecSend, wtx, keyChange, nFeeRequired, nChangePosRet, strFailReason); + if (!fCreated) + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason); + CValidationState state; + if (!pwalletMain->CommitTransaction(wtx, keyChange, g_connman.get(), state)) { + strFailReason = strprintf("Transaction commit failed:: %s", state.GetRejectReason()); + throw JSONRPCError(RPC_WALLET_ERROR, strFailReason); + } + + return wtx.GetHash().GetHex(); +} + +UniValue sendtokenmany(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() != 3) + throw runtime_error( + "sendtokenmany \"fromaccount\" \"tokensymbol\" {\"address\":amount,...}\n" + "\nSend multiple times. Amounts are double-precision floating point numbers." + + HelpRequiringPassphrase() + "\n" + "\nArguments:\n" + "1. \"fromaccount\" (string, required) DEPRECATED. The account to send the funds from. Should be \"\" for the default account\n" + "2. \"tokensymbol\" (string, required) Tokensymbol which you want to send\n" + "3. \"amounts\" (string, required) A json object with addresses and amounts\n" + " {\n" + " \"address\":amount (numeric or string) The ipchain address is the key, the numeric amount (can be string) in tokenvalue is the value\n" + " ,...\n" + " }\n" + "\nResult:\n" + "\"txid\" (string) The transaction id for the send. Only 1 transaction is created regardless of \n" + " the number of addresses.\n" + "\nExamples:\n" + "\nSend two token amounts to two different addresses:\n" + + HelpExampleCli("sendtokenmany", "\"\" \"tokensymbol\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + if (pwalletMain->GetBroadcastTransactions() && !g_connman) + throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); + + string strAccount = AccountFromValue(request.params[0]); + string tokensymbol = request.params[1].get_str(); + if (tokenDataMap.count(tokensymbol) == 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Error: Can't found 'accuracy' of the Token"); + + int tokenaccuracy = tokenDataMap[tokensymbol].accuracy; + //std::cout << "tokenaccuracy = " << tokenaccuracy << std::endl; + UniValue sendTo = request.params[2].get_obj(); + + CWalletTx wtx; + wtx.strFromAccount = strAccount; + + set setAddress; + vector vecSend; + vecSend.clear(); + uint64_t totalAmount = 0; + vector keys = sendTo.getKeys(); + BOOST_FOREACH(const string& name_, keys) + { + CBitcoinAddress address(name_); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid IPchain address: ") + name_); + + if (setAddress.count(address)) + throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ") + name_); + setAddress.insert(address); + + CScript scriptPubKey = GetScriptForDestination(address.Get()); + int64_t nAmount = TCoinsFromValue(sendTo[name_], tokenaccuracy); + if (nAmount <= 0) + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid token amount for send"); + totalAmount += nAmount; + + bool fSubtractFeeFromAmount = false; + CAmount nipcAmount = 0; + uint64_t ntokenamount = nAmount; + CRecipientToken recipient = { scriptPubKey, nipcAmount, ntokenamount, fSubtractFeeFromAmount }; + vecSend.push_back(recipient); + } + + EnsureWalletIsUnlocked(); + + // Check funds + uint64_t nBalance = 0; + pwalletMain->GetSymbolbalance(tokensymbol, nBalance); + if (totalAmount > nBalance) + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds"); + //std::cout << "totalAmount =" << totalAmount << std::endl; + + // Send + CReserveKey keyChange(pwalletMain); + CAmount nFeeRequired = 0; + int nChangePosRet = -1; + string strFailReason; + bool fCreated = pwalletMain->CreateTokenTransactionM(tokensymbol,vecSend, wtx, keyChange, nFeeRequired, nChangePosRet, strFailReason); + if (!fCreated) + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason); + CValidationState state; + if (!pwalletMain->CommitTransaction(wtx, keyChange, g_connman.get(), state)) { + strFailReason = strprintf("Transaction commit failed:: %s", state.GetRejectReason()); + throw JSONRPCError(RPC_WALLET_ERROR, strFailReason); + } + + return wtx.GetHash().GetHex(); +} +// Defined in rpc/misc.cpp +extern CScript _createmultisig_redeemScript(const UniValue& params); + +UniValue addmultisigaddress(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) + { + string msg = "addmultisigaddress nrequired [\"key\",...] ( \"account\" )\n" + "\nAdd a nrequired-to-sign multisignature address to the wallet.\n" + "Each key is a Ipchain address or hex-encoded public key.\n" + "If 'account' is specified (DEPRECATED), assign address to that account.\n" + + "\nArguments:\n" + "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n" + "2. \"keys\" (string, required) A json array of ipchain addresses or hex-encoded public keys\n" + " [\n" + " \"address\" (string) ipchain address or hex-encoded public key\n" + " ...,\n" + " ]\n" + "3. \"account\" (string, optional) DEPRECATED. An account to assign the addresses to.\n" + + "\nResult:\n" + "\"address\" (string) A ipchain address associated with the keys.\n" + + "\nExamples:\n" + "\nAdd a multisig address from 2 addresses\n" + + HelpExampleCli("addmultisigaddress", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") + + "\nAs json rpc call\n" + + HelpExampleRpc("addmultisigaddress", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") + ; + throw runtime_error(msg); + } + + LOCK2(cs_main, pwalletMain->cs_wallet); + + string strAccount; + if (request.params.size() > 2) + strAccount = AccountFromValue(request.params[2]); + + // Construct using pay-to-script-hash: + CScript inner = _createmultisig_redeemScript(request.params); + + std::string multiscript = ScriptToAsmStr(inner); + + + CScriptID innerID(inner); + pwalletMain->AddCScript(inner); + + pwalletMain->SetAddressBook(innerID, strAccount, "union"); + + return CBitcoinAddress(innerID).ToString(); +} +UniValue createmultiaddress(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) + { + string msg = "createmultiaddress nrequired [\"key\",...] ( \"account\" )\n" + "\nAdd a nrequired-to-sign multisignature address to the wallet.\n" + "Each key is a ipc address or hex-encoded public key.\n" + "If 'account' is specified (DEPRECATED), assign address to that account.\n" + + "\nArguments:\n" + "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n" + "2. \"keys\" (string, required) A json array of bitcoin addresses or hex-encoded public keys\n" + " [\n" + " \"address\" (string) hex-encoded public key\n" + " ...,\n" + " ]\n" + "3. \"account\" (string, optional) DEPRECATED. An account to assign the addresses to.\n" + + "\nResult:\n" + "\"address\" (string) A bitcoin address associated with the keys.\n" + + "\nExamples:\n" + "\nAdd a multisig address from 2 addresses\n" + + HelpExampleCli("createmultiaddress", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") + + "\nAs json rpc call\n" + + HelpExampleRpc("createmultiaddress", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") + ; + throw runtime_error(msg); + } + + LOCK2(cs_main, pwalletMain->cs_wallet); + + string strAccount; + if (request.params.size() > 2) + strAccount = AccountFromValue(request.params[2]); + + int nmembers; + int nRequired = request.params[0].get_int(); + std::vector pubkeys; + const UniValue& keys = request.params[1].get_array(); + if (nRequired < 1) + throw runtime_error("a multisignature address must require at least one key to redeem"); + if ((int)keys.size() < nRequired) + throw runtime_error( + strprintf("not enough keys supplied " + "(got %u keys, but need at least %d to redeem)", keys.size(), nRequired)); + if (keys.size() > 16) + throw runtime_error("Number of addresses involved in the multisignature address creation > 16\nReduce the number"); + pubkeys.resize(keys.size()); + for (unsigned int i = 0; i < keys.size(); i++) + { + const std::string& ks = keys[i].get_str(); + pubkeys[i] = ks; + } + std::string multiscript; + std::string strmultiaddress; + std::string strFailReason; + if(pwalletMain->CreateMultiAddress(nRequired, pubkeys,multiscript,strmultiaddress,strFailReason) + &&pwalletMain->AddMultiAddress(multiscript, strFailReason,nRequired,nmembers,strAccount)){ + return multiscript; + } + else{ + throw runtime_error( + strprintf("error reason: " + "(%s)", strFailReason)); + } +} +UniValue addmultiadd(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) + { + string msg = "addmultiadd nrequired [\"key\",...] ( \"account\" )\n" + "\nAdd a nrequired-to-sign multisignature address to the wallet.\n" + "Each key is a Bitcoin address or hex-encoded public key.\n" + "If 'account' is specified (DEPRECATED), assign address to that account.\n" + + "\nArguments:\n" + "1. strhex (string, required) The hex of address which you want to add .\n" + "2. \"account\" (string, optional) DEPRECATED. An account to assign the addresses to.\n" + + "\nResult:\n" + "\"bool\" true or false.\n" + + "\nExamples:\n" + "\nAdd a multisig address \n" + + HelpExampleCli("addmultiadd", "\"strhex \""); + throw runtime_error(msg); + } + + LOCK2(cs_main, pwalletMain->cs_wallet); + std::string strmultiaddress = request.params[0].get_str(); + std::string strAccount = ""; + if (request.params.size() > 1) + strAccount = request.params[1].get_str(); + std::string strFailReason = ""; + int nRequired; + int nmembers; + if(!pwalletMain->AddMultiAddress(strmultiaddress, strFailReason,nRequired,nmembers,strAccount)){ + throw runtime_error( + strprintf("error reason: " + "(%s)", strFailReason)); + } + return true; +} + +UniValue decodeInvCode(const JSONRPCRequest& request) +{ + + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) + { + string msg = "decodeInvCode \"strInvCode\" \n" + "\nDecode the strInvCode of the multiaddress.\n" + + "\nArguments:\n" + "1. \"strInvCode\" (string, required) hex-encoded from createmultiaddress\n" + "\nResult:\n" + "\"infos\" arry of the info.\n" + + "\nExamples:\n" + "\nDecode the strInvCode of the multiaddress. \n" + + HelpExampleCli("decodeInvCode", "\"strInvCode \""); + throw runtime_error(msg); + } + + LOCK2(cs_main, pwalletMain->cs_wallet); + std::string strInvCode = request.params[0].get_str(); + + UniValue sInfo(UniValue::VARR); + UniValue results(UniValue::VOBJ); + int nRequired = 0; + int nmembers = 0; + std::vector pubkeys; + if (pwalletMain->DecodeStrInvCode(strInvCode, pubkeys, nRequired, nmembers)) + { + results.push_back(Pair("nRequired", nRequired)); + results.push_back(Pair("nmembers", nmembers)); + unsigned int nSize = pubkeys.size(); + for (unsigned i = 0; i < nSize;i++) + sInfo.push_back(pubkeys[i]); + results.push_back(Pair("pubkeys", sInfo)); + } + + return results; +} + +UniValue getunionaddresses(const JSONRPCRequest& request) +{ + std::vector addressbook; + pwalletMain->getUnionAddresses(addressbook); + auto itor = addressbook.begin(); + UniValue obj(UniValue::VOBJ); + while(itor!=addressbook.end()){ + obj.push_back(Pair(itor->address, itor->name)); + itor++; + } + return obj; +} + +UniValue getunioncoins(const JSONRPCRequest& request) +{ + + if (request.fHelp || request.params.size() != 1) + { + string msg = "getunioncoins \"strInvCode\" \n" + "\nDecode the strInvCode of the multiaddress.\n" + + "\nArguments:\n" + "1. addresses (string, required) The strInvCode of multiaddress which you want to decode .\n" + + "\nResult:\n" + "\"address and money\" arry of the pubkeys.\n" + + "\nExamples:\n" + "\nDecode the strInvCode of the multiaddress. \n" + + HelpExampleCli("getunioncoins", "\"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"] \""); + throw runtime_error(msg); + } + const UniValue& addresses = request.params[0].get_array(); + std::map moneynums; + for (unsigned int i = 0; i < addresses.size(); i++) + { + const std::string& ks = addresses[i].get_str(); + moneynums[ks] = 0; + } + pwalletMain->AvailableUnionCoins(moneynums); + auto itor = moneynums.begin(); + UniValue obj(UniValue::VOBJ); + while(itor!=moneynums.end()){ + obj.push_back(Pair(itor->first,ValueFromAmount(itor->second))); + itor++; + } + return obj; +} + +class Witnessifier : public boost::static_visitor +{ +public: + CScriptID result; + + bool operator()(const CNoDestination &dest) const { return false; } + + bool operator()(const CKeyID &keyID) { + CPubKey pubkey; + if (pwalletMain) { + CScript basescript = GetScriptForDestination(keyID); + isminetype typ; + typ = IsMine(*pwalletMain, basescript, SIGVERSION_WITNESS_V0); + if (typ != ISMINE_SPENDABLE && typ != ISMINE_WATCH_SOLVABLE) + return false; + CScript witscript = GetScriptForWitness(basescript); + pwalletMain->AddCScript(witscript); + result = CScriptID(witscript); + return true; + } + return false; + } + + bool operator()(const CScriptID &scriptID) { + CScript subscript; + if (pwalletMain && pwalletMain->GetCScript(scriptID, subscript)) { + int witnessversion; + std::vector witprog; + if (subscript.IsWitnessProgram(witnessversion, witprog)) { + result = scriptID; + return true; + } + isminetype typ; + typ = IsMine(*pwalletMain, subscript, SIGVERSION_WITNESS_V0); + if (typ != ISMINE_SPENDABLE && typ != ISMINE_WATCH_SOLVABLE) + return false; + CScript witscript = GetScriptForWitness(subscript); + pwalletMain->AddCScript(witscript); + result = CScriptID(witscript); + return true; + } + return false; + } +}; + +UniValue addwitnessaddress(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 1 || request.params.size() > 1) + { + string msg = "addwitnessaddress \"address\"\n" + "\nAdd a witness address for a script (with pubkey or redeemscript known).\n" + "It returns the witness script.\n" + + "\nArguments:\n" + "1. \"address\" (string, required) An address known to the wallet\n" + + "\nResult:\n" + "\"witnessaddress\", (string) The value of the new address (P2SH of witness script).\n" + "}\n" + ; + throw runtime_error(msg); + } + + { + LOCK(cs_main); + if (!IsWitnessEnabled(chainActive.Tip(), Params().GetConsensus()) && !GetBoolArg("-walletprematurewitness", false)) { + throw JSONRPCError(RPC_WALLET_ERROR, "Segregated witness not enabled on network"); + } + } + + CBitcoinAddress address(request.params[0].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Ipchain address"); + + Witnessifier w; + CTxDestination dest = address.Get(); + bool ret = boost::apply_visitor(w, dest); + if (!ret) { + throw JSONRPCError(RPC_WALLET_ERROR, "Public key or redeemscript not known to wallet, or the key is uncompressed"); + } + + pwalletMain->SetAddressBook(w.result, "", "receive"); + + return CBitcoinAddress(w.result).ToString(); +} + +struct tallyitem +{ + CAmount nAmount; + int nConf; + vector txids; + bool fIsWatchonly; + tallyitem() + { + nAmount = 0; + nConf = std::numeric_limits::max(); + fIsWatchonly = false; + } +}; + +UniValue ListReceived(const UniValue& params, bool fByAccounts) +{ + // Minimum confirmations + int nMinDepth = 1; + if (params.size() > 0) + nMinDepth = params[0].get_int(); + + // Whether to include empty accounts + bool fIncludeEmpty = false; + if (params.size() > 1) + fIncludeEmpty = params[1].get_bool(); + + isminefilter filter = ISMINE_SPENDABLE; + if(params.size() > 2) + if(params[2].get_bool()) + filter = filter | ISMINE_WATCH_ONLY; + + // Tally + map mapTally; + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + + if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx)) + continue; + + int nDepth = wtx.GetDepthInMainChain(); + if (nDepth < nMinDepth) + continue; + + BOOST_FOREACH(const CTxOut& txout, wtx.tx->vout) + { + CTxDestination address; + if (!ExtractDestination(txout.scriptPubKey, address)) + continue; + + isminefilter mine = IsMine(*pwalletMain, address); + if(!(mine & filter)) + continue; + + tallyitem& item = mapTally[address]; + item.nAmount += txout.nValue; + item.nConf = min(item.nConf, nDepth); + item.txids.push_back(wtx.GetHash()); + if (mine & ISMINE_WATCH_ONLY) + item.fIsWatchonly = true; + } + } + + // Reply + UniValue ret(UniValue::VARR); + map mapAccountTally; + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwalletMain->mapAddressBook) + { + const CBitcoinAddress& address = item.first; + const string& strAccount = item.second.name; + map::iterator it = mapTally.find(address); + if (it == mapTally.end() && !fIncludeEmpty) + continue; + + CAmount nAmount = 0; + int nConf = std::numeric_limits::max(); + bool fIsWatchonly = false; + if (it != mapTally.end()) + { + nAmount = (*it).second.nAmount; + nConf = (*it).second.nConf; + fIsWatchonly = (*it).second.fIsWatchonly; + } + + if (fByAccounts) + { + tallyitem& _item = mapAccountTally[strAccount]; + _item.nAmount += nAmount; + _item.nConf = min(_item.nConf, nConf); + _item.fIsWatchonly = fIsWatchonly; + } + else + { + UniValue obj(UniValue::VOBJ); + if(fIsWatchonly) + obj.push_back(Pair("involvesWatchonly", true)); + obj.push_back(Pair("address", address.ToString())); + obj.push_back(Pair("account", strAccount)); + obj.push_back(Pair("amount", ValueFromAmount(nAmount))); + obj.push_back(Pair("confirmations", (nConf == std::numeric_limits::max() ? 0 : nConf))); + if (!fByAccounts) + obj.push_back(Pair("label", strAccount)); + UniValue transactions(UniValue::VARR); + if (it != mapTally.end()) + { + BOOST_FOREACH(const uint256& _item, (*it).second.txids) + { + transactions.push_back(_item.GetHex()); + } + } + obj.push_back(Pair("txids", transactions)); + ret.push_back(obj); + } + } + + if (fByAccounts) + { + for (map::iterator it = mapAccountTally.begin(); it != mapAccountTally.end(); ++it) + { + CAmount nAmount = (*it).second.nAmount; + int nConf = (*it).second.nConf; + UniValue obj(UniValue::VOBJ); + if((*it).second.fIsWatchonly) + obj.push_back(Pair("involvesWatchonly", true)); + obj.push_back(Pair("account", (*it).first)); + obj.push_back(Pair("amount", ValueFromAmount(nAmount))); + obj.push_back(Pair("confirmations", (nConf == std::numeric_limits::max() ? 0 : nConf))); + ret.push_back(obj); + } + } + + return ret; +} + +UniValue listreceivedbyaddress(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() > 3) + throw runtime_error( + "listreceivedbyaddress ( minconf include_empty include_watchonly)\n" + "\nList balances by receiving address.\n" + "\nArguments:\n" + "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n" + "2. include_empty (bool, optional, default=false) Whether to include addresses that haven't received any payments.\n" + "3. include_watchonly (bool, optional, default=false) Whether to include watch-only addresses (see 'importaddress').\n" + + "\nResult:\n" + "[\n" + " {\n" + " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n" + " \"address\" : \"receivingaddress\", (string) The receiving address\n" + " \"account\" : \"accountname\", (string) DEPRECATED. The account of the receiving address. The default account is \"\".\n" + " \"amount\" : x.xxx, (numeric) The total amount in " + CURRENCY_UNIT + " received by the address\n" + " \"confirmations\" : n, (numeric) The number of confirmations of the most recent transaction included\n" + " \"label\" : \"label\", (string) A comment for the address/transaction, if any\n" + " \"txids\": [\n" + " n, (numeric) The ids of transactions received with the address \n" + " ...\n" + " ]\n" + " }\n" + " ,...\n" + "]\n" + + "\nExamples:\n" + + HelpExampleCli("listreceivedbyaddress", "") + + HelpExampleCli("listreceivedbyaddress", "6 true") + + HelpExampleRpc("listreceivedbyaddress", "6, true, true") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + return ListReceived(request.params, false); +} + +UniValue listreceivedbyaccount(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() > 3) + throw runtime_error( + "listreceivedbyaccount ( minconf include_empty include_watchonly)\n" + "\nDEPRECATED. List balances by account.\n" + "\nArguments:\n" + "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n" + "2. include_empty (bool, optional, default=false) Whether to include accounts that haven't received any payments.\n" + "3. include_watchonly (bool, optional, default=false) Whether to include watch-only addresses (see 'importaddress').\n" + + "\nResult:\n" + "[\n" + " {\n" + " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n" + " \"account\" : \"accountname\", (string) The account name of the receiving account\n" + " \"amount\" : x.xxx, (numeric) The total amount received by addresses with this account\n" + " \"confirmations\" : n, (numeric) The number of confirmations of the most recent transaction included\n" + " \"label\" : \"label\" (string) A comment for the address/transaction, if any\n" + " }\n" + " ,...\n" + "]\n" + + "\nExamples:\n" + + HelpExampleCli("listreceivedbyaccount", "") + + HelpExampleCli("listreceivedbyaccount", "6 true") + + HelpExampleRpc("listreceivedbyaccount", "6, true, true") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + return ListReceived(request.params, true); +} + +static void MaybePushAddress(UniValue & entry, const CTxDestination &dest) +{ + CBitcoinAddress addr; + if (addr.Set(dest)) + entry.push_back(Pair("address", addr.ToString())); +} + +void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter) +{ + CAmount nFee; + string strSentAccount; + list listReceived; + list listSent; + + wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, filter); + + bool fAllAccounts = (strAccount == string("*")); + bool involvesWatchonly = wtx.IsFromMe(ISMINE_WATCH_ONLY); + + // Sent + if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount)) + { + BOOST_FOREACH(const COutputEntry& s, listSent) + { + UniValue entry(UniValue::VOBJ); + if(involvesWatchonly || (::IsMine(*pwalletMain, s.destination) & ISMINE_WATCH_ONLY)) + entry.push_back(Pair("involvesWatchonly", true)); + entry.push_back(Pair("account", strSentAccount)); + MaybePushAddress(entry, s.destination); + entry.push_back(Pair("category", "send")); + entry.push_back(Pair("amount", ValueFromAmount(-s.amount))); + if (pwalletMain->mapAddressBook.count(s.destination)) + entry.push_back(Pair("label", pwalletMain->mapAddressBook[s.destination].name)); + entry.push_back(Pair("vout", s.vout)); + entry.push_back(Pair("fee", ValueFromAmount(-nFee))); + if (fLong) + WalletTxToJSON(wtx, entry); + entry.push_back(Pair("abandoned", wtx.isAbandoned())); + ret.push_back(entry); + } + } + + // Received + if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth) + { + BOOST_FOREACH(const COutputEntry& r, listReceived) + { + string account; + if (pwalletMain->mapAddressBook.count(r.destination)) + account = pwalletMain->mapAddressBook[r.destination].name; + if (fAllAccounts || (account == strAccount)) + { + UniValue entry(UniValue::VOBJ); + if(involvesWatchonly || (::IsMine(*pwalletMain, r.destination) & ISMINE_WATCH_ONLY)) + entry.push_back(Pair("involvesWatchonly", true)); + entry.push_back(Pair("account", account)); + MaybePushAddress(entry, r.destination); + if (wtx.IsCoinBase()) + { + if (wtx.GetDepthInMainChain() < 1) + entry.push_back(Pair("category", "orphan")); + else if (wtx.GetBlocksToMaturity() > 0) + entry.push_back(Pair("category", "immature")); + else + entry.push_back(Pair("category", "generate")); + } + else + { + entry.push_back(Pair("category", "receive")); + } + entry.push_back(Pair("amount", ValueFromAmount(r.amount))); + if (pwalletMain->mapAddressBook.count(r.destination)) + entry.push_back(Pair("label", account)); + entry.push_back(Pair("vout", r.vout)); + if (fLong) + WalletTxToJSON(wtx, entry); + ret.push_back(entry); + } + } + } +} +void ListTransactionsForGetttx(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter) +{ + CAmount nFee; + string strSentAccount; + list listReceived; + list listSent; + + wtx.GetAmountsTokenForGetttx(listReceived, listSent, nFee, strSentAccount, filter); + + bool fAllAccounts = (strAccount == string("*")); + bool involvesWatchonly = wtx.IsFromMe(ISMINE_WATCH_ONLY); + + // Sent + if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount)) + { + BOOST_FOREACH(const COutputEntryToken& s, listSent) + { + UniValue entry(UniValue::VOBJ); + if (involvesWatchonly || (::IsMine(*pwalletMain, s.destination) & ISMINE_WATCH_ONLY)) + entry.push_back(Pair("involvesWatchonly", true)); + entry.push_back(Pair("account", strSentAccount)); + MaybePushAddress(entry, s.destination); + entry.push_back(Pair("category", "send")); + entry.push_back(Pair("amount", ValueFromTCoins(s.value, s.accuracy))); + if (pwalletMain->mapAddressBook.count(s.destination)) + entry.push_back(Pair("label", pwalletMain->mapAddressBook[s.destination].name)); + entry.push_back(Pair("vout", s.vout)); + entry.push_back(Pair("fee", ValueFromAmount(-nFee))); + if (fLong) + WalletTxToJSON(wtx, entry); + entry.push_back(Pair("abandoned", wtx.isAbandoned())); + ret.push_back(entry); + } + } + + // Received + if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth) + { + BOOST_FOREACH(const COutputEntryToken& r, listReceived) + { + string account; + if (pwalletMain->mapAddressBook.count(r.destination)) + account = pwalletMain->mapAddressBook[r.destination].name; + if (fAllAccounts || (account == strAccount)) + { + UniValue entry(UniValue::VOBJ); + if (involvesWatchonly || (::IsMine(*pwalletMain, r.destination) & ISMINE_WATCH_ONLY)) + entry.push_back(Pair("involvesWatchonly", true)); + entry.push_back(Pair("account", account)); + MaybePushAddress(entry, r.destination); + if (wtx.IsCoinBase()) + { + if (wtx.GetDepthInMainChain() < 1) + entry.push_back(Pair("category", "orphan")); + else if (wtx.GetBlocksToMaturity() > 0) + entry.push_back(Pair("category", "immature")); + else + entry.push_back(Pair("category", "generate")); + } + else + { + entry.push_back(Pair("category", "receive")); + } + entry.push_back(Pair("amount", ValueFromTCoins(r.value, r.accuracy))); + if (pwalletMain->mapAddressBook.count(r.destination)) + entry.push_back(Pair("label", account)); + entry.push_back(Pair("vout", r.vout)); + if (fLong) + WalletTxToJSON(wtx, entry); + ret.push_back(entry); + } + } + } +} +void ListTransactions2(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter) +{ + CAmount nFee; + string strSentAccount; + list listReceived; + list listSent; + + wtx.GetAmounts2(listReceived, listSent, nFee, strSentAccount, filter); + + bool fAllAccounts = (strAccount == string("*")); + bool involvesWatchonly = wtx.IsFromMe(ISMINE_WATCH_ONLY); + + // Sent + if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount)) + { + BOOST_FOREACH(const COutputEntry& s, listSent) + { + UniValue entry(UniValue::VOBJ); + if (involvesWatchonly || (::IsMine(*pwalletMain, s.destination) & ISMINE_WATCH_ONLY)) + entry.push_back(Pair("involvesWatchonly", true)); + entry.push_back(Pair("account", strSentAccount)); + MaybePushAddress(entry, s.destination); + entry.push_back(Pair("category", "send")); + entry.push_back(Pair("amount", ValueFromAmount(-s.amount))); + if (pwalletMain->mapAddressBook.count(s.destination)) + entry.push_back(Pair("label", pwalletMain->mapAddressBook[s.destination].name)); + entry.push_back(Pair("vout", s.vout)); + entry.push_back(Pair("fee", ValueFromAmount(-nFee))); + if (fLong) + WalletTxToJSON(wtx, entry); + entry.push_back(Pair("abandoned", wtx.isAbandoned())); + ret.push_back(entry); + } + } + + // Received + if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth) + { + BOOST_FOREACH(const COutputEntry& r, listReceived) + { + string account; + if (pwalletMain->mapAddressBook.count(r.destination)) + account = pwalletMain->mapAddressBook[r.destination].name; + if (fAllAccounts || (account == strAccount)) + { + UniValue entry(UniValue::VOBJ); + if (involvesWatchonly || (::IsMine(*pwalletMain, r.destination) & ISMINE_WATCH_ONLY)) + entry.push_back(Pair("involvesWatchonly", true)); + entry.push_back(Pair("account", account)); + MaybePushAddress(entry, r.destination); + if (wtx.IsCoinBase()) + { + if (wtx.GetDepthInMainChain() < 1) + entry.push_back(Pair("category", "orphan")); + else if (wtx.GetBlocksToMaturity() > 0) + entry.push_back(Pair("category", "immature")); + else + entry.push_back(Pair("category", "generate")); + } + else + { + entry.push_back(Pair("category", "receive")); + } + entry.push_back(Pair("amount", ValueFromAmount(r.amount))); + if (pwalletMain->mapAddressBook.count(r.destination)) + entry.push_back(Pair("label", account)); + entry.push_back(Pair("vout", r.vout)); + if (fLong) + WalletTxToJSON(wtx, entry); + ret.push_back(entry); + } + } + } +} + +void ListTransactionsToken(const std::string& strtokensymbol,const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter) +{ + CAmount nFee; + string strSentAccount; + list listReceived; + list listSent; + + wtx.GetAmountsToken(strtokensymbol,listReceived, listSent, nFee, strSentAccount, filter); + + bool fAllAccounts = (strAccount == string("*")); + bool involvesWatchonly = wtx.IsFromMe(ISMINE_WATCH_ONLY); + + // Sent + if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount)) + { + BOOST_FOREACH(const COutputEntryToken& s, listSent) + { + UniValue entry(UniValue::VOBJ); + if (involvesWatchonly || (::IsMine(*pwalletMain, s.destination) & ISMINE_WATCH_ONLY)) + entry.push_back(Pair("involvesWatchonly", true)); + entry.push_back(Pair("account", strSentAccount)); + MaybePushAddress(entry, s.destination); + entry.push_back(Pair("category", "send")); + entry.push_back(Pair("amount", ValueFromTCoinsN(s.value,s.accuracy)));//token value + if (pwalletMain->mapAddressBook.count(s.destination)) + entry.push_back(Pair("label", pwalletMain->mapAddressBook[s.destination].name)); + entry.push_back(Pair("vout", s.vout)); + entry.push_back(Pair("fee", ValueFromAmount(-nFee))); + if (fLong) + WalletTxToJSON(wtx, entry); + entry.push_back(Pair("abandoned", wtx.isAbandoned())); + ret.push_back(entry); + } + } + + // Received + if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth) + { + BOOST_FOREACH(const COutputEntryToken& r, listReceived) + { + string account; + if (pwalletMain->mapAddressBook.count(r.destination)) + account = pwalletMain->mapAddressBook[r.destination].name; + if (fAllAccounts || (account == strAccount)) + { + UniValue entry(UniValue::VOBJ); + if (involvesWatchonly || (::IsMine(*pwalletMain, r.destination) & ISMINE_WATCH_ONLY)) + entry.push_back(Pair("involvesWatchonly", true)); + entry.push_back(Pair("account", account)); + MaybePushAddress(entry, r.destination); + if (wtx.IsCoinBase()) + { + if (wtx.GetDepthInMainChain() < 1) + entry.push_back(Pair("category", "orphan")); + else if (wtx.GetBlocksToMaturity() > 0) + entry.push_back(Pair("category", "immature")); + else + entry.push_back(Pair("category", "generate")); + } + else + { + entry.push_back(Pair("category", "receive")); + } + entry.push_back(Pair("amount", ValueFromTCoinsN(r.value, r.accuracy))); //token value + if (pwalletMain->mapAddressBook.count(r.destination)) + entry.push_back(Pair("label", account)); + entry.push_back(Pair("vout", r.vout)); + if (fLong) + WalletTxToJSON(wtx, entry); + ret.push_back(entry); + } + } + } +} + +void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, UniValue& ret) +{ + bool fAllAccounts = (strAccount == string("*")); + + if (fAllAccounts || acentry.strAccount == strAccount) + { + UniValue entry(UniValue::VOBJ); + entry.push_back(Pair("account", acentry.strAccount)); + entry.push_back(Pair("category", "move")); + entry.push_back(Pair("time", acentry.nTime)); + entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit))); + entry.push_back(Pair("otheraccount", acentry.strOtherAccount)); + entry.push_back(Pair("comment", acentry.strComment)); + ret.push_back(entry); + } +} + +UniValue listtransactions(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() > 4) + throw runtime_error( + "listtransactions ( \"account\" count skip include_watchonly)\n" + "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n" + "\nArguments:\n" + "1. \"account\" (string, optional) DEPRECATED. The account name. Should be \"*\".\n" + "2. count (numeric, optional, default=10) The number of transactions to return\n" + "3. skip (numeric, optional, default=0) The number of transactions to skip\n" + "4. include_watchonly (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')\n" + "\nResult:\n" + "[\n" + " {\n" + " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. \n" + " It will be \"\" for the default account.\n" + " \"address\":\"address\", (string) The ipchain address of the transaction. Not present for \n" + " move transactions (category = move).\n" + " \"category\":\"send|receive|move\", (string) The transaction category. 'move' is a local (off blockchain)\n" + " transaction between accounts, and not associated with an address,\n" + " transaction id or block. 'send' and 'receive' transactions are \n" + " associated with an address, transaction id and block details\n" + " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the\n" + " 'move' category for moves outbound. It is positive for the 'receive' category,\n" + " and for the 'move' category for inbound funds.\n" + " \"label\": \"label\", (string) A comment for the address/transaction, if any\n" + " \"vout\": n, (numeric) the vout value\n" + " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n" + " 'send' category of transactions.\n" + " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and \n" + " 'receive' category of transactions. Negative confirmations indicate the\n" + " transaction conflicts with the block chain\n" + " \"trusted\": xxx, (bool) Whether we consider the outputs of this unconfirmed transaction safe to spend.\n" + " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive'\n" + " category of transactions.\n" + " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it. Available for 'send' and 'receive'\n" + " category of transactions.\n" + " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n" + " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n" + " \"time\": xxx, (numeric) The transaction time in seconds since epoch (midnight Jan 1 1970 GMT).\n" + " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (midnight Jan 1 1970 GMT). Available \n" + " for 'send' and 'receive' category of transactions.\n" + " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n" + " \"otheraccount\": \"accountname\", (string) DEPRECATED. For the 'move' category of transactions, the account the funds came \n" + " from (for receiving funds, positive amounts), or went to (for sending funds,\n" + " negative amounts).\n" + " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n" + " may be unknown for unconfirmed transactions not in the mempool\n" + " \"abandoned\": xxx (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n" + " 'send' category of transactions.\n" + " }\n" + "]\n" + + "\nExamples:\n" + "\nList the most recent 10 transactions in the systems\n" + + HelpExampleCli("listtransactions", "") + + "\nList transactions 100 to 120\n" + + HelpExampleCli("listtransactions", "\"*\" 20 100") + + "\nAs a json rpc call\n" + + HelpExampleRpc("listtransactions", "\"*\", 20, 100") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + string strAccount = "*"; + if (request.params.size() > 0) + strAccount = request.params[0].get_str(); + int nCount = 10; + if (request.params.size() > 1) + nCount = request.params[1].get_int(); + int nFrom = 0; + if (request.params.size() > 2) + nFrom = request.params[2].get_int(); + isminefilter filter = ISMINE_SPENDABLE; + if(request.params.size() > 3) + if(request.params[3].get_bool()) + filter = filter | ISMINE_WATCH_ONLY; + + if (nCount < 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count"); + if (nFrom < 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from"); + + UniValue ret(UniValue::VARR); + + const CWallet::TxItems & txOrdered = pwalletMain->wtxOrdered; + + // iterate backwards until we have nCount items to return: + for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) + { + CWalletTx *const pwtx = (*it).second.first; + if (pwtx != 0) + ListTransactions2(*pwtx, strAccount, 0, true, ret, filter); + CAccountingEntry *const pacentry = (*it).second.second; + if (pacentry != 0) + AcentryToJSON(*pacentry, strAccount, ret); + + if ((int)ret.size() >= (nCount+nFrom)) break; + } + // ret is newest to oldest + + if (nFrom > (int)ret.size()) + nFrom = ret.size(); + if ((nFrom + nCount) > (int)ret.size()) + nCount = ret.size() - nFrom; + + vector arrTmp = ret.getValues(); + + vector::iterator first = arrTmp.begin(); + std::advance(first, nFrom); + vector::iterator last = arrTmp.begin(); + std::advance(last, nFrom+nCount); + + if (last != arrTmp.end()) arrTmp.erase(last, arrTmp.end()); + if (first != arrTmp.begin()) arrTmp.erase(arrTmp.begin(), first); + + std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest + + ret.clear(); + ret.setArray(); + ret.push_backV(arrTmp); + + return ret; +} + +UniValue listtokentransactions(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) + throw runtime_error( + "listtokentransactions \"tokensymbol\" ( count skip include_watchonly )\n" + "\nReturns most recent transactions skipping the first 'from' transactions for the tokensymbol.\n" + "\nArguments:\n" + "1. \"tokensymbol\" (string, required) The token name. \n" + "2. count (numeric, optional, default=10) The number of transactions to return\n" + "3. skip (numeric, optional, default=0) The number of transactions to skip\n" + "4. include_watchonly (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')\n" + "\nResult:\n" + "[\n" + " {\n" + " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. \n" + " It will be \"\" for the default account.\n" + " \"address\":\"address\", (string) The ipchain address of the transaction. Not present for \n" + " move transactions (category = move).\n" + " \"category\":\"send|receive|move\", (string) The transaction category. 'move' is a local (off blockchain)\n" + " transaction between accounts, and not associated with an address,\n" + " transaction id or block. 'send' and 'receive' transactions are \n" + " associated with an address, transaction id and block details\n" + " \"amount\": x.xxx, (numeric) The amount in tokenLable. This is negative for the 'send' category, and for the\n" + " 'move' category for moves outbound. It is positive for the 'receive' category,\n" + " and for the 'move' category for inbound funds.\n" + " \"label\": \"label\", (string) A comment for the address/transaction, if any\n" + " \"vout\": n, (numeric) the vout value\n" + " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n" + " 'send' category of transactions.\n" + " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and \n" + " 'receive' category of transactions. Negative confirmations indicate the\n" + " transaction conflicts with the block chain\n" + " \"trusted\": xxx, (bool) Whether we consider the outputs of this unconfirmed transaction safe to spend.\n" + " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive'\n" + " category of transactions.\n" + " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it. Available for 'send' and 'receive'\n" + " category of transactions.\n" + " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n" + " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n" + " \"time\": xxx, (numeric) The transaction time in seconds since epoch (midnight Jan 1 1970 GMT).\n" + " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (midnight Jan 1 1970 GMT). Available \n" + " for 'send' and 'receive' category of transactions.\n" + " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n" + " \"otheraccount\": \"accountname\", (string) DEPRECATED. For the 'move' category of transactions, the account the funds came \n" + " from (for receiving funds, positive amounts), or went to (for sending funds,\n" + " negative amounts).\n" + " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n" + " may be unknown for unconfirmed transactions not in the mempool\n" + " \"abandoned\": xxx (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n" + " 'send' category of transactions.\n" + " }\n" + "]\n" + + "\nExamples:\n" + "\nList the most recent 10 transactions in the systems\n" + + HelpExampleCli("listtokentransactions", "") + + "\nList transactions 100 to 120\n" + + HelpExampleCli("listtokentransactions", "tokensymbol 20 100") + + "\nAs a json rpc call\n" + + HelpExampleRpc("listtokentransactions", "tokensymbol, 20, 100") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + string strAccount = "*"; + string strsymbol = ""; + if (request.params.size() > 0) + strsymbol = request.params[0].get_str(); +// if (tokenDataMap.count(strsymbol) == 0) +// throw JSONRPCError(RPC_INVALID_PARAMETER, "No record of this Token!"); + int nCount = 10; + if (request.params.size() > 1) + nCount = request.params[1].get_int(); + int nFrom = 0; + if (request.params.size() > 2) + nFrom = request.params[2].get_int(); + isminefilter filter = ISMINE_SPENDABLE; + if (request.params.size() > 3) + if (request.params[3].get_bool()) + filter = filter | ISMINE_WATCH_ONLY; + + if (nCount < 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count"); + if (nFrom < 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from"); + + UniValue ret(UniValue::VARR); + + const CWallet::TxItems & txOrdered = pwalletMain->wtxOrdered; + + // iterate backwards until we have nCount items to return: + for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) + { + CWalletTx *const pwtx = (*it).second.first; + if (pwtx != 0) + ListTransactionsToken(strsymbol,*pwtx, strAccount, 0, true, ret, filter); + CAccountingEntry *const pacentry = (*it).second.second; + if (pacentry != 0) + AcentryToJSON(*pacentry, strAccount, ret); + + if ((int)ret.size() >= (nCount + nFrom)) break; + } + // ret is newest to oldest + + if (nFrom > (int)ret.size()) + nFrom = ret.size(); + if ((nFrom + nCount) > (int)ret.size()) + nCount = ret.size() - nFrom; + + vector arrTmp = ret.getValues(); + + vector::iterator first = arrTmp.begin(); + std::advance(first, nFrom); + vector::iterator last = arrTmp.begin(); + std::advance(last, nFrom + nCount); + + if (last != arrTmp.end()) arrTmp.erase(last, arrTmp.end()); + if (first != arrTmp.begin()) arrTmp.erase(arrTmp.begin(), first); + + std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest + + ret.clear(); + ret.setArray(); + ret.push_backV(arrTmp); + + return ret; +} + + +UniValue listaccounts(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() > 2) + throw runtime_error( + "listaccounts ( minconf include_watchonly)\n" + "\nDEPRECATED. Returns Object that has account names as keys, account balances as values.\n" + "\nArguments:\n" + "1. minconf (numeric, optional, default=1) Only include transactions with at least this many confirmations\n" + "2. include_watchonly (bool, optional, default=false) Include balances in watch-only addresses (see 'importaddress')\n" + "\nResult:\n" + "{ (json object where keys are account names, and values are numeric balances\n" + " \"account\": x.xxx, (numeric) The property name is the account name, and the value is the total balance for the account.\n" + " ...\n" + "}\n" + "\nExamples:\n" + "\nList account balances where there at least 1 confirmation\n" + + HelpExampleCli("listaccounts", "") + + "\nList account balances including zero confirmation transactions\n" + + HelpExampleCli("listaccounts", "0") + + "\nList account balances for 6 or more confirmations\n" + + HelpExampleCli("listaccounts", "6") + + "\nAs json rpc call\n" + + HelpExampleRpc("listaccounts", "6") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + int nMinDepth = 1; + if (request.params.size() > 0) + nMinDepth = request.params[0].get_int(); + isminefilter includeWatchonly = ISMINE_SPENDABLE; + if(request.params.size() > 1) + if(request.params[1].get_bool()) + includeWatchonly = includeWatchonly | ISMINE_WATCH_ONLY; + + map mapAccountBalances; + BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& entry, pwalletMain->mapAddressBook) { + if (IsMine(*pwalletMain, entry.first) & includeWatchonly) // This address belongs to me + mapAccountBalances[entry.second.name] = 0; + } + + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + CAmount nFee; + string strSentAccount; + list listReceived; + list listSent; + int nDepth = wtx.GetDepthInMainChain(); + if (wtx.GetBlocksToMaturity() > 0 || nDepth < 0) + continue; + wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, includeWatchonly); + mapAccountBalances[strSentAccount] -= nFee; + BOOST_FOREACH(const COutputEntry& s, listSent) + mapAccountBalances[strSentAccount] -= s.amount; + if (nDepth >= nMinDepth) + { + BOOST_FOREACH(const COutputEntry& r, listReceived) + if (pwalletMain->mapAddressBook.count(r.destination)) + mapAccountBalances[pwalletMain->mapAddressBook[r.destination].name] += r.amount; + else + mapAccountBalances[""] += r.amount; + } + } + + const list & acentries = pwalletMain->laccentries; + BOOST_FOREACH(const CAccountingEntry& entry, acentries) + mapAccountBalances[entry.strAccount] += entry.nCreditDebit; + + UniValue ret(UniValue::VOBJ); + BOOST_FOREACH(const PAIRTYPE(string, CAmount)& accountBalance, mapAccountBalances) { + ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second))); + } + return ret; +} + +UniValue listsinceblock(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp) + throw runtime_error( + "listsinceblock ( \"blockhash\" target_confirmations include_watchonly)\n" + "\nGet all transactions in blocks since block [blockhash], or all transactions if omitted\n" + "\nArguments:\n" + "1. \"blockhash\" (string, optional) The block hash to list transactions since\n" + "2. target_confirmations: (numeric, optional) The confirmations required, must be 1 or more\n" + "3. include_watchonly: (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')" + "\nResult:\n" + "{\n" + " \"transactions\": [\n" + " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n" + " \"address\":\"address\", (string) The ipchain address of the transaction. Not present for move transactions (category = move).\n" + " \"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n" + " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the 'move' category for moves \n" + " outbound. It is positive for the 'receive' category, and for the 'move' category for inbound funds.\n" + " \"vout\" : n, (numeric) the vout value\n" + " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the 'send' category of transactions.\n" + " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and 'receive' category of transactions.\n" + " When it's < 0, it means the transaction conflicted that many blocks ago.\n" + " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive' category of transactions.\n" + " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it. Available for 'send' and 'receive' category of transactions.\n" + " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n" + " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n" + " \"time\": xxx, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT).\n" + " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (Jan 1 1970 GMT). Available for 'send' and 'receive' category of transactions.\n" + " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n" + " may be unknown for unconfirmed transactions not in the mempool\n" + " \"abandoned\": xxx, (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the 'send' category of transactions.\n" + " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n" + " \"label\" : \"label\" (string) A comment for the address/transaction, if any\n" + " \"to\": \"...\", (string) If a comment to is associated with the transaction.\n" + " ],\n" + " \"lastblock\": \"lastblockhash\" (string) The hash of the last block\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("listsinceblock", "") + + HelpExampleCli("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\" 6") + + HelpExampleRpc("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\", 6") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + const CBlockIndex *pindex = NULL; + int target_confirms = 1; + isminefilter filter = ISMINE_SPENDABLE; + + if (request.params.size() > 0) + { + uint256 blockId; + + blockId.SetHex(request.params[0].get_str()); + BlockMap::iterator it = mapBlockIndex.find(blockId); + if (it != mapBlockIndex.end()) + { + pindex = it->second; + if (chainActive[pindex->nHeight] != pindex) + { + // the block being asked for is a part of a deactivated chain; + // we don't want to depend on its perceived height in the block + // chain, we want to instead use the last common ancestor + pindex = chainActive.FindFork(pindex); + } + } + } + + if (request.params.size() > 1) + { + target_confirms = request.params[1].get_int(); + + if (target_confirms < 1) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter"); + } + + if (request.params.size() > 2 && request.params[2].get_bool()) + { + filter = filter | ISMINE_WATCH_ONLY; + } + + int depth = pindex ? (1 + chainActive.Height() - pindex->nHeight) : -1; + + UniValue transactions(UniValue::VARR); + + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); it++) + { + CWalletTx tx = (*it).second; + + if (depth == -1 || tx.GetDepthInMainChain() < depth) + ListTransactions(tx, "*", 0, true, transactions, filter); + } + + CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms]; + uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : uint256(); + + UniValue ret(UniValue::VOBJ); + ret.push_back(Pair("transactions", transactions)); + ret.push_back(Pair("lastblock", lastblock.GetHex())); + + return ret; +} + +UniValue gettransaction(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) + throw runtime_error( + "gettransaction \"txid\" ( include_watchonly )\n" + "\nGet detailed information about in-wallet transaction \n" + "\nArguments:\n" + "1. \"txid\" (string, required) The transaction id\n" + "2. \"include_watchonly\" (bool, optional, default=false) Whether to include watch-only addresses in balance calculation and details[]\n" + "\nResult:\n" + "{\n" + " \"amount\" : x.xxx, (numeric) The transaction amount in " + CURRENCY_UNIT + "\n" + " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n" + " 'send' category of transactions.\n" + " \"confirmations\" : n, (numeric) The number of confirmations\n" + " \"blockhash\" : \"hash\", (string) The block hash\n" + " \"blockindex\" : xx, (numeric) The index of the transaction in the block that includes it\n" + " \"blocktime\" : ttt, (numeric) The time in seconds since epoch (1 Jan 1970 GMT)\n" + " \"txid\" : \"transactionid\", (string) The transaction id.\n" + " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (1 Jan 1970 GMT)\n" + " \"timereceived\" : ttt, (numeric) The time received in seconds since epoch (1 Jan 1970 GMT)\n" + " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n" + " may be unknown for unconfirmed transactions not in the mempool\n" + " \"details\" : [\n" + " {\n" + " \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n" + " \"address\" : \"address\", (string) The ipchain address involved in the transaction\n" + " \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n" + " \"amount\" : x.xxx, (numeric) The amount in " + CURRENCY_UNIT + "\n" + " \"label\" : \"label\", (string) A comment for the address/transaction, if any\n" + " \"vout\" : n, (numeric) the vout value\n" + " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n" + " 'send' category of transactions.\n" + " \"abandoned\": xxx (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n" + " 'send' category of transactions.\n" + " }\n" + " ,...\n" + " ],\n" + " \"hex\" : \"data\" (string) Raw data for transaction\n" + "}\n" + + "\nExamples:\n" + + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") + + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\" true") + + HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + uint256 hash; + hash.SetHex(request.params[0].get_str()); + + isminefilter filter = ISMINE_SPENDABLE; + if (request.params.size() > 1) + if (request.params[1].get_bool()) + filter = filter | ISMINE_WATCH_ONLY; + + UniValue entry(UniValue::VOBJ); + if (!pwalletMain->mapWallet.count(hash)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); + const CWalletTx& wtx = pwalletMain->mapWallet[hash]; + + CAmount nCredit = wtx.GetCredit(filter); + CAmount nDebit = wtx.GetDebit(filter); + CAmount nNet = nCredit - nDebit; + CAmount nFee = (wtx.IsFromMe(filter) ? wtx.tx->GetValueOut() - nDebit : 0); + + entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee))); + if (wtx.IsFromMe(filter)) + entry.push_back(Pair("fee", ValueFromAmount(nFee))); + + WalletTxToJSON(wtx, entry); + + UniValue details(UniValue::VARR); + ListTransactions(wtx, "*", 0, false, details, filter); + entry.push_back(Pair("details", details)); + + string strHex = EncodeHexTx(static_cast(wtx), RPCSerializationFlags()); + entry.push_back(Pair("hex", strHex)); + + return entry; +} + +UniValue gettokentransaction(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) + throw runtime_error( + "gettokentransaction \"txid\" ( include_watchonly )\n" + "\nGet detailed information about in-wallet transaction \n" + "\nArguments:\n" + "1. \"txid\" (string, required) The transaction id\n" + "2. \"include_watchonly\" (bool, optional, default=false) Whether to include watch-only addresses in balance calculation and details[]\n" + "\nResult:\n" + "{\n" + " \"amount\" : x.xxx, (numeric) The transaction amount of token.\n" + " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n" + " 'send' category of transactions.\n" + " \"confirmations\" : n, (numeric) The number of confirmations\n" + " \"blockhash\" : \"hash\", (string) The block hash\n" + " \"blockindex\" : xx, (numeric) The index of the transaction in the block that includes it\n" + " \"blocktime\" : ttt, (numeric) The time in seconds since epoch (1 Jan 1970 GMT)\n" + " \"txid\" : \"transactionid\", (string) The transaction id.\n" + " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (1 Jan 1970 GMT)\n" + " \"timereceived\" : ttt, (numeric) The time received in seconds since epoch (1 Jan 1970 GMT)\n" + " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n" + " may be unknown for unconfirmed transactions not in the mempool\n" + " \"details\" : [\n" + " {\n" + " \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n" + " \"address\" : \"address\", (string) The ipchain address involved in the transaction\n" + " \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n" + " \"amount\" : x.xxx, (numeric) The amount of the token.\n" + " \"label\" : \"label\", (string) A comment for the address/transaction, if any\n" + " \"vout\" : n, (numeric) the vout value\n" + " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n" + " 'send' category of transactions.\n" + " \"abandoned\": xxx (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n" + " 'send' category of transactions.\n" + " }\n" + " ,...\n" + " ],\n" + " \"hex\" : \"data\" (string) Raw data for transaction\n" + "}\n" + + "\nExamples:\n" + + HelpExampleCli("gettokentransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") + + HelpExampleCli("gettokentransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\" true") + + HelpExampleRpc("gettokentransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + uint256 hash; + hash.SetHex(request.params[0].get_str()); + + isminefilter filter = ISMINE_SPENDABLE; + if (request.params.size() > 1) + if (request.params[1].get_bool()) + filter = filter | ISMINE_WATCH_ONLY; + + UniValue entry(UniValue::VOBJ); + if (!pwalletMain->mapWallet.count(hash)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); + const CWalletTx& wtx = pwalletMain->mapWallet[hash]; + + CAmount nCredit = wtx.GetCredit(filter); + CAmount nDebit = wtx.GetDebit(filter); + CAmount nNet = nCredit - nDebit; + CAmount nFee = (wtx.IsFromMe(filter) ? wtx.tx->GetValueOut() - nDebit : 0); + + entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee))); + if (wtx.IsFromMe(filter)) + entry.push_back(Pair("fee", ValueFromAmount(nFee))); + + WalletTxToJSON(wtx, entry); + + UniValue details(UniValue::VARR); + ListTransactionsForGetttx(wtx, "*", 0, false, details, filter); + entry.push_back(Pair("details", details)); + + string strHex = EncodeHexTx(static_cast(wtx), RPCSerializationFlags()); + entry.push_back(Pair("hex", strHex)); + + return entry; +} + +UniValue abandontransaction(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "abandontransaction \"txid\"\n" + "\nMark in-wallet transaction as abandoned\n" + "This will mark this transaction and all its in-wallet descendants as abandoned which will allow\n" + "for their inputs to be respent. It can be used to replace \"stuck\" or evicted transactions.\n" + "It only works on transactions which are not included in a block and are not currently in the mempool.\n" + "It has no effect on transactions which are already conflicted or abandoned.\n" + "\nArguments:\n" + "1. \"txid\" (string, required) The transaction id\n" + "\nResult:\n" + "\nExamples:\n" + + HelpExampleCli("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") + + HelpExampleRpc("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + uint256 hash; + hash.SetHex(request.params[0].get_str()); + + if (!pwalletMain->mapWallet.count(hash)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); + if (!pwalletMain->AbandonTransaction(hash)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not eligible for abandonment"); + + return NullUniValue; +} + + +UniValue backupwallet(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "backupwallet \"destination\"\n" + "\nSafely copies current wallet file to destination, which can be a directory or a path with filename.\n" + "\nArguments:\n" + "1. \"destination\" (string) The destination directory or file\n" + "\nExamples:\n" + + HelpExampleCli("backupwallet", "\"backup.dat\"") + + HelpExampleRpc("backupwallet", "\"backup.dat\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + string strDest = request.params[0].get_str(); + if (!pwalletMain->BackupWallet(strDest)) + throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!"); + + return NullUniValue; +} + + +UniValue keypoolrefill(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() > 1) + throw runtime_error( + "keypoolrefill ( newsize )\n" + "\nFills the keypool." + + HelpRequiringPassphrase() + "\n" + "\nArguments\n" + "1. newsize (numeric, optional, default=100) The new keypool size\n" + "\nExamples:\n" + + HelpExampleCli("keypoolrefill", "") + + HelpExampleRpc("keypoolrefill", "") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + // 0 is interpreted by TopUpKeyPool() as the default keypool size given by -keypool + unsigned int kpSize = 0; + if (request.params.size() > 0) { + if (request.params[0].get_int() < 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected valid size."); + kpSize = (unsigned int)request.params[0].get_int(); + } + + EnsureWalletIsUnlocked(); + pwalletMain->TopUpKeyPool(kpSize); + + if (pwalletMain->GetKeyPoolSize() < kpSize) + throw JSONRPCError(RPC_WALLET_ERROR, "Error refreshing keypool."); + + return NullUniValue; +} + + +static void LockWallet(CWallet* pWallet) +{ + LOCK(cs_nWalletUnlockTime); + nWalletUnlockTime = 0; + pWallet->Lock(); +} + +UniValue walletpassphrase(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 2)) + throw runtime_error( + "walletpassphrase \"passphrase\" timeout\n" + "\nStores the wallet decryption key in memory for 'timeout' seconds.\n" + "This is needed prior to performing transactions related to private keys such as sending ipccoins\n" + "\nArguments:\n" + "1. \"passphrase\" (string, required) The wallet passphrase\n" + "2. timeout (numeric, required) The time to keep the decryption key in seconds.\n" + "\nNote:\n" + "Issuing the walletpassphrase command while the wallet is already unlocked will set a new unlock\n" + "time that overrides the old one.\n" + "\nExamples:\n" + "\nunlock the wallet for 60 seconds\n" + + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 60") + + "\nLock the wallet again (before 60 seconds)\n" + + HelpExampleCli("walletlock", "") + + "\nAs json rpc call\n" + + HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + if (request.fHelp) + return true; + if (!pwalletMain->IsCrypted()) + throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrase was called."); + + // Note that the walletpassphrase is stored in request.params[0] which is not mlock()ed + SecureString strWalletPass; + strWalletPass.reserve(100); + // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string) + // Alternately, find a way to make request.params[0] mlock()'d to begin with. + strWalletPass = request.params[0].get_str().c_str(); + + if (strWalletPass.length() > 0) + { + if (!pwalletMain->Unlock(strWalletPass)) + throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect."); + } + else + throw runtime_error( + "walletpassphrase \n" + "Stores the wallet decryption key in memory for seconds."); + + pwalletMain->TopUpKeyPool(); + + int64_t nSleepTime = request.params[1].get_int64(); + LOCK(cs_nWalletUnlockTime); + nWalletUnlockTime = GetTime() + nSleepTime; + RPCRunLater("lockwallet", boost::bind(LockWallet, pwalletMain), nSleepTime); + + return NullUniValue; +} + + +UniValue walletpassphrasechange(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 2)) + throw runtime_error( + "walletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\n" + "\nChanges the wallet passphrase from 'oldpassphrase' to 'newpassphrase'.\n" + "\nArguments:\n" + "1. \"oldpassphrase\" (string) The current passphrase\n" + "2. \"newpassphrase\" (string) The new passphrase\n" + "\nExamples:\n" + + HelpExampleCli("walletpassphrasechange", "\"old one\" \"new one\"") + + HelpExampleRpc("walletpassphrasechange", "\"old one\", \"new one\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + if (request.fHelp) + return true; + if (!pwalletMain->IsCrypted()) + throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrasechange was called."); + + // TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string) + // Alternately, find a way to make request.params[0] mlock()'d to begin with. + SecureString strOldWalletPass; + strOldWalletPass.reserve(100); + strOldWalletPass = request.params[0].get_str().c_str(); + + SecureString strNewWalletPass; + strNewWalletPass.reserve(100); + strNewWalletPass = request.params[1].get_str().c_str(); + + if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1) + throw runtime_error( + "walletpassphrasechange \n" + "Changes the wallet passphrase from to ."); + + if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) + throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect."); + + return NullUniValue; +} + + +UniValue walletlock(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 0)) + throw runtime_error( + "walletlock\n" + "\nRemoves the wallet encryption key from memory, locking the wallet.\n" + "After calling this method, you will need to call walletpassphrase again\n" + "before being able to call any methods which require the wallet to be unlocked.\n" + "\nExamples:\n" + "\nSet the passphrase for 2 minutes to perform a transaction\n" + + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 120") + + "\nPerform a send (requires passphrase set)\n" + + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 1.0") + + "\nClear the passphrase since we are done before 2 minutes is up\n" + + HelpExampleCli("walletlock", "") + + "\nAs json rpc call\n" + + HelpExampleRpc("walletlock", "") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + if (request.fHelp) + return true; + if (!pwalletMain->IsCrypted()) + throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletlock was called."); + + { + LOCK(cs_nWalletUnlockTime); + pwalletMain->Lock(); + nWalletUnlockTime = 0; + } + + return NullUniValue; +} + + +UniValue encryptwallet(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (!pwalletMain->IsCrypted() && (request.fHelp || request.params.size() != 1)) + throw runtime_error( + "encryptwallet \"passphrase\"\n" + "\nEncrypts the wallet with 'passphrase'. This is for first time encryption.\n" + "After this, any calls that interact with private keys such as sending or signing \n" + "will require the passphrase to be set prior the making these calls.\n" + "Use the walletpassphrase call for this, and then walletlock call.\n" + "If the wallet is already encrypted, use the walletpassphrasechange call.\n" + "Note that this will shutdown the server.\n" + "\nArguments:\n" + "1. \"passphrase\" (string) The pass phrase to encrypt the wallet with. It must be at least 1 character, but should be long.\n" + "\nExamples:\n" + "\nEncrypt you wallet\n" + + HelpExampleCli("encryptwallet", "\"my pass phrase\"") + + "\nNow set the passphrase to use the wallet, such as for signing or sending ipccoin\n" + + HelpExampleCli("walletpassphrase", "\"my pass phrase\"") + + "\nNow we can so something like sign\n" + + HelpExampleCli("signmessage", "\"address\" \"test message\"") + + "\nNow lock the wallet again by removing the passphrase\n" + + HelpExampleCli("walletlock", "") + + "\nAs a json rpc call\n" + + HelpExampleRpc("encryptwallet", "\"my pass phrase\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + if (request.fHelp) + return true; + if (pwalletMain->IsCrypted()) + throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an encrypted wallet, but encryptwallet was called."); + + // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string) + // Alternately, find a way to make request.params[0] mlock()'d to begin with. + SecureString strWalletPass; + strWalletPass.reserve(100); + strWalletPass = request.params[0].get_str().c_str(); + + if (strWalletPass.length() < 1) + throw runtime_error( + "encryptwallet \n" + "Encrypts the wallet with ."); + + if (!pwalletMain->EncryptWallet(strWalletPass)) + throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: Failed to encrypt the wallet."); + + // BDB seems to have a bad habit of writing old data into + // slack space in .dat files; that is bad if the old data is + // unencrypted private keys. So: + StartShutdown(); + return "wallet encrypted; Ipchain server stopping, restart to run with encrypted wallet. The keypool has been flushed and a new HD seed was generated (if you are using HD). You need to make a new backup."; +} + +UniValue lockunspent(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) + throw runtime_error( + "lockunspent unlock ([{\"txid\":\"txid\",\"vout\":n},...])\n" + "\nUpdates list of temporarily unspendable outputs.\n" + "Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.\n" + "If no transaction outputs are specified when unlocking then all current locked transaction outputs are unlocked.\n" + "A locked transaction output will not be chosen by automatic coin selection, when spending ipccoins.\n" + "Locks are stored in memory only. Nodes start with zero locked outputs, and the locked output list\n" + "is always cleared (by virtue of process exit) when a node stops or fails.\n" + "Also see the listunspent call\n" + "\nArguments:\n" + "1. unlock (boolean, required) Whether to unlock (true) or lock (false) the specified transactions\n" + "2. \"transactions\" (string, optional) A json array of objects. Each object the txid (string) vout (numeric)\n" + " [ (json array of json objects)\n" + " {\n" + " \"txid\":\"id\", (string) The transaction id\n" + " \"vout\": n (numeric) The output number\n" + " }\n" + " ,...\n" + " ]\n" + + "\nResult:\n" + "true|false (boolean) Whether the command was successful or not\n" + + "\nExamples:\n" + "\nList the unspent transactions\n" + + HelpExampleCli("listunspent", "") + + "\nLock an unspent transaction\n" + + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") + + "\nList the locked transactions\n" + + HelpExampleCli("listlockunspent", "") + + "\nUnlock the transaction again\n" + + HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") + + "\nAs a json rpc call\n" + + HelpExampleRpc("lockunspent", "false, \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + if (request.params.size() == 1) + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VBOOL)); + else + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VBOOL)(UniValue::VARR)); + + bool fUnlock = request.params[0].get_bool(); + + if (request.params.size() == 1) { + if (fUnlock) + pwalletMain->UnlockAllCoins(); + return true; + } + + UniValue outputs = request.params[1].get_array(); + for (unsigned int idx = 0; idx < outputs.size(); idx++) { + const UniValue& output = outputs[idx]; + if (!output.isObject()) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object"); + const UniValue& o = output.get_obj(); + + RPCTypeCheckObj(o, + { + {"txid", UniValueType(UniValue::VSTR)}, + {"vout", UniValueType(UniValue::VNUM)}, + }); + + string txid = find_value(o, "txid").get_str(); + if (!IsHex(txid)) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected hex txid"); + + int nOutput = find_value(o, "vout").get_int(); + if (nOutput < 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive"); + + COutPoint outpt(uint256S(txid), nOutput); + + if (fUnlock) + pwalletMain->UnlockCoin(outpt); + else + pwalletMain->LockCoin(outpt); + } + + return true; +} + +UniValue listlockunspent(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() > 0) + throw runtime_error( + "listlockunspent\n" + "\nReturns list of temporarily unspendable outputs.\n" + "See the lockunspent call to lock and unlock transactions for spending.\n" + "\nResult:\n" + "[\n" + " {\n" + " \"txid\" : \"transactionid\", (string) The transaction id locked\n" + " \"vout\" : n (numeric) The vout value\n" + " }\n" + " ,...\n" + "]\n" + "\nExamples:\n" + "\nList the unspent transactions\n" + + HelpExampleCli("listunspent", "") + + "\nLock an unspent transaction\n" + + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") + + "\nList the locked transactions\n" + + HelpExampleCli("listlockunspent", "") + + "\nUnlock the transaction again\n" + + HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") + + "\nAs a json rpc call\n" + + HelpExampleRpc("listlockunspent", "") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + vector vOutpts; + pwalletMain->ListLockedCoins(vOutpts); + + UniValue ret(UniValue::VARR); + + BOOST_FOREACH(COutPoint &outpt, vOutpts) { + UniValue o(UniValue::VOBJ); + + o.push_back(Pair("txid", outpt.hash.GetHex())); + o.push_back(Pair("vout", (int)outpt.n)); + ret.push_back(o); + } + + return ret; +} + +UniValue settxfee(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 1 || request.params.size() > 1) + throw runtime_error( + "settxfee amount\n" + "\nSet the transaction fee per kB. Overwrites the paytxfee parameter.\n" + "\nArguments:\n" + "1. amount (numeric or string, required) The transaction fee in " + CURRENCY_UNIT + "/kB\n" + "\nResult\n" + "true|false (boolean) Returns true if successful\n" + "\nExamples:\n" + + HelpExampleCli("settxfee", "0.00001") + + HelpExampleRpc("settxfee", "0.00001") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + // Amount + CAmount nAmount = AmountFromValue(request.params[0]); + + payTxFee = CFeeRate(nAmount, 1000); + return true; +} + +UniValue getwalletinfo(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() != 0) + throw runtime_error( + "getwalletinfo\n" + "Returns an object containing various wallet state info.\n" + "\nResult:\n" + "{\n" + " \"walletversion\": xxxxx, (numeric) the wallet version\n" + " \"balance\": xxxxxxx, (numeric) the total confirmed balance of the wallet in " + CURRENCY_UNIT + "\n" + " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed balance of the wallet in " + CURRENCY_UNIT + "\n" + " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet in " + CURRENCY_UNIT + "\n" + " \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n" + " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since Unix epoch) of the oldest pre-generated key in the key pool\n" + " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n" + " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n" + " \"paytxfee\": x.xxxx, (numeric) the transaction fee configuration, set in " + CURRENCY_UNIT + "/kB\n" + " \"hdmasterkeyid\": \"\" (string) the Hash160 of the HD master pubkey\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("getwalletinfo", "") + + HelpExampleRpc("getwalletinfo", "") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + UniValue obj(UniValue::VOBJ); + obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); + obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); + obj.push_back(Pair("unconfirmed_balance", ValueFromAmount(pwalletMain->GetUnconfirmedBalance()))); + obj.push_back(Pair("immature_balance", ValueFromAmount(pwalletMain->GetImmatureBalance()))); + obj.push_back(Pair("txcount", (int)pwalletMain->mapWallet.size())); + obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime())); + obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize())); + if (pwalletMain->IsCrypted()) + obj.push_back(Pair("unlocked_until", nWalletUnlockTime)); + obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK()))); + CKeyID masterKeyID = pwalletMain->GetHDChain().masterKeyID; + if (!masterKeyID.IsNull()) + obj.push_back(Pair("hdmasterkeyid", masterKeyID.GetHex())); + return obj; +} + +UniValue resendwallettransactions(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() != 0) + throw runtime_error( + "resendwallettransactions\n" + "Immediately re-broadcast unconfirmed wallet transactions to all peers.\n" + "Intended only for testing; the wallet code periodically re-broadcasts\n" + "automatically.\n" + "Returns array of transaction ids that were re-broadcast.\n" + ); + + if (!g_connman) + throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + std::vector txids = pwalletMain->ResendWalletTransactionsBefore(GetTime(), g_connman.get()); + UniValue result(UniValue::VARR); + BOOST_FOREACH(const uint256& txid, txids) + { + result.push_back(txid.ToString()); + } + return result; +} + +UniValue listunspent(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() > 4) + throw runtime_error( + "listunspent ( minconf maxconf [\"addresses\",...] [include_unsafe] )\n" + "\nReturns array of unspent transaction outputs\n" + "with between minconf and maxconf (inclusive) confirmations.\n" + "Optionally filter to only include txouts paid to specified addresses.\n" + "\nArguments:\n" + "1. minconf (numeric, optional, default=8) The minimum confirmations to filter\n" + "2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n" + "3. \"addresses\" (string) A json array of ipchain addresses to filter\n" + " [\n" + " \"address\" (string) Ipchain address\n" + " ,...\n" + " ]\n" + "4. include_unsafe (bool, optional, default=true) Include outputs that are not safe to spend\n" + " because they come from unconfirmed untrusted transactions or unconfirmed\n" + " replacement transactions (cases where we are less sure that a conflicting\n" + " transaction won't be mined).\n" + "\nResult\n" + "[ (array of json object)\n" + " {\n" + " \"txid\" : \"txid\", (string) the transaction id \n" + " \"vout\" : n, (numeric) the vout value\n" + " \"address\" : \"address\", (string) the ipchain address\n" + " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n" + " \"scriptPubKey\" : \"key\", (string) the script key\n" + " \"amount\" : x.xxx, (numeric) the transaction output amount in " + CURRENCY_UNIT + "\n" + " \"confirmations\" : n, (numeric) The number of confirmations\n" + " \"redeemScript\" : n (string) The redeemScript if scriptPubKey is P2SH\n" + " \"spendable\" : xxx, (bool) Whether we have the private keys to spend this output\n" + " \"solvable\" : xxx (bool) Whether we know how to spend this output, ignoring the lack of keys\n" + " }\n" + " ,...\n" + "]\n" + + "\nExamples\n" + + HelpExampleCli("listunspent", "") + + HelpExampleCli("listunspent", "6 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") + + HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") + ); + + int nMinDepth = 1; + if (request.params.size() > 0 && !request.params[0].isNull()) { + RPCTypeCheckArgument(request.params[0], UniValue::VNUM); + nMinDepth = request.params[0].get_int(); + } + + int nMaxDepth = 9999999; + if (request.params.size() > 1 && !request.params[1].isNull()) { + RPCTypeCheckArgument(request.params[1], UniValue::VNUM); + nMaxDepth = request.params[1].get_int(); + } + + set setAddress; + if (request.params.size() > 2 && !request.params[2].isNull()) { + RPCTypeCheckArgument(request.params[2], UniValue::VARR); + UniValue inputs = request.params[2].get_array(); + for (unsigned int idx = 0; idx < inputs.size(); idx++) { + const UniValue& input = inputs[idx]; + CBitcoinAddress address(input.get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Ipchain address: ")+input.get_str()); + if (setAddress.count(address)) + throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+input.get_str()); + setAddress.insert(address); + } + } + + bool include_unsafe = true; + if (request.params.size() > 3 && !request.params[3].isNull()) { + RPCTypeCheckArgument(request.params[3], UniValue::VBOOL); + include_unsafe = request.params[3].get_bool(); + } + + UniValue results(UniValue::VARR); + vector vecOutputs; + assert(pwalletMain != NULL); + LOCK2(cs_main, pwalletMain->cs_wallet); + pwalletMain->AvailableNormalCoins(vecOutputs, !include_unsafe, NULL, true); + BOOST_FOREACH(const COutput& out, vecOutputs) { + if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth) + continue; + + CTxDestination address; + const CScript& scriptPubKey = out.tx->tx->vout[out.i].scriptPubKey; + bool fValidAddress = ExtractDestination(scriptPubKey, address); + + if (setAddress.size() && (!fValidAddress || !setAddress.count(address))) + continue; + + UniValue entry(UniValue::VOBJ); + entry.push_back(Pair("txid", out.tx->GetHash().GetHex())); + entry.push_back(Pair("vout", out.i)); + + if (fValidAddress) { + entry.push_back(Pair("address", CBitcoinAddress(address).ToString())); + + if (pwalletMain->mapAddressBook.count(address)) + entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name)); + + if (scriptPubKey.IsPayToScriptHash()) { + const CScriptID& hash = boost::get(address); + CScript redeemScript; + if (pwalletMain->GetCScript(hash, redeemScript)) + entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end()))); + } + } + + entry.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end()))); + entry.push_back(Pair("amount", ValueFromAmount(out.tx->tx->vout[out.i].nValue))); + entry.push_back(Pair("confirmations", out.nDepth)); + entry.push_back(Pair("spendable", out.fSpendable)); + entry.push_back(Pair("solvable", out.fSolvable)); + results.push_back(entry); + } + + return results; +} + +//add by xxy +UniValue listunspentNormal(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() > 4) + throw runtime_error( + "listunspentNormal ( minconf maxconf [\"addresses\",...] [include_unsafe] )\n" + "\nReturns array of unspent transaction outputs\n" + "with between minconf and maxconf (inclusive) confirmations.\n" + "Optionally filter to only include txouts paid to specified addresses.\n" + "\nArguments:\n" + "1. minconf (numeric, optional, default=8) The minimum confirmations to filter\n" + "2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n" + "3. \"addresses\" (string) A json array of ipchain addresses to filter\n" + " [\n" + " \"address\" (string) Ipchain address\n" + " ,...\n" + " ]\n" + "4. include_unsafe (bool, optional, default=true) Include outputs that are not safe to spend\n" + " because they come from unconfirmed untrusted transactions or unconfirmed\n" + " replacement transactions (cases where we are less sure that a conflicting\n" + " transaction won't be mined).\n" + "\nResult\n" + "[ (array of json object)\n" + " {\n" + " \"txid\" : \"txid\", (string) the transaction id \n" + " \"vout\" : n, (numeric) the vout value\n" + " \"address\" : \"address\", (string) the ipchain address\n" + " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n" + " \"scriptPubKey\" : \"key\", (string) the script key\n" + " \"amount\" : x.xxx, (numeric) the transaction output amount in " + CURRENCY_UNIT + "\n" + " \"confirmations\" : n, (numeric) The number of confirmations\n" + " \"redeemScript\" : n (string) The redeemScript if scriptPubKey is P2SH\n" + " \"spendable\" : xxx, (bool) Whether we have the private keys to spend this output\n" + " \"solvable\" : xxx (bool) Whether we know how to spend this output, ignoring the lack of keys\n" + " }\n" + " ,...\n" + "]\n" + + "\nExamples\n" + + HelpExampleCli("listunspentNormal", "") + + HelpExampleCli("listunspentNormal", "6 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") + + HelpExampleRpc("listunspentNormal", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") + ); + + int nMinDepth = 1; + if (request.params.size() > 0 && !request.params[0].isNull()) { + RPCTypeCheckArgument(request.params[0], UniValue::VNUM); + nMinDepth = request.params[0].get_int(); + } + + int nMaxDepth = 9999999; + if (request.params.size() > 1 && !request.params[1].isNull()) { + RPCTypeCheckArgument(request.params[1], UniValue::VNUM); + nMaxDepth = request.params[1].get_int(); + } + + set setAddress; + if (request.params.size() > 2 && !request.params[2].isNull()) { + RPCTypeCheckArgument(request.params[2], UniValue::VARR); + UniValue inputs = request.params[2].get_array(); + for (unsigned int idx = 0; idx < inputs.size(); idx++) { + const UniValue& input = inputs[idx]; + CBitcoinAddress address(input.get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Ipchain address: ") + input.get_str()); + if (setAddress.count(address)) + throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ") + input.get_str()); + setAddress.insert(address); + } + } + + bool include_unsafe = true; + if (request.params.size() > 3 && !request.params[3].isNull()) { + RPCTypeCheckArgument(request.params[3], UniValue::VBOOL); + include_unsafe = request.params[3].get_bool(); + } + + UniValue results(UniValue::VARR); + vector vecOutputs; + assert(pwalletMain != NULL); + LOCK2(cs_main, pwalletMain->cs_wallet); + pwalletMain->AvailableNormalCoins(vecOutputs, !include_unsafe, NULL, true); + BOOST_FOREACH(const COutput& out, vecOutputs) { + if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth) + continue; + + CTxDestination address; + const CScript& scriptPubKey = out.tx->tx->vout[out.i].scriptPubKey; + bool fValidAddress = ExtractDestination(scriptPubKey, address); + + if (setAddress.size() && (!fValidAddress || !setAddress.count(address))) + continue; + + UniValue entry(UniValue::VOBJ); + entry.push_back(Pair("txid", out.tx->GetHash().GetHex())); + entry.push_back(Pair("vout", out.i)); + + if (fValidAddress) { + entry.push_back(Pair("address", CBitcoinAddress(address).ToString())); + + if (pwalletMain->mapAddressBook.count(address)) + entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name)); + + if (scriptPubKey.IsPayToScriptHash()) { + const CScriptID& hash = boost::get(address); + CScript redeemScript; + if (pwalletMain->GetCScript(hash, redeemScript)) + entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end()))); + } + } + + entry.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end()))); + entry.push_back(Pair("amount", ValueFromAmount(out.tx->tx->vout[out.i].nValue))); + entry.push_back(Pair("confirmations", out.nDepth)); + entry.push_back(Pair("spendable", out.fSpendable)); + entry.push_back(Pair("solvable", out.fSolvable)); + results.push_back(entry); + } + + return results; +} + +UniValue listunspentIPC(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() > 4) + throw runtime_error( + "listunspentIPC ( minconf maxconf [\"addresses\",...] [include_unsafe] )\n" + "\nReturns array of unspent transaction outputs\n" + "with between minconf and maxconf (inclusive) confirmations.\n" + "Optionally filter to only include txouts paid to specified addresses.\n" + "\nArguments:\n" + "1. minconf (numeric, optional, default=8) The minimum confirmations to filter\n" + "2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n" + "3. \"addresses\" (string) A json array of ipchain addresses to filter\n" + " [\n" + " \"address\" (string) Ipchain address\n" + " ,...\n" + " ]\n" + "4. include_unsafe (bool, optional, default=true) Include outputs that are not safe to spend\n" + " because they come from unconfirmed untrusted transactions or unconfirmed\n" + " replacement transactions (cases where we are less sure that a conflicting\n" + " transaction won't be mined).\n" + "\nResult\n" + "[ (array of json object)\n" + " {\n" + " \"txid\" : \"txid\", (string) the transaction id \n" + " \"vout\" : n, (numeric) the vout value\n" + " \"address\" : \"address\", (string) the ipchain address\n" + " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n" + " \"scriptPubKey\" : \"key\", (string) the script key\n" + " \"amount\" : x.xxx, (numeric) the transaction output amount in " + CURRENCY_UNIT + "\n" + " \"confirmations\" : n, (numeric) The number of confirmations\n" + " \"redeemScript\" : n (string) The redeemScript if scriptPubKey is P2SH\n" + " \"spendable\" : xxx, (bool) Whether we have the private keys to spend this output\n" + " \"solvable\" : xxx (bool) Whether we know how to spend this output, ignoring the lack of keys\n" + " }\n" + " ,...\n" + "]\n" + + "\nExamples\n" + + HelpExampleCli("listunspentIPC", "") + + HelpExampleCli("listunspentIPC", "6 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") + + HelpExampleRpc("listunspentIPC", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") + ); + + int nMinDepth = 1; + if (request.params.size() > 0 && !request.params[0].isNull()) { + RPCTypeCheckArgument(request.params[0], UniValue::VNUM); + nMinDepth = request.params[0].get_int(); + } + + int nMaxDepth = 9999999; + if (request.params.size() > 1 && !request.params[1].isNull()) { + RPCTypeCheckArgument(request.params[1], UniValue::VNUM); + nMaxDepth = request.params[1].get_int(); + } + + set setAddress; + if (request.params.size() > 2 && !request.params[2].isNull()) { + RPCTypeCheckArgument(request.params[2], UniValue::VARR); + UniValue inputs = request.params[2].get_array(); + for (unsigned int idx = 0; idx < inputs.size(); idx++) { + const UniValue& input = inputs[idx]; + CBitcoinAddress address(input.get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Ipchain address: ") + input.get_str()); + if (setAddress.count(address)) + throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ") + input.get_str()); + setAddress.insert(address); + } + } + + bool include_unsafe = true; + if (request.params.size() > 3 && !request.params[3].isNull()) { + RPCTypeCheckArgument(request.params[3], UniValue::VBOOL); + include_unsafe = request.params[3].get_bool(); + } + + UniValue results(UniValue::VARR); + vector vecOutputs; + assert(pwalletMain != NULL); + LOCK2(cs_main, pwalletMain->cs_wallet); + pwalletMain->AvailableIPCCoins(vecOutputs, !include_unsafe, NULL, true); + BOOST_FOREACH(const COutput& out, vecOutputs) { + if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth) + continue; + if (out.nDepthtx->vout[out.i].scriptPubKey; + bool fValidAddress = ExtractDestination(scriptPubKey, address); + + if (setAddress.size() && (!fValidAddress || !setAddress.count(address))) + continue; + + UniValue entry(UniValue::VOBJ); + entry.push_back(Pair("txid", out.tx->GetHash().GetHex())); + entry.push_back(Pair("vout", out.i)); + entry.push_back(make_pair("UTXOType", out.GetType())); + entry.push_back(make_pair("GetIPCExtendType", out.GetIPCExtendType())); + entry.push_back(make_pair("GetIPCStartTime", out.GetIPCStartTime())); + entry.push_back(make_pair("GetIPCStopTime", out.GetIPCStopTime())); + entry.push_back(make_pair("GetIPCHash", out.GetIPCHash())); + entry.push_back(make_pair("GetIPCTitle", out.GetIPCTitle())); + entry.push_back(make_pair("GetIPCLabel", out.GetIPCLabel())); + entry.push_back(make_pair("CanBeSentToOhter", out.CanBeSentToOhter())); + entry.push_back(make_pair("CanBeAuthorizedToOther", out.CanBeAuthorizedToOther())); + entry.push_back(make_pair("CanBeUniqueAuthorizedToOther", out.CanBeUniqueAuthorizedToOther())); + + if (fValidAddress) { + entry.push_back(Pair("address", CBitcoinAddress(address).ToString())); + + if (pwalletMain->mapAddressBook.count(address)) + entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name)); + + if (scriptPubKey.IsPayToScriptHash()) { + const CScriptID& hash = boost::get(address); + CScript redeemScript; + if (pwalletMain->GetCScript(hash, redeemScript)) + entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end()))); + } + } + + entry.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end()))); + entry.push_back(Pair("amount", ValueFromAmount(out.tx->tx->vout[out.i].nValue))); + entry.push_back(Pair("confirmations", out.nDepth)); + entry.push_back(Pair("spendable", out.fSpendable)); + entry.push_back(Pair("solvable", out.fSolvable)); + results.push_back(entry); + } + + return results; +} +UniValue listtokencoins(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() > 1 || request.params.size() < 1) + throw runtime_error( + "listtokencoins \"tokensymbol\"\n" + "\nReturns the value of tokensymbol balance \n" + "\nArguments:\n" + "1. tokensymbol (string) The tokensymbol\n" + "\nResult\n" + "[ (array of json object)\n" + " {\n" + " \"symbol\" : \"symbol\", (string) the TokenSymbol id \n" + " \"balance\" : n, (numeric) the value of tokensymbol\n" + " }\n" + " ,...\n" + "]\n" + + "\nExamples\n" + + HelpExampleCli("listtokencoins", "tokensymbol") + ); + std::string tokensymbol = request.params[0].get_str(); + uint64_t balance = 0; + bool getbalanceYet = pwalletMain->GetSymbolbalance(tokensymbol, balance); + if (!getbalanceYet) + throw JSONRPCError(RPC_DATABASE_ERROR, string("Can't find the balance of the tokensymbol!")); + UniValue results(UniValue::VOBJ); + results.push_back(Pair("Tokensymbol", tokensymbol)); + results.push_back(Pair("balance", ValueFromTCoinsN(balance, (int)tokenDataMap[tokensymbol].accuracy))); + + return results; +} + +UniValue gettokenbalance(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() > 1 || request.params.size() < 1) + throw runtime_error( + "gettokenbalance \"tokensymbol\" \n" + "\nReturns the value of tokensymbol balance \n" + "\nArguments:\n" + "1. tokensymbol (string) The tokensymbol\n" + "\nResult\n" + "balance (numeric) The balance of the tokensymbol.\n" + "\nExamples\n" + + HelpExampleCli("gettokenbalance", "tokensymbol") + ); + std::string tokensymbol = request.params[0].get_str(); + uint64_t balance = 0; + bool getbalanceYet = pwalletMain->GetSymbolbalance(tokensymbol, balance); + if (!getbalanceYet) + throw JSONRPCError(RPC_DATABASE_ERROR, string("Can't find the balance of the tokensymbol!")); + + return ValueFromTCoinsN(balance, (int)tokenDataMap[tokensymbol].accuracy); +} + +UniValue listunspentToken(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() > 4) + throw runtime_error( + "listunspentToken ( minconf maxconf [\"addresses\",...] [include_unsafe] )\n" + "\nReturns array of unspent transaction outputs\n" + "with between minconf and maxconf (inclusive) confirmations.\n" + "Optionally filter to only include txouts paid to specified addresses.\n" + "\nArguments:\n" + "1. minconf (numeric, optional, default=1) The minimum confirmations to filter\n" + "2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n" + "3. \"addresses\" (string) A json array of ipchain addresses to filter\n" + " [\n" + " \"address\" (string) Ipchain address\n" + " ,...\n" + " ]\n" + "4. include_unsafe (bool, optional, default=true) Include outputs that are not safe to spend\n" + " because they come from unconfirmed untrusted transactions or unconfirmed\n" + " replacement transactions (cases where we are less sure that a conflicting\n" + " transaction won't be mined).\n" + "\nResult\n" + "[ (array of json object)\n" + " {\n" + " \"txid\" : \"txid\", (string) the transaction id \n" + " \"vout\" : n, (numeric) the vout value\n" + " \"TokenSymbol\" : \"symbol\", (string) the token symbol\n" + " \"tokenvalue\" : \"value\", (numeric) the transaction output token value\n" + " \"TokenAccuracy\" : \"accuracy\", (numeric) the token accuracy\n" + " \"address\" : \"address\", (string) the ipchain address\n" + " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n" + " \"scriptPubKey\" : \"key\", (string) the script key\n" + " \"amount\" : x.xxx, (numeric) the transaction output amount in " + CURRENCY_UNIT + "\n" + " \"confirmations\" : n, (numeric) The number of confirmations\n" + " \"redeemScript\" : n (string) The redeemScript if scriptPubKey is P2SH\n" + " \"spendable\" : xxx, (bool) Whether we have the private keys to spend this output\n" + " \"solvable\" : xxx (bool) Whether we know how to spend this output, ignoring the lack of keys\n" + " }\n" + " ,...\n" + "]\n" + + "\nExamples\n" + + HelpExampleCli("listunspentToken", "") + + HelpExampleCli("listunspentToken", "6 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") + + HelpExampleRpc("listunspentToken", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") + ); + + int nMinDepth = 1; + if (request.params.size() > 0 && !request.params[0].isNull()) { + RPCTypeCheckArgument(request.params[0], UniValue::VNUM); + nMinDepth = request.params[0].get_int(); + } + + int nMaxDepth = 9999999; + if (request.params.size() > 1 && !request.params[1].isNull()) { + RPCTypeCheckArgument(request.params[1], UniValue::VNUM); + nMaxDepth = request.params[1].get_int(); + } + + set setAddress; + if (request.params.size() > 2 && !request.params[2].isNull()) { + RPCTypeCheckArgument(request.params[2], UniValue::VARR); + UniValue inputs = request.params[2].get_array(); + for (unsigned int idx = 0; idx < inputs.size(); idx++) { + const UniValue& input = inputs[idx]; + CBitcoinAddress address(input.get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Ipchain address: ") + input.get_str()); + if (setAddress.count(address)) + throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ") + input.get_str()); + setAddress.insert(address); + } + } + + bool include_unsafe = true; + if (request.params.size() > 3 && !request.params[3].isNull()) { + RPCTypeCheckArgument(request.params[3], UniValue::VBOOL); + include_unsafe = request.params[3].get_bool(); + } + + UniValue results(UniValue::VARR); + vector vecOutputs; + assert(pwalletMain != NULL); + LOCK2(cs_main, pwalletMain->cs_wallet); + pwalletMain->AvailableTokenCoins(vecOutputs, !include_unsafe, NULL, true); + BOOST_FOREACH(const COutput& out, vecOutputs) { + if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth) + continue; + + if (out.nDepth < nTxConfirmTarget) + continue; + CTxDestination address; + const CScript& scriptPubKey = out.tx->tx->vout[out.i].scriptPubKey; + bool fValidAddress = ExtractDestination(scriptPubKey, address); + + if (setAddress.size() && (!fValidAddress || !setAddress.count(address))) + continue; + + UniValue entry(UniValue::VOBJ); + entry.push_back(Pair("txid", out.tx->GetHash().GetHex())); + entry.push_back(Pair("vout", out.i)); + entry.push_back(Pair("TokenSymbol", out.GetTokenSymbol())); + entry.push_back(Pair("tokenvalue", ValueFromTCoinsN(out.GetTokenvalue(), (int)out.GetTokenAccuracy()))); + entry.push_back(Pair("TokenAccuracy", out.GetTokenAccuracy())); + + if (fValidAddress) { + entry.push_back(Pair("address", CBitcoinAddress(address).ToString())); + + if (pwalletMain->mapAddressBook.count(address)) + entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name)); + + if (scriptPubKey.IsPayToScriptHash()) { + const CScriptID& hash = boost::get(address); + CScript redeemScript; + if (pwalletMain->GetCScript(hash, redeemScript)) + entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end()))); + } + } + + entry.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end()))); + entry.push_back(Pair("amount", ValueFromAmount(out.tx->tx->vout[out.i].nValue))); + entry.push_back(Pair("confirmations", out.nDepth)); + entry.push_back(Pair("spendable", out.fSpendable)); + entry.push_back(Pair("solvable", out.fSolvable)); + results.push_back(entry); + } + + return results; +} +//end +UniValue fundrawtransaction(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) + throw runtime_error( + "fundrawtransaction \"hexstring\" ( options )\n" + "\nAdd inputs to a transaction until it has enough in value to meet its out value.\n" + "This will not modify existing inputs, and will add at most one change output to the outputs.\n" + "No existing outputs will be modified unless \"subtractFeeFromOutputs\" is specified.\n" + "Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n" + "The inputs added will not be signed, use signrawtransaction for that.\n" + "Note that all existing inputs must have their previous output transaction be in the wallet.\n" + "Note that all inputs selected must be of standard form and P2SH scripts must be\n" + "in the wallet using importaddress or addmultisigaddress (to calculate fees).\n" + "You can see whether this is the case by checking the \"solvable\" field in the listunspent output.\n" + "Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only\n" + "\nArguments:\n" + "1. \"hexstring\" (string, required) The hex string of the raw transaction\n" + "2. options (object, optional)\n" + " {\n" + " \"changeAddress\" (string, optional, default pool address) The ipchain address to receive the change\n" + " \"changePosition\" (numeric, optional, default random) The index of the change output\n" + " \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n" + " \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n" + " \"reserveChangeKey\" (boolean, optional, default true) Reserves the change output key from the keypool\n" + " \"feeRate\" (numeric, optional, default not set: makes wallet determine the fee) Set a specific feerate (" + CURRENCY_UNIT + " per KB)\n" + " \"subtractFeeFromOutputs\" (array, optional) A json array of integers.\n" + " The fee will be equally deducted from the amount of each specified output.\n" + " The outputs are specified by their zero-based index, before any change output is added.\n" + " Those recipients will receive less ipccoins than you enter in their corresponding amount field.\n" + " If no outputs are specified here, the sender pays the fee.\n" + " [vout_index,...]\n" + " }\n" + " for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n" + "\nResult:\n" + "{\n" + " \"hex\": \"value\", (string) The resulting raw transaction (hex-encoded string)\n" + " \"fee\": n, (numeric) Fee in " + CURRENCY_UNIT + " the resulting transaction pays\n" + " \"changepos\": n (numeric) The position of the added change output, or -1\n" + "}\n" + "\nExamples:\n" + "\nCreate a transaction with no inputs\n" + + HelpExampleCli("createrawtransaction", "\"[]\" \"{\\\"myaddress\\\":0.01}\"") + + "\nAdd sufficient unsigned inputs to meet the output value\n" + + HelpExampleCli("fundrawtransaction", "\"rawtransactionhex\"") + + "\nSign the transaction\n" + + HelpExampleCli("signrawtransaction", "\"fundedtransactionhex\"") + + "\nSend the transaction\n" + + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"") + ); + + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR)); + + CTxDestination changeAddress = CNoDestination(); + int changePosition = -1; + bool includeWatching = false; + bool lockUnspents = false; + bool reserveChangeKey = true; + CFeeRate feeRate = CFeeRate(0); + bool overrideEstimatedFeerate = false; + UniValue subtractFeeFromOutputs; + set setSubtractFeeFromOutputs; + + if (request.params.size() > 1) { + if (request.params[1].type() == UniValue::VBOOL) { + // backward compatibility bool only fallback + includeWatching = request.params[1].get_bool(); + } + else { + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR)(UniValue::VOBJ)); + + UniValue options = request.params[1]; + + RPCTypeCheckObj(options, + { + {"changeAddress", UniValueType(UniValue::VSTR)}, + {"changePosition", UniValueType(UniValue::VNUM)}, + {"includeWatching", UniValueType(UniValue::VBOOL)}, + {"lockUnspents", UniValueType(UniValue::VBOOL)}, + {"reserveChangeKey", UniValueType(UniValue::VBOOL)}, + {"feeRate", UniValueType()}, // will be checked below + {"subtractFeeFromOutputs", UniValueType(UniValue::VARR)}, + }, + true, true); + + if (options.exists("changeAddress")) { + CBitcoinAddress address(options["changeAddress"].get_str()); + + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_PARAMETER, "changeAddress must be a valid ipchain address"); + + changeAddress = address.Get(); + } + + if (options.exists("changePosition")) + changePosition = options["changePosition"].get_int(); + + if (options.exists("includeWatching")) + includeWatching = options["includeWatching"].get_bool(); + + if (options.exists("lockUnspents")) + lockUnspents = options["lockUnspents"].get_bool(); + + if (options.exists("reserveChangeKey")) + reserveChangeKey = options["reserveChangeKey"].get_bool(); + + if (options.exists("feeRate")) + { + feeRate = CFeeRate(AmountFromValue(options["feeRate"])); + overrideEstimatedFeerate = true; + } + + if (options.exists("subtractFeeFromOutputs")) + subtractFeeFromOutputs = options["subtractFeeFromOutputs"].get_array(); + } + } + + // parse hex string from parameter + CMutableTransaction tx; + if (!DecodeHexTx(tx, request.params[0].get_str(), true)) + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); + + if (tx.vout.size() == 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "TX must have at least one output"); + + if (changePosition != -1 && (changePosition < 0 || (unsigned int)changePosition > tx.vout.size())) + throw JSONRPCError(RPC_INVALID_PARAMETER, "changePosition out of bounds"); + + for (unsigned int idx = 0; idx < subtractFeeFromOutputs.size(); idx++) { + int pos = subtractFeeFromOutputs[idx].get_int(); + if (setSubtractFeeFromOutputs.count(pos)) + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, duplicated position: %d", pos)); + if (pos < 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, negative position: %d", pos)); + if (pos >= int(tx.vout.size())) + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, position too large: %d", pos)); + setSubtractFeeFromOutputs.insert(pos); + } + + CAmount nFeeOut; + string strFailReason; + + if(!pwalletMain->FundTransaction(tx, nFeeOut, overrideEstimatedFeerate, feeRate, changePosition, strFailReason, includeWatching, lockUnspents, setSubtractFeeFromOutputs, reserveChangeKey, changeAddress)) + throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason); + + UniValue result(UniValue::VOBJ); + result.push_back(Pair("hex", EncodeHexTx(tx))); + result.push_back(Pair("changepos", changePosition)); + result.push_back(Pair("fee", ValueFromAmount(nFeeOut))); + + return result; +} + +// Calculate the size of the transaction assuming all signatures are max size +// Use DummySignatureCreator, which inserts 72 byte signatures everywhere. +// TODO: re-use this in CWallet::CreateTransaction (right now +// CreateTransaction uses the constructed dummy-signed tx to do a priority +// calculation, but we should be able to refactor after priority is removed). +// NOTE: this requires that all inputs must be in mapWallet (eg the tx should +// be IsAllFromMe). +int64_t CalculateMaximumSignedTxSize(const CTransaction &tx) +{ + CMutableTransaction txNew(tx); + std::vector> vCoins; + // Look up the inputs. We should have already checked that this transaction + // IsAllFromMe(ISMINE_SPENDABLE), so every input should already be in our + // wallet, with a valid index into the vout array. + for (auto& input : tx.vin) { + const auto mi = pwalletMain->mapWallet.find(input.prevout.hash); + assert(mi != pwalletMain->mapWallet.end() && input.prevout.n < mi->second.tx->vout.size()); + vCoins.emplace_back(make_pair(&(mi->second), input.prevout.n)); + } + if (!pwalletMain->DummySignTx(txNew, vCoins)) { + // This should never happen, because IsAllFromMe(ISMINE_SPENDABLE) + // implies that we can sign for every input. + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction contains inputs that cannot be signed"); + } + return GetVirtualTransactionSize(txNew); +} + +UniValue bumpfee(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) { + return NullUniValue; + } + + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { + throw runtime_error( + "bumpfee \"txid\" ( options ) \n" + "\nBumps the fee of an opt-in-RBF transaction T, replacing it with a new transaction B.\n" + "An opt-in RBF transaction with the given txid must be in the wallet.\n" + "The command will pay the additional fee by decreasing (or perhaps removing) its change output.\n" + "If the change output is not big enough to cover the increased fee, the command will currently fail\n" + "instead of adding new inputs to compensate. (A future implementation could improve this.)\n" + "The command will fail if the wallet or mempool contains a transaction that spends one of T's outputs.\n" + "By default, the new fee will be calculated automatically using estimatefee.\n" + "The user can specify a confirmation target for estimatefee.\n" + "Alternatively, the user can specify totalFee, or use RPC setpaytxfee to set a higher fee rate.\n" + "At a minimum, the new fee rate must be high enough to pay an additional new relay fee (incrementalfee\n" + "returned by getnetworkinfo) to enter the node's mempool.\n" + "\nArguments:\n" + "1. txid (string, required) The txid to be bumped\n" + "2. options (object, optional)\n" + " {\n" + " \"confTarget\" (numeric, optional) Confirmation target (in blocks)\n" + " \"totalFee\" (numeric, optional) Total fee (NOT feerate) to pay, in satoshis.\n" + " In rare cases, the actual fee paid might be slightly higher than the specified\n" + " totalFee if the tx change output has to be removed because it is too close to\n" + " the dust threshold.\n" + " \"replaceable\" (boolean, optional, default true) Whether the new transaction should still be\n" + " marked bip-125 replaceable. If true, the sequence numbers in the transaction will\n" + " be left unchanged from the original. If false, any input sequence numbers in the\n" + " original transaction that were less than 0xfffffffe will be increased to 0xfffffffe\n" + " so the new transaction will not be explicitly bip-125 replaceable (though it may\n" + " still be replacable in practice, for example if it has unconfirmed ancestors which\n" + " are replaceable).\n" + " }\n" + "\nResult:\n" + "{\n" + " \"txid\": \"value\", (string) The id of the new transaction\n" + " \"origfee\": n, (numeric) Fee of the replaced transaction\n" + " \"fee\": n, (numeric) Fee of the new transaction\n" + " \"errors\": [ str... ] (json array of strings) Errors encountered during processing (may be empty)\n" + "}\n" + "\nExamples:\n" + "\nBump the fee, get the new transaction\'s txid\n" + + HelpExampleCli("bumpfee", "")); + } + + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR)(UniValue::VOBJ)); + uint256 hash; + hash.SetHex(request.params[0].get_str()); + + // retrieve the original tx from the wallet + LOCK2(cs_main, pwalletMain->cs_wallet); + EnsureWalletIsUnlocked(); + if (!pwalletMain->mapWallet.count(hash)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); + } + CWalletTx& wtx = pwalletMain->mapWallet[hash]; + + if (pwalletMain->HasWalletSpend(hash)) { + throw JSONRPCError(RPC_MISC_ERROR, "Transaction has descendants in the wallet"); + } + + { + LOCK(mempool.cs); + auto it = mempool.mapTx.find(hash); + if (it != mempool.mapTx.end() && it->GetCountWithDescendants() > 1) { + throw JSONRPCError(RPC_MISC_ERROR, "Transaction has descendants in the mempool"); + } + } + + if (wtx.GetDepthInMainChain() != 0) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction has been mined, or is conflicted with a mined transaction"); + } + + if (!SignalsOptInRBF(wtx)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction is not BIP 125 replaceable"); + } + + if (wtx.mapValue.count("replaced_by_txid")) { + throw JSONRPCError(RPC_INVALID_REQUEST, strprintf("Cannot bump transaction %s which was already bumped by transaction %s", hash.ToString(), wtx.mapValue.at("replaced_by_txid"))); + } + + // check that original tx consists entirely of our inputs + // if not, we can't bump the fee, because the wallet has no way of knowing the value of the other inputs (thus the fee) + if (!pwalletMain->IsAllFromMe(wtx, ISMINE_SPENDABLE)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction contains inputs that don't belong to this wallet"); + } + + // figure out which output was change + // if there was no change output or multiple change outputs, fail + int nOutput = -1; + for (size_t i = 0; i < wtx.tx->vout.size(); ++i) { + if (pwalletMain->IsChange(wtx.tx->vout[i]) || i == wtx.tx->vout.size()-1) { + if (nOutput != -1) { + throw JSONRPCError(RPC_MISC_ERROR, "Transaction has multiple change outputs"); + } + nOutput = i; + } + } + if (nOutput == -1) { + throw JSONRPCError(RPC_MISC_ERROR, "Transaction does not have a change output"); + } + + // Calculate the expected size of the new transaction. + int64_t txSize = GetVirtualTransactionSize(*(wtx.tx)); + const int64_t maxNewTxSize = CalculateMaximumSignedTxSize(*wtx.tx); + + // optional parameters + bool specifiedConfirmTarget = false; + int newConfirmTarget = nTxConfirmTarget; + CAmount totalFee = 0; + bool replaceable = true; + if (request.params.size() > 1) { + UniValue options = request.params[1]; + RPCTypeCheckObj(options, + { + {"confTarget", UniValueType(UniValue::VNUM)}, + {"totalFee", UniValueType(UniValue::VNUM)}, + {"replaceable", UniValueType(UniValue::VBOOL)}, + }, + true, true); + + if (options.exists("confTarget") && options.exists("totalFee")) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "confTarget and totalFee options should not both be set. Please provide either a confirmation target for fee estimation or an explicit total fee for the transaction."); + } else if (options.exists("confTarget")) { + specifiedConfirmTarget = true; + newConfirmTarget = options["confTarget"].get_int(); + if (newConfirmTarget <= 0) { // upper-bound will be checked by estimatefee/smartfee + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid confTarget (cannot be <= 0)"); + } + } else if (options.exists("totalFee")) { + totalFee = options["totalFee"].get_int64(); + CAmount requiredFee = CWallet::GetRequiredFee(maxNewTxSize); + if (totalFee < requiredFee ) { + throw JSONRPCError(RPC_INVALID_PARAMETER, + strprintf("Insufficient totalFee (cannot be less than required fee %s)", + FormatMoney(requiredFee))); + } + } + + if (options.exists("replaceable")) { + replaceable = options["replaceable"].get_bool(); + } + } + + // calculate the old fee and fee-rate + CAmount nOldFee = wtx.GetDebit(ISMINE_SPENDABLE) - wtx.tx->GetValueOut(); + CFeeRate nOldFeeRate(nOldFee, txSize); + CAmount nNewFee; + CFeeRate nNewFeeRate; + // The wallet uses a conservative WALLET_INCREMENTAL_RELAY_FEE value to + // future proof against changes to network wide policy for incremental relay + // fee that our node may not be aware of. + CFeeRate walletIncrementalRelayFee = CFeeRate(WALLET_INCREMENTAL_RELAY_FEE); + if (::incrementalRelayFee > walletIncrementalRelayFee) { + walletIncrementalRelayFee = ::incrementalRelayFee; + } + + if (totalFee > 0) { + CAmount minTotalFee = nOldFeeRate.GetFee(maxNewTxSize) + ::incrementalRelayFee.GetFee(maxNewTxSize); + if (totalFee < minTotalFee) { + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Insufficient totalFee, must be at least %s (oldFee %s + incrementalFee %s)", + FormatMoney(minTotalFee), FormatMoney(nOldFeeRate.GetFee(maxNewTxSize)), FormatMoney(::incrementalRelayFee.GetFee(maxNewTxSize)))); + } + nNewFee = totalFee; + nNewFeeRate = CFeeRate(totalFee, maxNewTxSize); + } else { + // if user specified a confirm target then don't consider any global payTxFee + if (specifiedConfirmTarget) { + nNewFee = CWallet::GetMinimumFee(maxNewTxSize, newConfirmTarget, mempool, CAmount(0)); + } + // otherwise use the regular wallet logic to select payTxFee or default confirm target + else { + nNewFee = CWallet::GetMinimumFee(maxNewTxSize, newConfirmTarget, mempool); + } + + nNewFeeRate = CFeeRate(nNewFee, maxNewTxSize); + + // New fee rate must be at least old rate + minimum incremental relay rate + // walletIncrementalRelayFee.GetFeePerK() should be exact, because it's initialized + // in that unit (fee per kb). + // However, nOldFeeRate is a calculated value from the tx fee/size, so + // add 1 satoshi to the result, because it may have been rounded down. + if (nNewFeeRate.GetFeePerK() < nOldFeeRate.GetFeePerK() + 1 + walletIncrementalRelayFee.GetFeePerK()) { + nNewFeeRate = CFeeRate(nOldFeeRate.GetFeePerK() + 1 + walletIncrementalRelayFee.GetFeePerK()); + nNewFee = nNewFeeRate.GetFee(maxNewTxSize); + } + } + + // Check that in all cases the new fee doesn't violate maxTxFee + if (nNewFee > maxTxFee) { + throw JSONRPCError(RPC_MISC_ERROR, + strprintf("Specified or calculated fee %s is too high (cannot be higher than maxTxFee %s)", + FormatMoney(nNewFee), FormatMoney(maxTxFee))); + } + + // check that fee rate is higher than mempool's minimum fee + // (no point in bumping fee if we know that the new tx won't be accepted to the mempool) + // This may occur if the user set TotalFee or paytxfee too low, if fallbackfee is too low, or, perhaps, + // in a rare situation where the mempool minimum fee increased significantly since the fee estimation just a + // moment earlier. In this case, we report an error to the user, who may use totalFee to make an adjustment. + CFeeRate minMempoolFeeRate = mempool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000); + if (nNewFeeRate.GetFeePerK() < minMempoolFeeRate.GetFeePerK()) { + throw JSONRPCError(RPC_MISC_ERROR, strprintf("New fee rate (%s) is less than the minimum fee rate (%s) to get into the mempool. totalFee value should to be at least %s or settxfee value should be at least %s to add transaction.", FormatMoney(nNewFeeRate.GetFeePerK()), FormatMoney(minMempoolFeeRate.GetFeePerK()), FormatMoney(minMempoolFeeRate.GetFee(maxNewTxSize)), FormatMoney(minMempoolFeeRate.GetFeePerK()))); + } + + // Now modify the output to increase the fee. + // If the output is not large enough to pay the fee, fail. + CAmount nDelta = nNewFee - nOldFee; + assert(nDelta > 0); + CMutableTransaction tx(*(wtx.tx)); + CTxOut* poutput = &(tx.vout[nOutput]); + if (poutput->nValue < nDelta) { + throw JSONRPCError(RPC_MISC_ERROR, "Change output is too small to bump the fee"); + } + + // If the output would become dust, discard it (converting the dust to fee) + poutput->nValue -= nDelta; + if (poutput->nValue <= poutput->GetDustThreshold(::dustRelayFee)) { + LogPrint("rpc", "Bumping fee and discarding dust output\n"); + nNewFee += poutput->nValue; + tx.vout.erase(tx.vout.begin() + nOutput); + } + + // Mark new tx not replaceable, if requested. + if (!replaceable) { + for (auto& input : tx.vin) { + if (input.nSequence < 0xfffffffe) input.nSequence = 0xfffffffe; + } + } + + // sign the new tx + CTransaction txNewConst(tx); + int nIn = 0; + for (auto& input : tx.vin) { + std::map::const_iterator mi = pwalletMain->mapWallet.find(input.prevout.hash); + assert(mi != pwalletMain->mapWallet.end() && input.prevout.n < mi->second.tx->vout.size()); + const CScript& scriptPubKey = mi->second.tx->vout[input.prevout.n].scriptPubKey; + const CAmount& amount = mi->second.tx->vout[input.prevout.n].nValue; + SignatureData sigdata; + if (!ProduceSignature(TransactionSignatureCreator(pwalletMain, &txNewConst, nIn, amount, SIGHASH_ALL), scriptPubKey, sigdata)) { + throw JSONRPCError(RPC_WALLET_ERROR, "Can't sign transaction."); + } + UpdateTransaction(tx, nIn, sigdata); + nIn++; + } + + // commit/broadcast the tx + CReserveKey reservekey(pwalletMain); + CWalletTx wtxBumped(pwalletMain, MakeTransactionRef(std::move(tx))); + wtxBumped.mapValue = wtx.mapValue; + wtxBumped.mapValue["replaces_txid"] = hash.ToString(); + wtxBumped.vOrderForm = wtx.vOrderForm; + wtxBumped.strFromAccount = wtx.strFromAccount; + wtxBumped.fTimeReceivedIsTxTime = true; + wtxBumped.fFromMe = true; + CValidationState state; + if (!pwalletMain->CommitTransaction(wtxBumped, reservekey, g_connman.get(), state)) { + // NOTE: CommitTransaction never returns false, so this should never happen. + throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason())); + } + + UniValue vErrors(UniValue::VARR); + if (state.IsInvalid()) { + // This can happen if the mempool rejected the transaction. Report + // what happened in the "errors" response. + vErrors.push_back(strprintf("Error: The transaction was rejected: %s", FormatStateMessage(state))); + } + + // mark the original tx as bumped + if (!pwalletMain->MarkReplaced(wtx.GetHash(), wtxBumped.GetHash())) { + // TODO: see if JSON-RPC has a standard way of returning a response + // along with an exception. It would be good to return information about + // wtxBumped to the caller even if marking the original transaction + // replaced does not succeed for some reason. + vErrors.push_back("Error: Created new bumpfee transaction but could not mark the original transaction as replaced."); + } + + UniValue result(UniValue::VOBJ); + result.push_back(Pair("txid", wtxBumped.GetHash().GetHex())); + result.push_back(Pair("origfee", ValueFromAmount(nOldFee))); + result.push_back(Pair("fee", ValueFromAmount(nNewFee))); + result.push_back(Pair("errors", vErrors)); + + return result; +} + +UniValue loadwallet(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "loadwallet \"filename\"\n" + "\nload a wallet from the wallet file .\n" + "\nArguments:\n" + "1. \"filename\" (string, required) The wallet file\n" + "\nExamples:\n" + "\nload the wallet\n" + + HelpExampleCli("loadwallet", "\"test\"") + + "\nloadwallet the wallet\n" + + HelpExampleCli("loadwallet", "\"test\"") + + "\nloadwallet using the json rpc call\n" + + HelpExampleRpc("loadwallet", "\"test\"") + ); + + if (fPruneMode) + throw JSONRPCError(RPC_WALLET_ERROR, "Importing wallets is disabled in pruned mode"); + + CWallet::LoadWalletFromFile(request.params[0].get_str()); + return NullUniValue; +} + +UniValue exportwallet(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "exportwallet \"filename\"\n" + "\nexport a wallet to the file .\n" + "\nArguments:\n" + "1. \"filename\" (string, required) The wallet file\n" + "\nExamples:\n" + "\export the wallet\n" + + HelpExampleRpc("exportwallet", "\"test\"") + ); + + if (fPruneMode) + throw JSONRPCError(RPC_WALLET_ERROR, "Exporting wallets is disabled in pruned mode"); + + CWallet::ExportWalletToFile(request.params[0].get_str()); + return NullUniValue; +} + UniValue getListTokenBuildByMe(const JSONRPCRequest& request) +{ + + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() >= 1) + throw runtime_error( + "getListTokenBuildByMe \n" + "\nload a wallet from the wallet file .\n" + "\nArguments:\n" + "\nExamples:\n" + "\ngetListTokenBuildByMe\n" + + HelpExampleCli("getListTokenBuildByMe", "") + + "\ngetListTokenBuildByMe using the json rpc call\n" + + HelpExampleRpc("getListTokenBuildByMe", "") + ); + tokenInfoMap tokeninfo; + pwalletMain->getListTokenBuildByMe(tokeninfo); + + UniValue resultarr(UniValue::VOBJ); + BOOST_FOREACH(tokenInfoMap::value_type& pinfo,tokeninfo){ + string name = pinfo.first; + TokenByMeInfo& info = pinfo.second; + UniValue infoobj(UniValue::VOBJ); + infoobj.push_back(Pair("accuracy",info.accuracy)); + infoobj.push_back(Pair("confirmation",info.confirmation)); + infoobj.push_back(Pair("txid",info.txid)); + UniValue addresses(UniValue::VARR); + BOOST_FOREACH(auto & address,info.addresses){ + addresses.push_back(address); + } + infoobj.push_back(Pair("addresses",addresses)); + resultarr.push_back(Pair(name,infoobj)); + } + return resultarr; +} + +extern UniValue dumpprivkey(const JSONRPCRequest& request); // in rpcdump.cpp +extern UniValue importprivkey(const JSONRPCRequest& request); +extern UniValue importaddress(const JSONRPCRequest& request); +extern UniValue importpubkey(const JSONRPCRequest& request); +extern UniValue dumpwallet(const JSONRPCRequest& request); +extern UniValue importwallet(const JSONRPCRequest& request); +extern UniValue importprunedfunds(const JSONRPCRequest& request); +extern UniValue removeprunedfunds(const JSONRPCRequest& request); +extern UniValue importmulti(const JSONRPCRequest& request); + +static const CRPCCommand commands[] = +{ // category name actor (function) okSafeMode + // --------------------- ------------------------ ----------------------- ---------- +// { "rawtransactions", "fundrawtransaction", &fundrawtransaction, false, {"hexstring","options"} }, + { "hidden", "resendwallettransactions", &resendwallettransactions, true, {} }, + { "wallet", "abandontransaction", &abandontransaction, false, {"txid"} }, +//{ "wallet", "addmultisigaddress", &addmultisigaddress, true, {"nrequired","keys","account"} }, + { "hidden", "addwitnessaddress", &addwitnessaddress, true, {"address"} }, + { "wallet", "backupwallet", &backupwallet, true, {"destination"} }, +// { "wallet", "bumpfee", &bumpfee, true, {"txid", "options"} }, + { "wallet", "dumpprivkey", &dumpprivkey, true, {"address"} }, + { "wallet", "dumpwallet", &dumpwallet, true, {"filename"} }, + { "wallet", "encryptwallet", &encryptwallet, true, {"passphrase"} }, +// { "wallet", "getaccountaddress", &getaccountaddress, true, {"account"} }, + { "wallet", "getaccount", &getaccount, true, {"address"} }, + { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true, {"account"} }, + { "wallet", "getbalance", &getbalance, false, {/*"account","minconf","include_watchonly"*/} }, + { "wallet", "getnewaddress", &getnewaddress, true, {"account"} }, +// { "wallet", "getrawchangeaddress", &getrawchangeaddress, true, {} }, + { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false, {"account","minconf"} }, + { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false, {"address","minconf"} }, + { "wallet", "gettransaction", &gettransaction, false, {"txid","include_watchonly"} }, + { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false, {} }, + { "wallet", "getwalletinfo", &getwalletinfo, false, {} }, +// { "wallet", "importmulti", &importmulti, true, {"requests","options"} }, + { "wallet", "importprivkey", &importprivkey, true, {"privkey","label","rescan"} }, + { "wallet", "importwallet", &importwallet, true, {"filename"} }, + { "wallet", "importaddress", &importaddress, true, {"address","label","rescan","p2sh"} }, +// { "wallet", "importprunedfunds", &importprunedfunds, true, {"rawtransaction","txoutproof"} }, + { "wallet", "importpubkey", &importpubkey, true, {"pubkey","label","rescan"} }, + { "wallet", "keypoolrefill", &keypoolrefill, true, {"newsize"} }, +// { "wallet", "listaccounts", &listaccounts, false, {"minconf","include_watchonly"} }, +// { "wallet", "listaddressgroupings", &listaddressgroupings, false, {} }, +// { "wallet", "listlockunspent", &listlockunspent, false, {} }, + { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false, {"minconf","include_empty","include_watchonly"} }, + { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false, {"minconf","include_empty","include_watchonly"} }, +// { "wallet", "listsinceblock", &listsinceblock, false, {"blockhash","target_confirmations","include_watchonly"} }, + { "wallet", "listtransactions", &listtransactions, false, {"account","count","skip","include_watchonly"} }, + { "wallet", "listunspent", &listunspent, false, {"minconf","maxconf","addresses","include_unsafe"} }, +// { "wallet", "lockunspent", &lockunspent, true, {"unlock","transactions"} }, + + { "wallet", "NormalSendToAddress", &NormalSendToAddress, true, { "address", "amount", "comment", "comment_to", "subtractfeefromamount" } }, + { "wallet", "IPCRegisterToAddress", &IPCRegisterToAddress, false, { "address", "ipclabel" } }, + { "wallet", "IPCSendToAddress", &IPCSendToAddress, false, { "txid", "index", "address" } }, + { "wallet", "IPCAuthorToAddress", &IPCAuthorToAddress, false, { "txid", "index", "address", "ipclabel" } }, + { "wallet", "IPCTokenRegToAddress", &IPCTokenRegToAddress, false, { "address", "tokenlabel" } }, + { "wallet", "IPCTokenSendToAddress", &IPCTokenSendToAddress, false, { "tokensymbol", "address", "value" } }, + //{ "wallet", "IPCTokenSendToAddressForCross", &IPCTokenSendToAddressForCross, false, { "tokensymbol", "address", "value", "txLabel" } }, + { "wallet", "listunspentNormal", &listunspentNormal, false, { "minconf", "maxconf", "addresses", "include_unsafe" } }, + { "wallet", "listunspentIPC", &listunspentIPC, false, { "minconf", "maxconf", "addresses", "include_unsafe" } }, + { "wallet", "listunspentToken", &listunspentToken, false, { "minconf", "maxconf", "addresses", "include_unsafe" } }, + { "wallet", "listtokencoins", &listtokencoins, false, { "tokensymbol"} }, + { "wallet", "gettokenbalance", &gettokenbalance, false, { "tokensymbol" } }, + { "wallet", "listtokentransactions", &listtokentransactions, false, { "tokensymbol", "count", "skip" } }, + { "wallet", "gettokentransaction", &gettokentransaction, false, { "txid", "include_watchonly" } }, + +// { "wallet", "move", &movecmd, false, {"fromaccount","toaccount","amount","minconf","comment"} }, +// { "wallet", "sendfrom", &sendfrom, false, {"fromaccount","toaddress","amount","minconf","comment","comment_to"} }, + { "wallet", "sendmany", &sendmany, false, {"fromaccount","amounts"/*,"minconf","comment","subtractfeefrom"*/} }, + { "wallet", "sendtokenmany", &sendtokenmany, true, { "fromaccount", "tokensymbol", "amounts" } }, + { "wallet", "sendtoaddress", &sendtoaddress, true, { "address", "amount", "comment", "comment_to", "subtractfeefromamount" } }, +// { "wallet", "setaccount", &setaccount, true, {"address","account"} }, +// { "wallet", "settxfee", &settxfee, true, {"amount"} }, + { "wallet", "signmessage", &signmessage, true, {"address","message"} }, + { "wallet", "walletlock", &walletlock, true, {} }, + { "wallet", "walletpassphrasechange", &walletpassphrasechange, true, {"oldpassphrase","newpassphrase"} }, + { "wallet", "walletpassphrase", &walletpassphrase, true, {"passphrase","timeout"} }, +// { "wallet", "removeprunedfunds", &removeprunedfunds, true, {"txid"} }, +// { "wallet", "loadwallet", &loadwallet, true, {"filename"} }, +// { "wallet", "exportwallet", &exportwallet, true, {"filename"} }, + { "wallet", "decodeinfobyaddress", &decodeinfobyaddress, true, { "address" } }, + + //Add command line operations that exit consensus + { "wallet", "getcurdeposit", &getcurdeposit, true, {} }, + { "wallet", "joincampaign", &joincampaign, true, {"address","deposi"} }, + { "wallet", "exitcampaign", &exitcampaign, true, {} }, + { "wallet", "isdepositabled", &isdepositabled, true, { "txid", "index" } }, +// { "wallet", "punishrequest", &punishrequest, true, { "address" } }, + { "wallet", "listreward", &listreward, true, {} }, + // { "wallet", "getListTokenBuildByMe", &getListTokenBuildByMe, true, {} }, +// { "wallet", "dpocsign", &dpocsign, true,{ "hexdata" } }, + + { "wallet", "addmultiadd", &addmultiadd, true, {"strhex","account"} }, + { "wallet", "createmultiaddress", &createmultiaddress, true, {"nrequired","keys","account"} }, + { "wallet", "decodeInvCode", &decodeInvCode, true, { "strInvCode" } }, + { "wallet", "getunionaddresses", &getunionaddresses, true, {} }, + { "wallet", "getunioncoins", &getunioncoins, true, {"addresses"} }, + { "wallet", "sendtomultiaddress", &sendtomultiaddress, true, {"toaddress", "fromaddress", "amount", "comment", "comment_to", "subtractfeefromamount" } }, + { "wallet", "signmultitx", &signmultitx, true, { "strtx"} }, + +}; + +void RegisterWalletRPCCommands(CRPCTable &t) +{ + if (GetBoolArg("-disablewallet", false)) + return; + + for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) + t.appendCommand(commands[vcidx].name, &commands[vcidx]); +} diff --git a/.svn/pristine/43/43f5cd971eebf90fda76f1f57b28efc2e92b0607.svn-base b/.svn/pristine/43/43f5cd971eebf90fda76f1f57b28efc2e92b0607.svn-base new file mode 100644 index 0000000..812f3ae --- /dev/null +++ b/.svn/pristine/43/43f5cd971eebf90fda76f1f57b28efc2e92b0607.svn-base @@ -0,0 +1,30 @@ +#ifndef SENDHISTORY_H +#define SENDHISTORY_H + +#include +#include +#include +QT_BEGIN_NAMESPACE +class QModelIndex; +QT_END_NAMESPACE +namespace Ui { +class sendhistory; +} + +class sendhistory : public QDialog +{ + Q_OBJECT + +public: + explicit sendhistory( QWidget *parent = 0); + ~sendhistory(); + + void showVisual(bool visual); + void updateInfo(QString status); + void setinfo(const QModelIndex &idx); + +private: + Ui::sendhistory *ui; +}; + +#endif // SENDHISTORY_H diff --git a/.svn/pristine/49/4967164d7bf4014fe5f2ef5f4a6e43d324af4f35.svn-base b/.svn/pristine/49/4967164d7bf4014fe5f2ef5f4a6e43d324af4f35.svn-base new file mode 100644 index 0000000..9c89fed --- /dev/null +++ b/.svn/pristine/49/4967164d7bf4014fe5f2ef5f4a6e43d324af4f35.svn-base @@ -0,0 +1,439 @@ + + + walletpagebuttons + + + + 0 + 0 + 1016 + 90 + + + + + 0 + 90 + + + + + 800000 + 90 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 90 + + + + + 16777215 + 90 + + + + background-image: url(:/res/png/btnsbackpage.png); + + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 15 + 20 + + + + + + + + + 0 + 0 + + + + + 10000 + 5400 + + + + + + + + + + + + + + 8 + + + 20 + + + 25 + + + + + + + + 16 + 15 + + + + + 16 + 15 + + + + background-image: url(:/res/png/hight.png); + + + + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + + color: white;font-size:16px + + + TextLabel + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + + + + + + + 19 + 14 + + + + + 19 + 14 + + + + background-image: url(:/res/png/node.png); + + + + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + + color: white;font-size:16px + + + TextLabel + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + + + + + + Qt::Horizontal + + + + 246 + 20 + + + + + + + + 0 + + + + + + 72 + 90 + + + + + 72 + 90 + + + + true + + + Qt::NoFocus + + + Qt::NoContextMenu + + + + + + + + + + + + + + 72 + 90 + + + + + 72 + 90 + + + + Qt::NoFocus + + + + + + + + + + + + + + 72 + 90 + + + + + 72 + 90 + + + + Qt::NoFocus + + + + + + + + + + + + + + 72 + 90 + + + + + 72 + 90 + + + + Qt::NoFocus + + + + + + + + + + + + + + 72 + 90 + + + + + 72 + 90 + + + + Qt::NoFocus + + + + + + + + + + + + + + 72 + 90 + + + + + 72 + 90 + + + + Qt::NoFocus + + + + + + + + + + + + + + 72 + 90 + + + + + 72 + 90 + + + + Qt::NoFocus + + + + + + + + + + + + + + 72 + 90 + + + + + 72 + 90 + + + + Qt::NoFocus + + + + + + + + + + + + + + + + + + + diff --git a/.svn/pristine/49/49f5e904fe8019dfb943727fe7fc5d213fedf906.svn-base b/.svn/pristine/49/49f5e904fe8019dfb943727fe7fc5d213fedf906.svn-base new file mode 100644 index 0000000..006dc08 --- /dev/null +++ b/.svn/pristine/49/49f5e904fe8019dfb943727fe7fc5d213fedf906.svn-base @@ -0,0 +1,90 @@ +#include "unionaccountgenkey.h" +#include "ui_unionaccountgenkey.h" +#include "log/log.h" +#ifdef ENABLE_WALLET +#include "walletmodel.h" +#endif +unionaccountgenkey::unionaccountgenkey(QWidget *parent) : + QWidget(parent),model(NULL), + ui(new Ui::unionaccountgenkey) +{ + ui->setupUi(this); + ui->genkey->setVisible(false); + ui->key_label->setText(""); +} + +unionaccountgenkey::~unionaccountgenkey() +{ + delete ui; +} +void unionaccountgenkey::setModel(WalletModel *_model) +{ + this->model = _model; +} +void unionaccountgenkey::on_genkey_pressed() +{ + +} + +void unionaccountgenkey::on_selectadd_btn_pressed() +{ + Q_EMIT selectaddress(); +} +void unionaccountgenkey::setaddress(QString address) +{ + m_address = address; + ui->selectadd_btn->setText(address); + ui->key_label->setText(""); + + + std::string m_key; + std::string m_failreason; + std::string add = m_address.toStdString(); + if("" == add) + { + ui->label_err->setText("input add"); + return; + } + if(this->model->addtopubkey(add,m_key,m_failreason)) + { + LOG_WRITE(LOG_INFO,"GENKEY",m_key.c_str()); + ui->key_label->setText(QString::fromStdString(m_key)); + } + else + { + + if("address is valid!" ==m_failreason ) + { + ui->label_err->setText(tr("address is valid!")); + } + else if("address can't be Script!" ==m_failreason) + { + ui->label_err->setText(tr("address can't be Script!")); + } + else if("GetPubKey faild!" ==m_failreason) + { + ui->label_err->setText(tr("GetPubKey faild!")); + } + else + { + ui->label_err->setText(tr("GenKey faild!")); + } + } + +} + +void unionaccountgenkey::clearData() +{ + m_address = ""; +} + +void unionaccountgenkey::showEvent(QShowEvent *event) +{ + ui->label_err->setText(""); + +} +void unionaccountgenkey::clearinfo(){ + ui->label_err->setText(""); + ui->key_label->setText(""); + ui->selectadd_btn->setText(tr("select address")); +} diff --git a/.svn/pristine/4f/4f9e4ffcad5b5e4cc53a37e9f5ef041fcca45214.svn-base b/.svn/pristine/4f/4f9e4ffcad5b5e4cc53a37e9f5ef041fcca45214.svn-base new file mode 100644 index 0000000..62d40be --- /dev/null +++ b/.svn/pristine/4f/4f9e4ffcad5b5e4cc53a37e9f5ef041fcca45214.svn-base @@ -0,0 +1,481 @@ +#include "unionaccountcreate.h" +#include "ui_unionaccountcreate.h" +#include "log/log.h" +#include "recentrequeststablemodel.h" +#include +#include "addresstablemodel.h" +#ifdef ENABLE_WALLET +#include "walletmodel.h" +#endif +unionaccountcreate::unionaccountcreate(QWidget *parent) : + QWidget(parent), + ui(new Ui::unionaccountcreate) +{ + ui->setupUi(this); + ui->scrollArea->setFrameShape(QFrame::NoFrame); + ui->comboBox->addItems(QStringList()<<"2"<<"3"<<"4"<<"5"); + ui->comboBox_2->addItems(QStringList()<<"2"<<"3"<<"4"<<"5"); + connect(ui->comboBox, SIGNAL(activated(int)), this, SLOT(coinUpdate(int))); + + // + ui->lineEdit_key1->setVisible(true); + ui->label_u1->setVisible(true); + + ui->lineEdit_key2->setVisible(false); + ui->label_u2->setVisible(false); + + ui->lineEdit_key3->setVisible(false); + ui->label_u3->setVisible(false); + + ui->lineEdit_key4->setVisible(false); + ui->label_u4->setVisible(false); + + + + ui->line_4->setVisible(true); + + ui->lineEdit_key1->setText(""); + ui->lineEdit_key2->setText(""); + ui->lineEdit_key3->setText(""); + ui->lineEdit_key4->setText(""); + + QRegExp regx("^\\S+$"); + QValidator *validator = new QRegExpValidator(regx, ui->lineEdit_name ); + ui->lineEdit_name->setValidator( validator ); + + + + +} + +void unionaccountcreate::coinUpdate(int idx) +{ + switch(ui->comboBox->currentIndex()+1) + { + /* + case 1: + { + ui->lineEdit_key1->setVisible(false); + ui->label_u1->setVisible(false); + + ui->lineEdit_key2->setVisible(false); + ui->label_u2->setVisible(false); + + ui->lineEdit_key3->setVisible(false); + ui->label_u3->setVisible(false); + + ui->lineEdit_key4->setVisible(false); + ui->label_u4->setVisible(false); + + ui->line_4->setVisible(false); + + ui->lineEdit_key1->setText(""); + ui->lineEdit_key2->setText(""); + ui->lineEdit_key3->setText(""); + ui->lineEdit_key4->setText(""); + } + break; + */ + case 1: + { + + + ui->lineEdit_key1->setVisible(true); + ui->label_u1->setVisible(true); + + ui->lineEdit_key2->setVisible(false); + ui->label_u2->setVisible(false); + + ui->lineEdit_key3->setVisible(false); + ui->label_u3->setVisible(false); + + ui->lineEdit_key4->setVisible(false); + ui->label_u4->setVisible(false); + + + + ui->line_4->setVisible(true); + + ui->lineEdit_key1->setText(""); + ui->lineEdit_key2->setText(""); + ui->lineEdit_key3->setText(""); + ui->lineEdit_key4->setText(""); + + + } + break; + case 2: + { + ui->lineEdit_key1->setVisible(true); + ui->label_u1->setVisible(true); + + ui->lineEdit_key2->setVisible(true); + ui->label_u2->setVisible(true); + + ui->lineEdit_key3->setVisible(false); + ui->label_u3->setVisible(false); + + ui->lineEdit_key4->setVisible(false); + ui->label_u4->setVisible(false); + + ui->line_4->setVisible(true); + + ui->lineEdit_key1->setText(""); + ui->lineEdit_key2->setText(""); + ui->lineEdit_key3->setText(""); + ui->lineEdit_key4->setText(""); + + + } + break; + case 3: + { + ui->lineEdit_key1->setVisible(true); + ui->label_u1->setVisible(true); + + ui->lineEdit_key2->setVisible(true); + ui->label_u2->setVisible(true); + + ui->lineEdit_key3->setVisible(true); + ui->label_u3->setVisible(true); + + ui->lineEdit_key4->setVisible(false); + ui->label_u4->setVisible(false); + + ui->line_4->setVisible(true); + + ui->lineEdit_key1->setText(""); + ui->lineEdit_key2->setText(""); + ui->lineEdit_key3->setText(""); + ui->lineEdit_key4->setText(""); + } + break; + case 4: + { + ui->lineEdit_key1->setVisible(true); + ui->label_u1->setVisible(true); + + ui->lineEdit_key2->setVisible(true); + ui->label_u2->setVisible(true); + + ui->lineEdit_key3->setVisible(true); + ui->label_u3->setVisible(true); + + ui->lineEdit_key4->setVisible(true); + ui->label_u4->setVisible(true); + + ui->line_4->setVisible(true); + + ui->lineEdit_key1->setText(""); + ui->lineEdit_key2->setText(""); + ui->lineEdit_key3->setText(""); + ui->lineEdit_key4->setText(""); + } + break; + default: + { + } + } +} + +unionaccountcreate::~unionaccountcreate() +{ + delete ui; +} +void unionaccountcreate::setModel(WalletModel *_model) +{ + this->model = _model; + +} +void unionaccountcreate::setInit() +{ + + ui->comboBox->tr("2"); + ui->comboBox_2->setCurrentIndex(0); + ui->comboBox->setCurrentIndex(0); + ui->label_error->setText(""); + ui->lineEdit_name->setText(""); + ui->lineEdit_key->setText(""); + ui->lineEdit_key1->setText(""); + ui->lineEdit_key2->setText(""); + ui->lineEdit_key3->setText(""); + ui->lineEdit_key4->setText(""); + + // + + ui->lineEdit_key1->setVisible(true); + ui->label_u1->setVisible(true); + + ui->lineEdit_key2->setVisible(false); + ui->label_u2->setVisible(false); + + ui->lineEdit_key3->setVisible(false); + ui->label_u3->setVisible(false); + + ui->lineEdit_key4->setVisible(false); + ui->label_u4->setVisible(false); + + + + ui->line_4->setVisible(true); + + ui->lineEdit_key1->setText(""); + ui->lineEdit_key2->setText(""); + ui->lineEdit_key3->setText(""); + ui->lineEdit_key4->setText(""); + +} +void unionaccountcreate::on_createBtn_pressed() +{ + + ui->label_error->clear(); + ui->label_error->setVisible(false); + ui->label_error->setText(""); + if(ui->lineEdit_name->text() == "" || ui->lineEdit_key->text() == "" ) + { + ui->label_error->setVisible(true); + ui->label_error->setText(tr("input info")); + return; + } + + ui->label_error->setVisible(true); + ui->label_error->setText(""); + std::string add1_ = ui->lineEdit_key->text().toStdString(); + std::string add2_ = ui->lineEdit_key1->text().toStdString(); + std::string add3_ = ui->lineEdit_key2->text().toStdString(); + std::string add4_ = ui->lineEdit_key3->text().toStdString(); + std::string add5_ = ui->lineEdit_key4->text().toStdString(); + std::vector vec_add; + + int num = ui->comboBox->currentIndex()+1; + + + QString my_num = ui->comboBox->currentText(); + + int conf_num = ui->comboBox_2->currentIndex()+2; + + //conf_num =1 ; + + LOG_WRITE(LOG_INFO,"my_num,conf_num",my_num.toStdString().c_str(),QString::number(conf_num).toStdString().c_str()); + if("2" == my_num && ui->lineEdit_key1->text() == "") + { + ui->label_error->setText(tr("input info")); + return; + } + + if("3" == my_num && (ui->lineEdit_key1->text() == "" || ui->lineEdit_key2->text() == "")) + { + ui->label_error->setText(tr("input info")); + return; + } + if("4" == my_num && (ui->lineEdit_key1->text() == "" || ui->lineEdit_key2->text() == "" || ui->lineEdit_key3->text() == "")) + { + ui->label_error->setText(tr("input info")); + return; + } + if("5" == my_num && (ui->lineEdit_key1->text() == "" || ui->lineEdit_key2->text() == "" || ui->lineEdit_key3->text() == "" || ui->lineEdit_key4->text() == "")) + { + ui->label_error->setText(tr("input info")); + return; + } + int mypknum = 0; + if(add1_ !="") + { + LOG_WRITE(LOG_INFO,"num1"); + vec_add.push_back(add1_); + LOG_WRITE(LOG_INFO,"num12"); + if(model->isMyPk(add1_)){ + LOG_WRITE(LOG_INFO,"num13"); + mypknum++; + } + } + if(add2_ !="") { vec_add.push_back(add2_); if(model->isMyPk(add2_)){LOG_WRITE(LOG_INFO,"num2");mypknum++;}} + if(add3_ !="") { vec_add.push_back(add3_); if(model->isMyPk(add3_)){LOG_WRITE(LOG_INFO,"num3");mypknum++;}} + if(add4_ !="") { vec_add.push_back(add4_); if(model->isMyPk(add4_)){LOG_WRITE(LOG_INFO,"num4");mypknum++;}} + if(add5_ !="") { vec_add.push_back(add5_); if(model->isMyPk(add5_)){LOG_WRITE(LOG_INFO,"num5");mypknum++;}} + if(mypknum!=1){ + LOG_WRITE(LOG_INFO,"mypknum ",QString::number(mypknum).toStdString().c_str()); + + ui->label_error->setText(tr("Please make sure that there is only one of your own public key.")); + return; + } + + for(int i = 0; i< vec_add.size(); i++) + { + std::string d1 = vec_add.at(i); + } + int ncount; + for(int i = 0; i< vec_add.size(); i++) + { + ncount = count(vec_add.begin(),vec_add.end(),vec_add.at(i)); + if(ncount>1) + { + ui->label_error->setText(tr("Publickey repetition")); + return; + } + } + std::string union_script,union_add,m_failreason; + if(model->CreateUnionAddress(conf_num,vec_add,union_script,union_add,m_failreason)) + { + + ui->label_error->setText(""); + if(model->joinunionaccount(ui->lineEdit_name->text().toStdString(),m_failreason,union_script)) + { + ui->label_error->setText(""); + LOG_WRITE(LOG_INFO,"joinunionaccount script + add",union_script.c_str(),union_add.c_str()); + Q_EMIT refreshunionaccount(); + Q_EMIT opensuccesscreatePage(QString::fromStdString(union_script),QString::fromStdString(union_add)); + } + else + { + if("script is not p2sh script!" ==m_failreason ) + { + ui->label_error->setText(tr("script is not p2sh script!")); + } + else if("AddMultiAddress failed!" ==m_failreason) + { + ui->label_error->setText(tr("AddMultiAddress failed!")); + } + else if("MultiAdd is not yours" == m_failreason) + { + ui->label_error->setText(tr("MultiAdd is not yours")); + } + else if("Address duplication!"== m_failreason) + { + ui->label_error->setText(tr("Address duplication")); + } + else if("Password error."== m_failreason) + { + ui->label_error->setText(tr("Password error.")); + } + else + { + LOG_WRITE(LOG_INFO,"JOIN FAIL",m_failreason.c_str()); + ui->label_error->setText(tr("join error")); + } + + } + } + else + { + + if("nRequired or strPubkeys size is valid!" ==m_failreason ) + { + ui->label_error->setText(tr("nRequired or strPubkeys size is valid!")); + } + else if("Pubkey is valid!" ==m_failreason) + { + ui->label_error->setText(tr("Pubkey is valid!")); + } + else if("CScript size too large!" ==m_failreason) + { + ui->label_error->setText(tr("CScript size too large!")); + } + else if("script is not p2sh script!" ==m_failreason ) + { + ui->label_error->setText(tr("script is not p2sh script!")); + } + else if("AddMultiAddress failed!" ==m_failreason) + { + ui->label_error->setText(tr("AddMultiAddress failed!")); + } + + else + { + LOG_WRITE(LOG_INFO,"CREATE FAIL"); + ui->label_error->setText(tr("create error")); + } + } +} +void unionaccountcreate::showEvent(QShowEvent *event) +{ + ui->label_error->setText(""); + ui->lineEdit_name->setText(""); + ui->lineEdit_key->setText(""); + ui->lineEdit_key1->setText(""); + ui->lineEdit_key2->setText(""); + ui->lineEdit_key3->setText(""); + ui->lineEdit_key4->setText(""); + + // + + ui->lineEdit_key1->setVisible(true); + ui->label_u1->setVisible(true); + + ui->lineEdit_key2->setVisible(false); + ui->label_u2->setVisible(false); + + ui->lineEdit_key3->setVisible(false); + ui->label_u3->setVisible(false); + + ui->lineEdit_key4->setVisible(false); + ui->label_u4->setVisible(false); + + + + ui->line_4->setVisible(true); + + ui->lineEdit_key1->setText(""); + ui->lineEdit_key2->setText(""); + ui->lineEdit_key3->setText(""); + ui->lineEdit_key4->setText(""); +} + +void unionaccountcreate::on_btn_genkey_pressed() +{ + ui->label_error->setText(""); + if(model && model->getOptionsModel()) + { + model->getRecentRequestsTableModel()->sort(RecentRequestsTableModel::Date, Qt::DescendingOrder); + QSortFilterProxyModel * proxyModel; + proxyModel = new QSortFilterProxyModel(this); + proxyModel->setSourceModel(model->getAddressTableModel()); + proxyModel->setDynamicSortFilter(true); + proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); + proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); + proxyModel->setFilterRole(AddressTableModel::TypeRole); + proxyModel->setFilterFixedString(AddressTableModel::Receive); + + QModelIndex buttomindex= proxyModel->index(0,1, QModelIndex()); + QVariant bumvar= buttomindex.data(); + QString str = bumvar.toString();; + std::string m_key; + std::string m_failreason; + std::string m_str = str.toStdString(); + + + + + + if(model->addtopubkey(m_str,m_key,m_failreason)) + { + LOG_WRITE(LOG_INFO,"GENKEY-CREATE",m_key.c_str()); + ui->lineEdit_key->setText(QString::fromStdString(m_key)); + } + else + { + + if("address is valid!" ==m_failreason ) + { + ui->label_error->setText(tr("address is valid!")); + } + else if("address can't be Script!" ==m_failreason) + { + ui->label_error->setText(tr("address can't be Script!")); + } + else if("GetPubKey faild!" ==m_failreason) + { + ui->label_error->setText(tr("GetPubKey faild!")); + } + else + { + ui->label_error->setText(tr("GenKey faild!")); + } + } + + + + + + } +} diff --git a/.svn/pristine/50/50d063761e95a1c08434c7efc53b8a1fc616f39f.svn-base b/.svn/pristine/50/50d063761e95a1c08434c7efc53b8a1fc616f39f.svn-base new file mode 100644 index 0000000..948ccaf --- /dev/null +++ b/.svn/pristine/50/50d063761e95a1c08434c7efc53b8a1fc616f39f.svn-base @@ -0,0 +1,462 @@ + + + overviewpage + + + + 0 + 0 + 916 + 676 + + + + Form + + + + + + + 7 + + + + + + + + 310 + 177 + + + + + 310 + 177 + + + + + 0 + + + + + + 0 + 0 + + + + + 3100000 + 6666 + + + + border:none + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 248 + 113 + 31 + 31 + + + + + 31 + 31 + + + + + 31 + 31 + + + + background-image: url(:/res/png/dateloading.png);border:none; + + + + + + + + + 0 + 99 + 231 + 71 + + + + + 3 + + + + + + 0 + 19 + + + + + 16777215 + 19 + + + + font-size : 14px; + + + Available: + + + Qt::NoTextInteraction + + + + + + + + 0 + 19 + + + + + 16777215 + 19 + + + + + -1 + + + + ArrowCursor + + + true + + + + + + font-size : 14px; + + + <html><head/><body><p><span style=" color:#000000;">0.000 000 00 BTC</span></p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + Qt::NoTextInteraction + + + + + + + font-size : 14px; + + + Immature: + + + Qt::NoTextInteraction + + + + + + + + -1 + + + + ArrowCursor + + + true + + + + + + font-size : 14px; + + + <html><head/><body><p><span style=" color:#000000;">0.000 000 00 BTC</span></p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + Qt::NoTextInteraction + + + + + + + font-size : 14px; + + + Detained: + + + + + + + font-size : 14px; + + + <html><head/><body><p><span style=" color:#000000;">0.000 000 00 BTC</span></p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + 10 + 10 + 261 + 58 + + + + true + + + true + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 261 + 58 + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 34 + + + + + 16777215 + 34 + + + + + -1 + + + + ArrowCursor + + + + + + font-size : 28px; + + + 0.000 000 00 BTC + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Qt::NoTextInteraction + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + + + + + 310 + 0 + + + + + 310 + 16777215 + + + + + 310 + 0 + + + + + 0 + + + 0 + + + + + QListView { background: transparent; } + + + QFrame::NoFrame + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAlwaysOff + + + QAbstractItemView::NoSelection + + + QAbstractItemView::ScrollPerPixel + + + + + + + + + + + + + MyScrollArea + QScrollArea +
../myscrollarea.h
+ 1 +
+
+ + +
diff --git a/.svn/pristine/55/55d6033fbf57ba81535bc32ebb1a89e5a21e3026.svn-base b/.svn/pristine/55/55d6033fbf57ba81535bc32ebb1a89e5a21e3026.svn-base new file mode 100644 index 0000000..e69c3f3 --- /dev/null +++ b/.svn/pristine/55/55d6033fbf57ba81535bc32ebb1a89e5a21e3026.svn-base @@ -0,0 +1,27 @@ +#ifndef SENDIPCHISTORY_H +#define SENDIPCHISTORY_H + +#include +QT_BEGIN_NAMESPACE +class QModelIndex; +QT_END_NAMESPACE +namespace Ui { +class sendipchistory; +} + +class sendipchistory : public QWidget +{ + Q_OBJECT + +public: + explicit sendipchistory(QWidget *parent = 0); + ~sendipchistory(); + void showVisual(bool visual); + void updateInfo(QString status); + void setinfo(const QModelIndex &idx); + +private: + Ui::sendipchistory *ui; +}; + +#endif // SENDIPCHISTORY_H diff --git a/.svn/pristine/57/57bdc01a6649cdb6b2503adb7fce9ed0b51ae4e8.svn-base b/.svn/pristine/57/57bdc01a6649cdb6b2503adb7fce9ed0b51ae4e8.svn-base new file mode 100644 index 0000000..6888f0c --- /dev/null +++ b/.svn/pristine/57/57bdc01a6649cdb6b2503adb7fce9ed0b51ae4e8.svn-base @@ -0,0 +1,322 @@ +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + +#include "passwordsettingwidget.h" +#include "forms/ui_passwordsettingwidget.h" +#include "guiconstants.h" +#include "walletmodel.h" +#include "support/allocators/secure.h" +#include +#include +#include +#include "cmessagebox.h" +#include "dpoc/TimeService.h" +#include +#include "log/log.h" +PasswordSettingWidget::PasswordSettingWidget(Mode _mode,QWidget *parent) : + QWidget(parent), + ui(new Ui::PasswordSettingWidget) +{ + ui->setupUi(this); + ui->passEdit1->setMinimumSize(ui->passEdit1->sizeHint()); + ui->passEdit2->setMinimumSize(ui->passEdit2->sizeHint()); + ui->passEdit3->setMinimumSize(ui->passEdit3->sizeHint()); + + ui->passEdit1->setMaxLength(MAX_PASSPHRASE_SIZE); + ui->passEdit2->setMaxLength(MAX_PASSPHRASE_SIZE); + ui->passEdit3->setMaxLength(MAX_PASSPHRASE_SIZE); + + // Setup Caps Lock detection. + ui->passEdit1->installEventFilter(this); + ui->passEdit2->installEventFilter(this); + ui->passEdit3->installEventFilter(this); + + LOG_WRITE(LOG_INFO,"passwordsettingwidget::passwordsettingwidget",QString::number(_mode).toStdString().c_str()); + switch(_mode) + { + case Encrypt: // Ask passphrase x2 + ui->passEdit3->hide(); + ui->passEdit3->setVisible(false); + ui->passEdit1->setPlaceholderText(tr("6-20 characters, suggesting English numerals are mixed")); + ui->passEdit2->setPlaceholderText(tr("Confirm password")); + break; + case Unlock: // Ask passphrase + ui->passEdit2->hide(); + ui->passEdit3->hide(); + break; + case Decrypt: // Ask passphrase + ui->passEdit2->hide(); + ui->passEdit3->hide(); + break; + case ChangePass: // Ask old passphrase + new passphrase x2 + ui->passEdit1->setPlaceholderText(tr("old password")); + ui->passEdit2->setPlaceholderText(tr("6-20 characters, suggesting English numerals are mixed")); + ui->passEdit3->setPlaceholderText(tr("Confirm password")); + break; + } + textChanged(); + connect(ui->passEdit1, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); + connect(ui->passEdit2, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); + connect(ui->passEdit3, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); + ui->label_error->setText(""); +} + +PasswordSettingWidget::~PasswordSettingWidget() +{ + delete ui; +} +void PasswordSettingWidget::on_pushButton_2_pressed() +{ + Q_EMIT back(); +} +void PasswordSettingWidget::setMode(Mode _mode) +{ + this->mode = _mode; + ui->passEdit1->setFocus(); + ui->passEdit1->setText(tr("")); + ui->passEdit2->setText(tr("")); + ui->passEdit3->setText(tr("")); + switch(mode) + { + case Encrypt: // Ask passphrase x2 + ui->passEdit3->hide(); + ui->passEdit3->setVisible(false); + ui->passEdit1->setPlaceholderText(tr("6-20 characters, suggesting English numerals are mixed")); + ui->passEdit2->setPlaceholderText(tr("Confirm password")); + break; + case Unlock: // Ask passphrase + ui->passEdit2->hide(); + ui->passEdit3->hide(); + break; + case Decrypt: // Ask passphrase + ui->passEdit2->hide(); + ui->passEdit3->hide(); + break; + case ChangePass: // Ask old passphrase + new passphrase x2 + ui->passEdit1->setPlaceholderText(tr("old password")); + ui->passEdit2->setPlaceholderText(tr("6-20 characters, suggesting English numerals are mixed")); + ui->passEdit3->setPlaceholderText(tr("Confirm password")); + ui->passEdit3->setVisible(true); + break; + } +} +void PasswordSettingWidget::setModel(WalletModel *_model) +{ + this->model = _model; +} +void PasswordSettingWidget::on_pushButton_pressed() +{ + LOG_WRITE(LOG_INFO,"passwordsettingwidget::on_pushBUtton_pressed",QString::number(mode).toStdString().c_str()); + + if(mode == Encrypt){ + if(ui->passEdit1->text().isEmpty()){ + ui->label_error->setText(tr("please set password")); + return; + }else if(ui->passEdit2->text().isEmpty()){ + ui->label_error->setText(tr("please set confirm password")); + return; + } + int size = ui->passEdit1->text().size(); + std::string temp = ui->passEdit1->text().toStdString(); + if(size<6||size>20||temp.length()!=size){ + //ui->label_error->setText(tr("please check password")); + ui->label_error->setText(tr("The input length is between 6-20,please check password")); + return; + } + }else if(mode == ChangePass){ + if(ui->passEdit1->text().isEmpty()){ + ui->label_error->setText(tr("please set old password")); + return; + }else if(ui->passEdit2->text().isEmpty()){ + ui->label_error->setText(tr("please set new password")); + return; + }else if(ui->passEdit3->text().isEmpty()){ + ui->label_error->setText(tr("please set confirm password")); + return; + } + int size = ui->passEdit2->text().size(); + std::string temp = ui->passEdit2->text().toStdString(); + if(size<6||size>20){ + ui->label_error->setText(tr("The input length is between 6-20,please check password")); + return; + } + if(temp.length()!=size){ + ui->label_error->setText(tr("Inconsistency of input passwords,please check password")); + return; + } + } + + ui->label_error->setText(tr("please wait...")); + SecureString oldpass, newpass1, newpass2; + if(!model) + return; + oldpass.reserve(MAX_PASSPHRASE_SIZE); + newpass1.reserve(MAX_PASSPHRASE_SIZE); + newpass2.reserve(MAX_PASSPHRASE_SIZE); + + switch(mode) + { + case Encrypt: { + newpass1.assign(ui->passEdit1->text().toStdString().c_str()); + newpass2.assign(ui->passEdit2->text().toStdString().c_str()); + + if(newpass1.empty() || newpass2.empty()) + { + // Cannot encrypt with empty passphrase + break; + } + if(newpass1 == newpass2) + { + if(model->setWalletEncrypted(true, newpass1)) + { + LOG_WRITE(LOG_INFO,"passwordsettingwidget::Encrypted",QString::number(getTag()).toStdString().c_str()); + if(2 == getTag()) + { + Q_EMIT openSendCoinsAffrimwidget(); + } + else + { + ui->label_error->setText(tr("passwordset success")); + Q_EMIT ChangePasswordSuccess(); + } + } + else + { + ui->label_error->setText(tr("Password mismatch")); + } + } + else + { + ui->label_error->setText(tr("Wallet encryption failed")); + } + + } break; + case Unlock: + if(!model->setWalletLocked(false, oldpass)) + { + ui->label_error->setText(tr("Wallet unlock failed")); + } + break; + case Decrypt: + if(!model->setWalletEncrypted(false, oldpass)) + { + ui->label_error->setText(tr("Wallet decryption failed")); + } + break; + case ChangePass: + oldpass.assign(ui->passEdit1->text().toStdString().c_str()); + newpass1.assign(ui->passEdit2->text().toStdString().c_str()); + newpass2.assign(ui->passEdit3->text().toStdString().c_str()); + if(newpass1 == newpass2) + { + int64_t timenum = 0; + int iPasswordErrorNum = 0; + bool was_locked = (model->getEncryptionStatus() == WalletModel::Locked)?1:0; + if(was_locked) + { + QSettings settings; + iPasswordErrorNum = settings.value("PasswordErrorNum").toInt(); + LOG_WRITE(LOG_INFO,"passwordsettingwidget::iPasswordErrorNum",QString::number(iPasswordErrorNum).toStdString().c_str()); + timenum = timeService.GetCurrentTimeSeconds(); + if(iPasswordErrorNum >= 5){ + QString locktime = settings.value("locktime").toString(); + LOG_WRITE(LOG_INFO,"passwordsettingwidget::timeService::GetCurrentTimeSeconds",QString::number(timenum).toStdString().c_str(),"locktime",locktime.toStdString().c_str()); + QString strtimenum = QString::number(timenum); + if(locktime > strtimenum){ + CMessageBox msg; + msg.setGeometry(this->x()+(this->width()-msg.width())/2, + this->y()+(this->height()-msg.height())/2,msg.width(),msg.height()); + + msg.setIsClose(false); + msg.setMessage(2); + msg.exec(); + ui->label_error->setText(tr("Wallet unlock failed")); + return; + } + } + if(model->changePassphrase(oldpass, newpass1)) + { + LOG_WRITE(LOG_INFO,"passwordsettingwidget::changePassphrase",QString::number(getTag()).toStdString().c_str()); + + settings.setValue("PasswordErrorNum", 0); + ui->label_error->setText(tr("Wallet passphrase was successfully changed.")); + if(2 == getTag()) + { + Q_EMIT openSendCoinsAffrimwidget(); + } + else + { + ui->label_error->setText(tr("passwordset success")); + Q_EMIT ChangePasswordSuccess(); + } + } + else + { + timenum = timenum + (int64_t)60*60*24; + settings.setValue("PasswordErrorNum", iPasswordErrorNum +1); + settings.setValue("locktime", QString::number(timenum)); + ui->label_error->setText(tr("Wallet encryption failed,The passphrase entered for the wallet decryption was incorrect.")); + } + }else{ + LOG_WRITE(LOG_INFO,"passwordsettingwidget::no lock"); + } + } + else + { + ui->label_error->setText(tr("Wallet encryption failed")); + secureClearPassFields(); + } + break; + } +} +int PasswordSettingWidget::getTag() +{ + return m_tag; +} +void PasswordSettingWidget::setTag(int tag) +{ + m_tag = tag; +} +void PasswordSettingWidget::textChanged() +{ + // Validate input, set Ok button to enabled when acceptable + bool acceptable = false; + switch(mode) + { + case Encrypt: + acceptable = !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty(); + break; + case Unlock: + case Decrypt: + break; + case ChangePass: + break; + } +} + +bool PasswordSettingWidget::event(QEvent *event) +{ + // Detect Caps Lock key press. + if (event->type() == QEvent::KeyPress) { + QKeyEvent *ke = static_cast(event); + if (ke->key() == Qt::Key_CapsLock) { + fCapsLock = !fCapsLock; + } + } + return QWidget::event(event); +} + +static void SecureClearQLineEdit(QLineEdit* edit) +{ + // Attempt to overwrite text so that they do not linger around in memory + edit->setText(QString(" ").repeated(edit->text().size())); + edit->clear(); +} + +void PasswordSettingWidget::secureClearPassFields() +{ + SecureClearQLineEdit(ui->passEdit2); + SecureClearQLineEdit(ui->passEdit3); +} + diff --git a/.svn/pristine/58/58cc83331ec648df097486235e97989a3799aeb6.svn-base b/.svn/pristine/58/58cc83331ec648df097486235e97989a3799aeb6.svn-base new file mode 100644 index 0000000..6931aa7 --- /dev/null +++ b/.svn/pristine/58/58cc83331ec648df097486235e97989a3799aeb6.svn-base @@ -0,0 +1,82 @@ + + + unionaccounthistory + + + + 0 + 0 + 809 + 783 + + + + Form + + + + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + background-image: url(:/res/png/back.png);border:none + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + border:none + + + true + + + + + 0 + 0 + 787 + 711 + + + + + + + + + + diff --git a/.svn/pristine/59/590e70213c9afdab119979d5a30202f672cab88d.svn-base b/.svn/pristine/59/590e70213c9afdab119979d5a30202f672cab88d.svn-base new file mode 100644 index 0000000..aca9cb0 --- /dev/null +++ b/.svn/pristine/59/590e70213c9afdab119979d5a30202f672cab88d.svn-base @@ -0,0 +1,364 @@ +#include "unionaccount.h" +#include "ui_unionaccount.h" +#include +#include "walletmodel.h" +#include "unionaccountcreate.h" +#include "unionaccountgenkey.h" +#include "unionaccountjoin.h" +#include "unionaccounttransaction.h" +#include "unionaccounttrasend.h" +#include "unionaccounttrasign.h" +#include "unionaccounthistory.h" +#include "unionacounthistorydetail.h" +#include "unionacounthistorydetailr.h" +#include "successfultrade.h" +#include "ipcselectaddress.h" +#include "upgradewidget.h" +#include "log/log.h" +#include "wallet/wallet.h" +unionaccount* g_unionaccount = NULL; +bool unionaccount::m_bNeedUpdateLater = false; +unionaccount::unionaccount(QWidget *parent) : + QWidget(parent),pOldSelectIpcButtons(NULL), + ui(new Ui::unionaccount) +{ + ui->setupUi(this); + + ui->scrollArea->setFrameShape(QFrame::NoFrame); + + ui->label_num->setText(tr("Unionaccount Total num:") + "0"); + + walletStackBranchPage = ui->stackedWidget; + + unionaccountcreatePage = new unionaccountcreate(this); + walletStackBranchPage->addWidget(unionaccountcreatePage); + connect(unionaccountcreatePage,SIGNAL(opensuccesscreatePage(QString,QString)),this,SLOT(gotosuccesscreatePage(QString,QString))); + + unionaccountgenkeyPage = new unionaccountgenkey(this); + walletStackBranchPage->addWidget(unionaccountgenkeyPage); + connect(unionaccountgenkeyPage,SIGNAL(opensuccessgenkeyPage()),this,SLOT(gotounionaccountgenkeyPage())); + + connect(unionaccountgenkeyPage,SIGNAL(selectaddress()),this,SLOT(gotoUnionAddressPage())); + + unionaccountjoinPage= new unionaccountjoin(this); + walletStackBranchPage->addWidget(unionaccountjoinPage); + + connect(unionaccountjoinPage,SIGNAL(opensuccessjoinPage()),this,SLOT(gotosuccessjoinPage())); + + SuccessfulTradePage= new SuccessfulTrade(this); + walletStackBranchPage->addWidget(SuccessfulTradePage); + unionaccounttransactionPage= new unionaccounttransaction(this); + connect(unionaccounttransactionPage,SIGNAL(gosendPage(QString)),this,SLOT(gotosendPage(QString))); + connect(unionaccounttransactionPage,SIGNAL(gosignPage()),this,SLOT(gotosignPage())); + + walletStackBranchPage->addWidget(unionaccounttransactionPage); + unionaccounttrasendPage= new unionaccounttrasend(this); + + + walletStackBranchPage->addWidget(unionaccounttrasendPage); + connect(unionaccounttrasendPage,SIGNAL(opensendsuccessPage(QString,QString)),this,SLOT(gotosendsuccessPage(QString,QString))); + unionaccounttrasignPage= new unionaccounttrasign(this); + walletStackBranchPage->addWidget(unionaccounttrasignPage); + connect(unionaccounttrasignPage,SIGNAL(opensignsuccessPage()),this,SLOT(gotosignsuccessPage())); + + unionSelectAddressPage = new ipcSelectAddress(this); + walletStackBranchPage->addWidget(unionSelectAddressPage); + + + + + connect(unionSelectAddressPage,SIGNAL(back(QString)),this,SLOT(gobacktounionaccountgenkeyPage(QString))); + + walletStackBranchPage->setCurrentWidget(unionaccountcreatePage); + connect(unionaccountjoinPage,SIGNAL(refreshunionaccount()),this,SLOT(updateunionaccountList())); + connect(unionaccountcreatePage,SIGNAL(refreshunionaccount()),this,SLOT(updateunionaccountList())); + + connect(unionaccounttrasendPage,SIGNAL(backtotraPage()),this,SLOT(gobacktotraPage())); + connect(unionaccounttrasignPage,SIGNAL(backtotraPage()),this,SLOT(gobacktotraPage())); + + + unionaccounthistoryPage = new unionaccounthistory(this); + walletStackBranchPage->addWidget(unionaccounthistoryPage); + + + connect(unionaccounttransactionPage,SIGNAL(jumptohistorypage(CAmount,std::string,std::map)),this,SLOT(gotohistorypage(CAmount,std::string,std::map))); + + + connect(unionaccounthistoryPage,SIGNAL(jumptohistorysend(std::string, CAmount,bool,CAmount,QString,QString,QString)),this,SLOT(gotohistorysend(std::string, CAmount,bool,CAmount,QString,QString,QString))); + + connect(unionaccounthistoryPage,SIGNAL(jumptohistoryrecv(std::string, CAmount,bool,CAmount,QString,QString,QString)),this,SLOT(gotohistoryrecv(std::string, CAmount,bool,CAmount,QString,QString,QString))); + + + + unionacounthistorydetailPage = new unionacounthistorydetail(this); + walletStackBranchPage->addWidget(unionacounthistorydetailPage); + + unionacounthistorydetailPageR = new unionacounthistorydetailR(this); + walletStackBranchPage->addWidget(unionacounthistorydetailPageR); + + + connect(unionacounthistorydetailPageR,SIGNAL(unionRPage_back()),this,SLOT(unionRPage_goback())); + + connect(unionacounthistorydetailPage,SIGNAL(unionPage_back()),this,SLOT(unionPage_goback())); + + connect(unionaccounthistoryPage,SIGNAL(backtoTraPage()),this,SLOT(gobacktoTrainfoPage())); + + + g_unionaccount = this; + +} + +unionaccount::~unionaccount() +{ + delete ui; +} +void unionaccount::gobacktoTrainfoPage() +{ + walletStackBranchPage->setCurrentWidget(unionaccounttransactionPage); +} +void unionaccount::unionRPage_goback() +{ + walletStackBranchPage->setCurrentWidget(unionaccounthistoryPage); +} +void unionaccount::unionPage_goback() +{ + walletStackBranchPage->setCurrentWidget(unionaccounthistoryPage); +} +void unionaccount::updataLater() +{ + if(unionaccount::m_bNeedUpdateLater) + { + updatalist(); + unionaccount::m_bNeedUpdateLater = false; + } +} +void unionaccount::gotohistorypage(CAmount num,std::string add,std::map s) +{ + unionaccounthistoryPage->setnum(num); + unionaccounthistoryPage->setAdd(add); + + LOG_WRITE(LOG_INFO,"updateinfoupdateinfo",QString::number(s.size()).toStdString().c_str()); + unionaccounthistoryPage->updateinfo(s); + + walletStackBranchPage->setCurrentWidget(unionaccounthistoryPage); +} +void unionaccount::updatalist() +{ + if(g_unionaccount&&g_unionaccount->model&&g_unionaccount->model->m_bFinishedLoading){ + + g_unionaccount->updateunionaccountList(); + } +} +void unionaccount::updateunionaccountList() +{ + if(model) + { + std::vector addinfo; + model->getUnionAddressinfo(addinfo); + ui->label_num->setText(tr("Unionaccount Total num:")+tr(" ")+QString::number(addinfo.size())); + QWidget * pnewall = new QWidget(); + pvboxlayoutall = new QVBoxLayout(); + pnewall->setLayout(pvboxlayoutall); + ui->scrollArea->setWidget(pnewall); + pOldSelectIpcButtons = NULL; + for (std::vector::iterator ii = addinfo.begin(); ii != addinfo.end(); ++ii) + { + QString address=QString::fromStdString((*ii).address); + QString name=QString::fromStdString((*ii).name); + QString tempname = name; + if(name.size()>8 ){ + tempname = name.mid(0,8); + tempname+="..."; + } + addnewoneaccount(name,address,tempname); + } + QSpacerItem* horizontalSpacer = new QSpacerItem(20,40,QSizePolicy::Minimum, QSizePolicy::Expanding); + pvboxlayoutall->addSpacerItem(horizontalSpacer); + } +} + +int unionaccount::addnewoneaccount(QString name,QString add,QString m_name) +{ + upgradewidget * pnewone = new upgradewidget(); + + + pnewone->name = name; + pnewone->m_name = m_name; + pnewone->add =add; + pnewone->setMaximumHeight(70); + pnewone->setMinimumHeight(70); + pnewone->setAutoFillBackground(true); + QPalette palette; + palette.setColor(QPalette::Background, QColor(79,194,186)); + pnewone->setPalette(palette); + + QHBoxLayout * phboxlayout = new QHBoxLayout(); + phboxlayout->setContentsMargins(0,0,0,0); + pnewone->setLayout(phboxlayout); + + QLabel* pemptylabel = new QLabel(" "); + phboxlayout->addWidget(pemptylabel); + QLabel* namelabel = new QLabel(m_name); + namelabel->setAttribute(Qt::WA_TranslucentBackground); + QFont ftname; + ftname.setPointSize(16); + namelabel->setFont(ftname); + QPalette paname; + paname.setColor(QPalette::WindowText,Qt::white); + namelabel->setPalette(paname); + phboxlayout->addWidget(namelabel); + QSpacerItem* horizontalSpacer = new QSpacerItem(40,20,QSizePolicy::Expanding); + phboxlayout->addSpacerItem(horizontalSpacer); + QLabel* picendlabel = new QLabel(); + pnewone->setipcselectlabel(picendlabel); + + + + + QPixmapCache::clear(); + QPixmapCache::setCacheLimit(1); + + + QPixmap p; + p.load(":/res/png/triangle.png"); + picendlabel->setPixmap(p); + phboxlayout->addWidget(picendlabel); + picendlabel->hide(); + connect(pnewone,SIGNAL(selectinfo(QString,QString)),this,SLOT(gotoUnionAccounttrainfo(QString,QString))); + + connect(pnewone,SIGNAL(selectlabel(QLabel*)),this,SLOT(changelabel(QLabel*))); + + pvboxlayoutall->addWidget(pnewone); + return 1; + +} +void unionaccount::changelabel(QLabel* date) +{ + if(pOldSelectIpcButtons == date)return; + if(pOldSelectIpcButtons)pOldSelectIpcButtons->hide(); + pOldSelectIpcButtons = date; +} +void unionaccount::gotoUnionAccounttrainfo(QString name,QString add) +{ + + std::map addinfo; + CAmount num = 0; + addinfo.clear(); + + addinfo.insert(make_pair(add.toStdString().c_str(), num)); + model->getAccounttrainfo(addinfo); + std::string m_add = add.toStdString().c_str(); + num = addinfo[m_add]; + std::string m_script = ""; + int sign_num = 0; + int nRequired = 0; + model->getScript(m_add,sign_num,nRequired,m_script); + unionaccounttransactionPage->setinfo(name,add,num,m_script, + QString::number(nRequired), + QString::number(sign_num)); + walletStackBranchPage->setCurrentWidget(unionaccounttransactionPage); +} + +void unionaccount::gotohistorysend(std::string add, CAmount fee,bool isSend,CAmount num,QString status,QString strtime,QString txid) +{ + + LOG_WRITE(LOG_INFO,"gotohistorysend",QString::number(fee).toStdString().c_str()); + unionacounthistorydetailPage->setinfo(add, fee,isSend,num,status,strtime,txid); + walletStackBranchPage->setCurrentWidget(unionacounthistorydetailPage); +} +void unionaccount::gotohistoryrecv(std::string add, CAmount fee,bool isSend,CAmount num,QString status,QString strtime,QString txid) +{ + unionacounthistorydetailPageR->setinfo(add, fee,isSend,num,status,strtime,txid); + walletStackBranchPage->setCurrentWidget(unionacounthistorydetailPageR); +} + +void unionaccount::setModel(WalletModel *_model) +{ + this->model = _model; + unionacounthistorydetailPage->setModel(model); + unionacounthistorydetailPageR->setModel(model); + unionaccountcreatePage->setModel(this->model); + unionaccountgenkeyPage->setModel(this->model); + unionaccountjoinPage->setModel(this->model); + unionaccounttransactionPage->setModel(this->model); + unionaccounttrasendPage->setModel(this->model); + unionaccounttrasignPage->setModel(this->model); + unionSelectAddressPage->setWalletModel(this->model); + unionaccounthistoryPage->setModel(this->model); + connect(model,SIGNAL(updataLoadingFinished()),this,SLOT(updateunionaccountList())); + //connect(model,SIGNAL(updataLater()),this,SLOT(updataLater())); + updateunionaccountList(); + +} +void unionaccount::on_createuniaccBtn_pressed() +{ + unionaccountcreatePage->setInit(); + walletStackBranchPage->setCurrentWidget(unionaccountcreatePage); +} + +void unionaccount::on_joinuniaccBtn_pressed() +{ + walletStackBranchPage->setCurrentWidget(unionaccountjoinPage); +} + +void unionaccount::on_genkeyBtn_pressed() +{ + unionaccountgenkeyPage->clearinfo(); + walletStackBranchPage->setCurrentWidget(unionaccountgenkeyPage); +} +void unionaccount::gotoUnionAddressPage() +{ + walletStackBranchPage->setCurrentWidget(unionSelectAddressPage); + +} + +void unionaccount::gobacktounionaccountgenkeyPage(QString address) +{ + if(!address.isEmpty()) + unionaccountgenkeyPage->setaddress(address); + else + unionaccountgenkeyPage->clearData(); + walletStackBranchPage->setCurrentWidget(unionaccountgenkeyPage); +} +void unionaccount::gotosuccesscreatePage(QString s1,QString s2) +{ + SuccessfulTradePage->setSuccessText_(s1,s2); + walletStackBranchPage->setCurrentWidget(SuccessfulTradePage); + +} +void unionaccount::gotounionaccountgenkeyPage() +{ + walletStackBranchPage->setCurrentWidget(SuccessfulTradePage); + +} +void unionaccount::gotosuccessjoinPage() +{ + walletStackBranchPage->setCurrentWidget(SuccessfulTradePage); + +} +void unionaccount::gotosendPage(QString add) +{ + unionaccounttrasendPage->setaddress(add); + walletStackBranchPage->setCurrentWidget(unionaccounttrasendPage); + +} +void unionaccount::gotosignPage() +{ + unionaccounttrasignPage->set0Text(); + string address = unionaccounttransactionPage->getAddress(); + unionaccounttrasignPage->setSourceAddress(address); + walletStackBranchPage->setCurrentWidget(unionaccounttrasignPage); +} +void unionaccount::gotosendsuccessPage(QString s1,QString s2) +{ + SuccessfulTradePage->setsendSuccessText_(s1,s2); + walletStackBranchPage->setCurrentWidget(SuccessfulTradePage); +} +void unionaccount::gotosignsuccessPage() +{ + walletStackBranchPage->setCurrentWidget(SuccessfulTradePage); +} +void unionaccount::gobacktotraPage() +{ + walletStackBranchPage->setCurrentWidget(unionaccounttransactionPage); +} diff --git a/.svn/pristine/5c/5c0cf63ace684760ca9ec1b840a2eca1a5f723a1.svn-base b/.svn/pristine/5c/5c0cf63ace684760ca9ec1b840a2eca1a5f723a1.svn-base new file mode 100644 index 0000000..aa6b588 --- /dev/null +++ b/.svn/pristine/5c/5c0cf63ace684760ca9ec1b840a2eca1a5f723a1.svn-base @@ -0,0 +1,275 @@ + + + ipcdialog + + + + 0 + 0 + 655 + 649 + + + + Form + + + + + + 0 + + + + + + 16777215 + 49 + + + + + + 10 + 10 + 23 + 17 + + + + IPC + + + Qt::AlignCenter + + + + + + + + + 310 + 177 + + + + + 310 + 177 + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + 0 + 0 + + + + + 16777215 + 201 + + + + + -1 + + + + font-size : 30px; +color: rgb(31, 168, 123); + + + Ip Total + + + Qt::AlignCenter + + + + + + + 10 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 120 + 35 + + + + + 120 + 35 + + + + Qt::NoFocus + + + background-image: url(:/res/png/buttons/120_35.png);border:none;font-size : 16px; +color: rgb(255,255,255); + + + IP register + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 120 + 35 + + + + + 120 + 35 + + + + Qt::NoFocus + + + background-image: url(:/res/png/buttons/120_35.png);border:none;color: rgb(255,255,255);font-size : 16px; + + + Inspection tag + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + 310 + 0 + + + + + 310 + 16777215 + + + + Qt::CustomContextMenu + + + QFrame::NoFrame + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 310 + 452 + + + + + + + + + + + 1 + + + + + + + + + + diff --git a/.svn/pristine/5c/5c172565f07f5e4f579168794ad1efe60eb20e26.svn-base b/.svn/pristine/5c/5c172565f07f5e4f579168794ad1efe60eb20e26.svn-base new file mode 100644 index 0000000..3e498a8 --- /dev/null +++ b/.svn/pristine/5c/5c172565f07f5e4f579168794ad1efe60eb20e26.svn-base @@ -0,0 +1,427 @@ +#include "ipcdetails.h" +#include "ui_ipcdetails.h" +#include "walletmodel.h" +#include "guiutil.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "log/log.h" +extern bool g_bIpchainShutdown; +bool firststart = 1; +bool g_staticfirststart2 = 1; +QStringList type = QStringList()<setupUi(this); + QPalette patime; + patime.setColor(QPalette::WindowText,Qt::gray); + ui->label_t7->setPalette(patime); + ui->label_t8->setPalette(patime); + m_nTimerId = startTimer(10000); + m_pushButton_transfer_show = false; + m_pushButton_authorization_show = false; + m_bCanTransaction = false; +} + +IpcDetails::~IpcDetails() +{ + killTimer(m_nTimerId); + delete ui; +} + +void IpcDetails::on_pushButton_back_pressed() +{ + Q_EMIT back(); +} + +void IpcDetails::on_pushButton_transfer_pressed() +{ + Q_EMIT gotoIpcTransferTransactionPage(ui->label_t1->text()); +} + +void IpcDetails::on_pushButton_authorization_pressed() +{ + Q_EMIT gotoIpcAuthorizationTransactionPage(ui->label_t1->text()); +} +void IpcDetails::resetinfo(int index) +{ + + ui->pushButton_transfer->hide(); + ui->pushButton_authorization->hide(); + ui->pushButton_toimage->hide(); + m_bCanTransaction = false; + if(walletModel) + { + m_index = index; + QStringList back = walletModel->getInfoFromIpcList(index); + if(back.size()>=13) + { + QString name = back.at(0); + + if(name.size()>55&&name.size()==name.toStdString().length()) + name.insert(54," "); + + ui->label_t1->setText(name); + + int typenum = back.at(1).toInt(); + QStringList type = QStringList()<=0&&typenum<8) + { + ui->label_t2->setText(type.at(typenum)); + } + else + { + ui->label_t2->setText(tr("patent")); + } + ui->label_t3->setText(back.at(2)); + if(back.at(3) == "forever") + { + ui->label_t4->setText(tr("forever")); + }else + ui->label_t4->setText(back.at(3)); + m_ui_label_t5 = back.at(4); + if("ownership"==back.at(4)){ + ui->label_t5->setText(tr("ownership")); + }else{ + ui->label_t5->setText(tr("Use right")); + } + m_ui_label_t6 = back.at(5); + if("can authorization"==back.at(5)){ + ui->label_t6->setText(tr("can authorization")); + }else{ + ui->label_t6->setText(tr("cannot authorization")); + } + + ui->label_t7->setText(back.at(6)); + ui->label_t8->setText(back.at(7)); + ui->label_t8->setAlignment(Qt::AlignLeft); + ui->label_t9->setText(back.at(8)); + + ui->label_t10->setText(back.at(9)); + if(back.at(10)=="1") + { + m_pushButton_transfer_show = true; + } + else + { + m_pushButton_transfer_show = false; + } + if(back.at(11)=="1") + { + m_pushButton_authorization_show = true; + } + else + { + m_pushButton_authorization_show = false; + } + + m_strExclusive = back.at(12); + QString canusetime = back.at(13); + ui->label_inuretime->setText(canusetime); + + if(back.at(8) == "") + { + ui->label_t9->hide(); + ui->label_18->hide(); + ui->line_9->hide(); + }else{ + if(firststart){ + firststart = 0; + ui->label_t9->document()->adjustSize(); + } + int row = ui->label_t9->document()->size().height(); + ui->label_t9->setMinimumHeight(row+5); + ui->label_t9->setMaximumHeight(row+5); + ui->label_t9->show(); + ui->label_18->show(); + ui->line_9->show(); + } + + if(walletModel->GetDepthInMainChain(index)>=8){ + bool bcanshow = canTransaction(); + if(m_pushButton_transfer_show&&bcanshow) + ui->pushButton_transfer->show(); + if(m_pushButton_authorization_show&&bcanshow) + ui->pushButton_authorization->show(); + ui->pushButton_toimage->show(); + }else{ + ui->pushButton_transfer->hide(); + ui->pushButton_authorization->hide(); + ui->pushButton_toimage->hide(); + } + } + } +} +void IpcDetails::on_pushButton_toimage_pressed() +{ + QLocale locale; + QString file_full, file_name, file_path; + QFileInfo fi; + file_full = QFileDialog::getSaveFileName(this,"","/","image Files(*.png)"); + if(file_full == "") + { + return; + } + if(file_full.right(4)!=".png"){ + file_full=file_full+".png"; + QFile mFile(file_full); + if(mFile.exists()) + { + QMessageBox::StandardButton reply; + if( locale.language() == QLocale::Chinese ) + reply = QMessageBox::question(this, "IPC", "该文件å已存在,是å¦è¦æ›¿æ¢ï¼Ÿ", QMessageBox::Yes | QMessageBox::No); + else + reply = QMessageBox::question(this, "IPC", "The file name already exists. Do you want to replace it?", QMessageBox::Yes | QMessageBox::No); + if(reply != QMessageBox::Yes) + { + return; + } + } + } + + bool isChineseLanguage = false; + + QImage image ; + image = QPixmap(":res/png/ipcinfoEnglish.png").toImage(); + QPainter painter(&image); + painter.setCompositionMode(QPainter::CompositionMode_SourceIn); + + QPen pen = painter.pen(); + pen.setColor(QColor(198,156,109)); + QFont font = painter.font(); + font.setFamily("SimplifiedChinese"); + + int fontsize = 18; + font.setPixelSize(fontsize); + + painter.setPen(pen); + painter.setFont(font); + QString label_t1_text = ui->label_t1->text(); + if(label_t1_text.size()<=20){ + painter.drawText(195,286+fontsize,label_t1_text); + + }else if(label_t1_text.size()<=40){ + painter.drawText(195,286-20+fontsize,label_t1_text.mid(0, 20)); + painter.drawText(195,286+fontsize,label_t1_text.mid(20, 20)); + } + else if(label_t1_text.size()<=60){ + painter.drawText(195,286-40+fontsize,label_t1_text.mid(0, 20)); + painter.drawText(195,286-20+fontsize,label_t1_text.mid(20, 20)); + painter.drawText(195,286+fontsize,label_t1_text.mid(40, 20)); + } + else{ + painter.drawText(195,286-60+10+fontsize,label_t1_text.mid(0, 20)); + painter.drawText(195,286-40+10+fontsize,label_t1_text.mid(20, 20)); + painter.drawText(195,286-20+10+fontsize,label_t1_text.mid(40, 20)); + painter.drawText(195,286+10+fontsize,label_t1_text.mid(60, 20)); + } + + QString label_t2_text = ui->label_t2->text(); + QStringList type = QStringList()<label_t5->text(); + if(isChineseLanguage){ + if(label_t5_text == tr("ownership")){ + painter.drawText(266,350+fontsize,"所有æƒ"); + } + else{ + painter.drawText(266,350+fontsize,"使用æƒ"); + } + }else{ + painter.drawText(266,350+fontsize,label_t5_text); + } + + QString label_t3_text = ui->label_t3->text(); + label_t3_text = QChineseTimeToEnglish(label_t3_text); + painter.drawText(240,385+fontsize,label_t3_text); + + QString label_t4_text = ui->label_t4->text(); + if(isChineseLanguage){ + if(label_t4_text == "forever")label_t4_text= "永久"; + painter.drawText(202,416+fontsize,label_t4_text); + }else{ + label_t4_text = QChineseTimeToEnglish(label_t4_text); + painter.drawText(202,416+fontsize,label_t4_text); + } + + QString inuretime = ui->label_inuretime->text(); + inuretime = QChineseTimeToEnglish(inuretime); + painter.drawText(246,451+fontsize,inuretime); + + QString label_t6_text = m_ui_label_t6;//ui->label_t6->text(); + if(isChineseLanguage){ + if(label_t6_text == tr("can authorization")){ + painter.drawText(300,484+fontsize,"å¯å†æŽˆæƒ"); + } + else{ + painter.drawText(300,484+fontsize,"ä¸å¯å†æŽˆæƒ"); + } + }else{ + painter.drawText(300,484+fontsize,label_t6_text); + } + QString hashstr = ui->label_t7->text(); + + + QString str = hashstr;; + + char* ch; + + QByteArray ba = str.toLatin1(); + + ch=ba.data(); + + QRcode *code = QRcode_encodeString(ch, 0, QR_ECLEVEL_L, QR_MODE_8, 1); + if (!code) + { + } + else + { + QImage qrImage = QImage(code->width , code->width , QImage::Format_RGB32); + unsigned char *p = code->data; + for (int y = 0; y < code->width; y++) + { + for (int x = 0; x < code->width; x++) + { + qrImage.setPixel(x , y , ((*p & 1) ? 0x363535 : 0xC69C6D)); + p++; + } + } + QRcode_free(code); + QImage qrAddrImage = QImage(140, 140, QImage::Format_RGB32); + QPainter painter1(&qrAddrImage); + painter1.drawImage(0, 0, qrImage.scaled(140, 140)); + font = GUIUtil::fixedPitchFont(); + font.setPixelSize(0);//25 + painter1.setFont(font); + QRect paddedRect = qrAddrImage.rect(); + paddedRect.setHeight(140); + painter1.end(); + painter.drawPixmap(277,569, QPixmap::fromImage(qrAddrImage)); + } + font.setPixelSize(fontsize); + font.setBold(true); + painter.setFont(font); + painter.drawText(183,517+fontsize,hashstr); + image.save(file_full,0); +} + +QString IpcDetails::QChineseTimeToEnglish(QString chtime) +{ + chtime.replace("å¹´","/"); + chtime.replace("æ—¥",""); + chtime.replace("月","/"); + chtime.replace("永久","forever"); + return chtime; +} + +QString IpcDetails::getStartTime() +{ + return ui->label_t3->text(); +} + +void IpcDetails::timerEvent( QTimerEvent *event ) +{ + if(m_index<0) + return; + if(g_bIpchainShutdown||!walletModel->m_bFinishedLoading)return; + try{ + int num = walletModel->GetDepthInMainChain(m_index); + if(num >= 0) + { + QString queren = QString::number(num); + queren.append("+"); + ui->label_t10->setText(queren); + if(num >=8) + { + if(m_pushButton_transfer_show&&canTransaction()) + ui->pushButton_transfer->show(); + if(m_pushButton_authorization_show&&canTransaction()) + ui->pushButton_authorization->show(); + ui->pushButton_toimage->show(); + + } + else if(num < 3){ + ui->label_inuretime->setText(walletModel->GetTimeOfTokenInChain(m_index)); + } + } + } + catch(...){ + LOG_WRITE(LOG_INFO,"IpcDetails::timerEvent Error"); + } +} +bool IpcDetails::canTransaction() +{ + if(!m_bCanTransaction) + m_bCanTransaction = walletModel->CanIPCTransaction(m_index); + return m_bCanTransaction; +} diff --git a/.svn/pristine/5d/5dbcdf1005ab135db4d1889ce6005526a0fa264c.svn-base b/.svn/pristine/5d/5dbcdf1005ab135db4d1889ce6005526a0fa264c.svn-base new file mode 100644 index 0000000..1046a08 --- /dev/null +++ b/.svn/pristine/5d/5dbcdf1005ab135db4d1889ce6005526a0fa264c.svn-base @@ -0,0 +1,233 @@ + + + unionaccountjoin + + + + 0 + 0 + 710 + 575 + + + + Form + + + + + + + 0 + 103 + + + + + 16777215 + 103 + + + + font-size : 28px; +color: rgb(51, 51, 51); + + + join unionaccount + + + + + + + + + + + 120 + 0 + + + + + 120 + 16777215 + + + + name + + + + + + + 8 + + + name + + + + + + + + + + Qt::Horizontal + + + + + + + + + + + 120 + 0 + + + + + 120 + 16777215 + + + + import scripts + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + + + + + + 100 + 30 + + + + + 100 + 30 + + + + background-image: url(:/icons/res/png/ioport.png);border:none + + + import + + + + + + + + + + color: rgb(255, 0, 0); + + + Please get joint scripts from the joint account person + + + + + + + Qt::Horizontal + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 266 + 20 + + + + + + + + + 421 + 50 + + + + + 421 + 50 + + + + background-image: url(:/res/png/buttons/421_50.png);border:none;color: rgb(255,255,255);font-size : 16px; + + + join + + + + + + + Qt::Horizontal + + + + 265 + 20 + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/.svn/pristine/60/60fc10ddde83d4c61e79d122cc79a0d20a81765b.svn-base b/.svn/pristine/60/60fc10ddde83d4c61e79d122cc79a0d20a81765b.svn-base new file mode 100644 index 0000000..62c37f0 --- /dev/null +++ b/.svn/pristine/60/60fc10ddde83d4c61e79d122cc79a0d20a81765b.svn-base @@ -0,0 +1,119 @@ +// Copyright (c) 2011-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_QT_OVERVIEWPAGE_H +#define BITCOIN_QT_OVERVIEWPAGE_H +//QTableView de tableview +#include "amount.h" +#include "guiutil.h" +#include +#include + +class ClientModel; +class TransactionFilterProxy; +class TxViewDelegate; +class PlatformStyle; +class WalletModel; +class TransactionView; +class TransactionRecord; +class InfoWidget; +class sendhistory; +class RecvHistory; +class sendipchistory; +class recvipchistory; +class SendTokenHistory; +class RecvTokenHistory; +namespace Ui { +class overviewpage; +} + +QT_BEGIN_NAMESPACE +class QModelIndex; +QT_END_NAMESPACE + +/** Overview ("home") page widget */ +class OverviewPage : public QWidget +{ + Q_OBJECT + +public: + explicit OverviewPage(const PlatformStyle *platformStyle, QWidget *parent = 0); + ~OverviewPage(); + static quint32 TYPE(int type) { return 1< filter; + + std::vector vWidget; + std::vector::iterator arr; + //QWidget* wWidget; + InfoWidget * singleton1; + QModelIndex index_; + +private Q_SLOTS: + void chooseDate(int idx); + void updateDisplayUnit(); + void handleOutOfSyncWarningClicks(); + void on_listTransactions_clicked(const QModelIndex &index); + void on_showdetailButton_pressed(); + +}; + +#endif // BITCOIN_QT_OVERVIEWPAGE_H diff --git a/.svn/pristine/61/6179d8d733ae42ef799c80b760218032b23c7542.svn-base b/.svn/pristine/61/6179d8d733ae42ef799c80b760218032b23c7542.svn-base new file mode 100644 index 0000000..1080305 --- /dev/null +++ b/.svn/pristine/61/6179d8d733ae42ef799c80b760218032b23c7542.svn-base @@ -0,0 +1,217 @@ +// Copyright (c) 2011-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_QT_WALLETVIEW_H +#define BITCOIN_QT_WALLETVIEW_H + +#include "amount.h" + +#include + +class BitcoinGUI; +class ClientModel; +class OverviewPage; +class PlatformStyle; +class ReceiveCoinsDialog; +class SendCoinsDialog; +class SendCoinsRecipient; +//class TransactionView; +class WalletModel; +//class AddressBookPage; +class ipcdialog; +class setdialog; +class ECoinDialog; +class unionaccount; +class SendConfirmationDialog; +class PasswordSettingWidget; +class SendCoinsAffrimWidget; +class InfoWidget; +class sendhistory; +class RecvHistory; +class sendipchistory; +class recvipchistory; +class SendTokenHistory; +class RecvTokenHistory; +class TallyAccount; +class TallyApply; +class TallyClause; +class TallyDscribe; +class TallyOutAccount; +class ipcSelectAddress; +class AddressTableModel; +class AddBookWidget; +class SendResultWidget; +#include +QT_BEGIN_NAMESPACE +class QModelIndex; +class QProgressDialog; +class Settingwidget; +QT_END_NAMESPACE + +/* + WalletView class. This class represents the view to a single wallet. + It was added to support multiple wallet functionality. Each wallet gets its own WalletView instance. + It communicates with both the client and the wallet models to give the user an up-to-date view of the + current core state. +*/ +struct SendInfo{ + QString Coin_; + QString Add_; + QString Label_; + int Status_; + +}; + + +class WalletView : public QStackedWidget +{ + Q_OBJECT + +public: + explicit WalletView(const PlatformStyle *platformStyle, QWidget *parent); + ~WalletView(); + void gotopsdsetpage(PasswordSettingWidget *PasswordSettingPage,int tag); + + + + void setvalue(SendInfo info); + SendInfo getvalue(); + + void setBitcoinGUI(BitcoinGUI *gui); + /** Set the client model. + The client model represents the part of the core that communicates with the P2P network, and is wallet-agnostic. + */ + void setClientModel(ClientModel *clientModel); + /** Set the wallet model. + The wallet model represents a bitcoin wallet, and offers access to the list of transactions, address book and sending + functionality. + */ + void setWalletModel(WalletModel *walletModel); + void opensendpage(sendhistory *sendpage); + void openrecvpage(RecvHistory *recvpage); + void opensendipcpage(sendipchistory *sendipcpage); + void openrecvipcpage(recvipchistory *recvipcpage); + void opensendtokenpage(SendTokenHistory *sendTokenPage); + void openrecvtokenpage(RecvTokenHistory *recvTokenPage); + void setVerticalLayout2AddWidget(QWidget *page); + + void setIsTallying(bool IsTally); + bool getIsTallying(); + + +private: + SendInfo sendinfo_; + ClientModel *clientModel; + WalletModel *walletModel; + PasswordSettingWidget* PasswordSettingPage; + SendCoinsAffrimWidget* SendCoinsAffrimPage; + //AddBookWidget* AddBookPage ; + AddBookWidget* AddBookPage_walletview ; + AddBookWidget* AddBookPage_setdialog; + + + OverviewPage *overviewPage; + //QWidget *transactionsPage; + + InfoWidget *infopage; + ReceiveCoinsDialog *receiveCoinsPage; + SendCoinsDialog *sendCoinsPage; + ipcdialog *ipcdialogPage; + setdialog *setdialogPage; + ECoinDialog *ecoinDialogPage; + unionaccount *unionaccountPage; + + QWidget * tallyDialogPage; + QStackedWidget *tallyDialogPageStack; + + SendResultWidget* sendresultpage ; + TallyAccount *pTallyAccount; + TallyApply *pTallyApply; + TallyClause *pTallyClause; + TallyDscribe *pTallyDscribe; + TallyOutAccount *pTallyOutAccount; + ipcSelectAddress *pTallySelectAddressPage; + + Settingwidget* settingwidgetPage; + QProgressDialog *progressDialog; + const PlatformStyle *platformStyle; + bool m_IsTallying; + +public Q_SLOTS: + /** Switch to overview (home) page */ + void gotoOverviewPage(); + /** Switch to receive coins page */ + void gotoReceiveCoinsPage(); + /** Switch to send coins page */ + void gotoSendCoinsPage(QString addr = "",QString label=""); + + void backtoSendCoinsPage(); + /** Switch to ipc page */ + void gotoIpcPage(); + /** Switch to set page */ + void gotoSetPage(); + void gotoSetDialogExportPage(); + void gotoUnionAccountPage(); + void gotoResultPage(); + void gotoTallyPage(); + void gotoeCoinPage(); + void gotoClausePage(); + void gotoDscribePage(); + void gotoTallyApplyPage(QString address= ""); + void gotoTallyAccountPage(QString add,CAmount num); + void gotoTallyOutAccountPage(QString add,CAmount num); + void gotoBackTallyAccountPage(bool); + void gotoTallyAddressPage(); + void gotoSendaffrimPage(QString a,QString b,QString label,int tag); + void gotoSettingPage(QString a,QString b,QString label,int tag); + void gotoPasswordSetwidgetPage(int tag); + void gotoSendCoinsAffrimPage(); + + void gotoPsdSetSuccessPage(); + void gotoAddBookPage(int tag); + void openAddBookPage(); + void gotoWalletViewPage(); + void gotoWalletViewPagekepinfo(); + void gotoWalletViewPaga(QString e,QString f); + + /** Show incoming transaction notification for new transactions. + + The new items are those between start and end inclusive, under the given parent item. + */ + void processNewTransaction(const QModelIndex& parent, int start, int /*end*/); + /** Encrypt the wallet */ + void encryptWallet(bool status); + /** Backup the wallet */ + void backupWallet(); + + /** Ask for passphrase to unlock wallet temporarily */ + void unlockWallet(); + + + /** Re-emit encryption status signal */ + void updateEncryptionStatus(); + + /** Show progress dialog e.g. for rescan */ + void showProgress(const QString &title, int nProgress); + + /** User has requested more information about the out of sync state */ + void requestedSyncWarningInfo(); + +Q_SIGNALS: + void openadd(); + /** Signal that we want to show the main window */ + void showNormalIfMinimized(); + /** Fired when a message should be reported to the user */ + void message(const QString &title, const QString &message, unsigned int style); + /** Encryption status of wallet changed */ + void encryptionStatusChanged(int status); + /** HD-Enabled status of wallet changed (only possible during startup) */ + void hdEnabledStatusChanged(int hdEnabled); + /** Notify that a new transaction appeared */ + void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label,const QString& ipctitle,const QString& ipctype); + /** Notify that the out of sync warning icon has been pressed */ + void outOfSyncWarningClicked(); +}; + +#endif // BITCOIN_QT_WALLETVIEW_H diff --git a/.svn/pristine/64/64c270efc5fdb8f6e531981f46e03d274278bf94.svn-base b/.svn/pristine/64/64c270efc5fdb8f6e531981f46e03d274278bf94.svn-base new file mode 100644 index 0000000..9aacdb4 Binary files /dev/null and b/.svn/pristine/64/64c270efc5fdb8f6e531981f46e03d274278bf94.svn-base differ diff --git a/.svn/pristine/67/67923ec41d9963c357106cb009b73d4999bd21cc.svn-base b/.svn/pristine/67/67923ec41d9963c357106cb009b73d4999bd21cc.svn-base new file mode 100644 index 0000000..7bfc41b --- /dev/null +++ b/.svn/pristine/67/67923ec41d9963c357106cb009b73d4999bd21cc.svn-base @@ -0,0 +1,658 @@ +// Copyright (c) 2011-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "walletview.h" +#include "ipchaingui.h" +#include "clientmodel.h" +#include "guiutil.h" +#include "optionsmodel.h" +#include "overviewpage.h" +#include "platformstyle.h" +#include "receivecoinsdialog.h" +#include "sendcoinsdialog.h" +#include "transactiontablemodel.h" +#include "walletmodel.h" +#include "settingwidget.h" +#include "ui_interface.h" +#include "ipcdialog.h" +#include "setdialog.h" +#include "infowidget.h" +#include "sendhistory.h" +#include "recvhistory.h" +#include "sendipchistory.h" +#include "recvipchistory.h" +#include "sendresultwidget.h" +#include "sendtokenhistory.h" +#include "recvtokenhistory.h" + +#include "passwordsettingwidget.h" +#include "sendcoinsaffrimwidget.h" +#include "addresstablemodel.h" +#include "addbookwidget.h" +//#include "editadddialog.h" +#include "ecoindialog.h" +#include "intro.h" +#include "unionaccount.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "tallyaccount.h" +#include "tallyapply.h" +#include "tallyclause.h" +#include "tallydscribe.h" +#include "tallyoutaccount.h" +#include "ipcselectaddress.h" + +#include "dpoc/DpocInfo.h" +#include "dpoc/DpocMining.h" +#include "log/log.h" + +WalletView::WalletView(const PlatformStyle *_platformStyle, QWidget *parent): + QStackedWidget(parent), + clientModel(0), + walletModel(0), + tallyDialogPage(0), + platformStyle(_platformStyle), + m_IsTallying(false) +{ + PasswordSettingPage = NULL; + overviewPage = new OverviewPage(platformStyle); + receiveCoinsPage = new ReceiveCoinsDialog(platformStyle); + sendCoinsPage = new SendCoinsDialog(platformStyle); + pTallySelectAddressPage = new ipcSelectAddress(this); + ipcdialogPage = new ipcdialog(); + setdialogPage = new setdialog(); + unionaccountPage = new unionaccount(); + + tallyDialogPage = new QWidget(); + tallyDialogPageStack = new QStackedWidget(); + AddBookPage_walletview = NULL; + AddBookPage_setdialog = NULL; + + QVBoxLayout *walletFrameLayout = new QVBoxLayout(); + walletFrameLayout->setContentsMargins(0,0,0,0); + walletFrameLayout->setContentsMargins(0,0,0,0); + tallyDialogPage->setLayout(walletFrameLayout); + walletFrameLayout->addWidget(tallyDialogPageStack); + + pTallyAccount = new TallyAccount(this); + pTallyApply = new TallyApply(this); + pTallyClause = new TallyClause(this); + pTallyDscribe = new TallyDscribe(this); + pTallyOutAccount = new TallyOutAccount(this); + tallyDialogPageStack->addWidget(pTallyAccount); + tallyDialogPageStack->addWidget(pTallyApply); + tallyDialogPageStack->addWidget(pTallyClause); + tallyDialogPageStack->addWidget(pTallyOutAccount); + tallyDialogPageStack->addWidget(pTallyDscribe); + tallyDialogPageStack->addWidget(pTallySelectAddressPage); + tallyDialogPageStack->setCurrentWidget(pTallyDscribe); + connect(pTallyDscribe,SIGNAL(next()),this,SLOT(gotoClausePage())); + connect(pTallyClause,SIGNAL(next()),this,SLOT(gotoTallyApplyPage())); + connect(pTallyClause,SIGNAL(back()),this,SLOT(gotoDscribePage())); + connect(pTallyApply,SIGNAL(next(QString,CAmount)),this,SLOT(gotoTallyAccountPage(QString,CAmount))); + connect(pTallyApply,SIGNAL(selectaddress()),this,SLOT(gotoTallyAddressPage())); + connect(pTallyAccount,SIGNAL(next(QString,CAmount)),this,SLOT(gotoTallyOutAccountPage(QString,CAmount))); + connect(pTallyOutAccount,SIGNAL(next(bool)),this,SLOT(gotoBackTallyAccountPage(bool))); + connect(pTallySelectAddressPage,SIGNAL(back(QString)),this,SLOT(gotoTallyApplyPage(QString))); + + ecoinDialogPage = new ECoinDialog(this); + + addWidget(overviewPage); + addWidget(receiveCoinsPage); + addWidget(sendCoinsPage); + addWidget(ipcdialogPage); + addWidget(unionaccountPage); + addWidget(setdialogPage); + addWidget(tallyDialogPage); + addWidget(ecoinDialogPage); + settingwidgetPage= new Settingwidget(this); + + addWidget(settingwidgetPage); + + connect(settingwidgetPage,SIGNAL(openPasswordSetwidget(int)),this,SLOT(gotoPasswordSetwidgetPage(int))); + connect(settingwidgetPage,SIGNAL(openSendCoinsAffrimwidget()),this,SLOT(gotoSendCoinsAffrimPage())); + + // Clicking on a transaction on the overview pre-selects the transaction on the transaction history page + // connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), parent, SLOT(focusTransaction(QModelIndex))); + connect(overviewPage, SIGNAL(transactionnnClicked(QModelIndex,quint8)), parent, SLOT(showwwDetails(QModelIndex,quint8))); + connect(overviewPage, SIGNAL(outOfSyncWarningClicked()), this, SLOT(requestedSyncWarningInfo())); + connect(sendCoinsPage,SIGNAL(openSettingwidget(QString,QString,QString,int)),this,SLOT(gotoSettingPage(QString,QString,QString,int))); + connect(sendCoinsPage,SIGNAL(openSendAffrimwidget(QString,QString,QString,int)),this,SLOT(gotoSendaffrimPage(QString,QString,QString,int))); + connect(sendCoinsPage,SIGNAL(openAddBookPagewidget(int)),this,SLOT(gotoAddBookPage(int))); + connect(setdialogPage,SIGNAL(openAddBookPagewidget(int)),this,SLOT(gotoAddBookPage(int))); + connect(setdialogPage,SIGNAL(openPasswordSetwidget(int)),this,SLOT(gotoPasswordSetwidgetPage(int))); + connect(this,SIGNAL(openadd()),this,SLOT(openAddBookPage())); + connect(sendCoinsPage, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int))); + connect(receiveCoinsPage,SIGNAL(gotoSetDialogExportPage()),this,SLOT(gotoSetDialogExportPage())); +} + +WalletView::~WalletView() +{ +} + +void WalletView::openAddBookPage() +{ + gotoAddBookPage(5); +} +void WalletView::gotoAddBookPage(int tag) +{ + AddressTableModel *atm = walletModel->getAddressTableModel(); + if(tag == 5){ + if(!AddBookPage_setdialog){ + AddBookPage_setdialog = new AddBookWidget(this); + connect(AddBookPage_setdialog,SIGNAL(backSend()),this,SLOT(gotoWalletViewPagekepinfo())); + AddBookPage_setdialog->settag(5); + // AddBookPage_setdialog->setModel(atm); + + } + AddBookPage_setdialog->setModel(atm); + setdialogPage->setAddpageshow(AddBookPage_setdialog); + } + else if(tag ==2){ + if(!AddBookPage_walletview){ + AddBookPage_walletview = new AddBookWidget(this); + connect(AddBookPage_walletview,SIGNAL(backSend()),this,SLOT(gotoWalletViewPagekepinfo())); + connect(AddBookPage_walletview,SIGNAL(selectaddressyes(QString,QString)),this,SLOT(gotoWalletViewPaga(QString,QString))); + AddBookPage_walletview->settag(2); + addWidget(AddBookPage_walletview); + } + AddBookPage_walletview->setModel(atm); + setCurrentWidget(AddBookPage_walletview); + } + +} + + +void WalletView::gotoWalletViewPagekepinfo() +{ + setCurrentWidget(sendCoinsPage); +} +void WalletView::gotoWalletViewPage() +{ + sendCoinsPage->clearInfo(); + setCurrentWidget(sendCoinsPage); +} + +void WalletView::gotoWalletViewPaga(QString a,QString b) +{ + /* if(5 == AddBookPage->gettag()) + { + return; + }*/ + gotoSendCoinsPage(a,b); + +} +void WalletView::gotoPasswordSetwidgetPage(int tag) +{ + bool was_locked = this->walletModel->CheckIsCrypted(); + PasswordSettingWidget::Mode status ; + if(was_locked) + { + status = PasswordSettingWidget::ChangePass; + } + else + { + status =PasswordSettingWidget::Encrypt; + } + if(!PasswordSettingPage) + { + PasswordSettingPage = new PasswordSettingWidget(status,this); + connect(PasswordSettingPage,SIGNAL(back()),this,SLOT(gotoWalletViewPage())); + connect(PasswordSettingPage,SIGNAL(openSendCoinsAffrimwidget()),this,SLOT(gotoSendCoinsAffrimPage())); + connect(PasswordSettingPage,SIGNAL(ChangePasswordSuccess()),this,SLOT(gotoPsdSetSuccessPage())); + } + if(PasswordSettingPage) + { + PasswordSettingPage->setMode(status); + PasswordSettingPage->setModel(this->walletModel); + this->gotopsdsetpage(PasswordSettingPage,tag); + } +} + + +void WalletView::gotoSendaffrimPage(QString a,QString b,QString label,int c) +{ + bool was_locked = this->walletModel->getEncryptionStatus() == WalletModel::Locked; + + SendCoinsAffrimPage = new SendCoinsAffrimWidget(was_locked,this); + SendCoinsAffrimPage->setModel(this->walletModel); + SendCoinsAffrimPage->setClientModel(this->clientModel); + connect(SendCoinsAffrimPage,SIGNAL(back()),this,SLOT(gotoWalletViewPage())); + connect(SendCoinsAffrimPage,SIGNAL(goresultpage()),this,SLOT(gotoResultPage()),Qt::DirectConnection); + connect(SendCoinsAffrimPage,SIGNAL(gobacktosendpage()),this,SLOT(backtoSendCoinsPage())); + + addWidget(SendCoinsAffrimPage); + setCurrentWidget(SendCoinsAffrimPage); + QString add = a; + QString coin = b; + int tag = c; + SendCoinsAffrimPage->setMessage(add,coin,label,tag); + +} +void WalletView::gotoSendCoinsAffrimPage() +{ + bool was_locked = this->walletModel->getEncryptionStatus() == WalletModel::Locked; + + SendCoinsAffrimPage = new SendCoinsAffrimWidget(was_locked,this); + SendCoinsAffrimPage->setModel(this->walletModel); + SendCoinsAffrimPage->setClientModel(this->clientModel); + connect(SendCoinsAffrimPage,SIGNAL(back()),this,SLOT(gotoWalletViewPage())); + connect(SendCoinsAffrimPage,SIGNAL(goresultpage()),this,SLOT(gotoResultPage()),Qt::DirectConnection); + connect(SendCoinsAffrimPage,SIGNAL(gobacktosendpage()),this,SLOT(backtoSendCoinsPage())); + + addWidget(SendCoinsAffrimPage); + setCurrentWidget(SendCoinsAffrimPage); + QString a = sendinfo_.Add_; + QString b = sendinfo_.Coin_; + QString label = sendinfo_.Label_; + int c = sendinfo_.Status_; + SendCoinsAffrimPage->setMessage(a,b,label,c); + +} +void WalletView::gotoPsdSetSuccessPage() +{ + setdialogPage->setPsdSetSuccess(); +} +void WalletView::gotoSettingPage(QString a,QString b,QString label,int tag) +{ + SendInfo T; + T.Add_ = a; + T.Coin_ = b, + T.Label_ = label; + T.Status_ = tag; + setvalue(T); + setCurrentWidget(settingwidgetPage); +} + +void WalletView::setvalue(SendInfo a) +{ + sendinfo_.Coin_ = a.Coin_; + sendinfo_.Add_ = a.Add_; + sendinfo_.Label_ = a.Label_; + sendinfo_.Status_ = a.Status_; +} +SendInfo WalletView::getvalue() +{ + return sendinfo_; +} + +void WalletView::setBitcoinGUI(BitcoinGUI *gui) +{ + + + if (gui) + { + connect(this, SIGNAL(message(QString,QString,unsigned int)), gui, SLOT(message(QString,QString,unsigned int))); + connect(this, SIGNAL(encryptionStatusChanged(int)), gui, SLOT(setEncryptionStatus(int))); + connect(this, SIGNAL(hdEnabledStatusChanged(int)), gui, SLOT(setHDStatus(int))); + } +} + +void WalletView::setClientModel(ClientModel *_clientModel) +{ + this->clientModel = _clientModel; + overviewPage->setClientModel(_clientModel); + sendCoinsPage->setClientModel(_clientModel); +} + +void WalletView::setWalletModel(WalletModel *_walletModel) +{ + this->walletModel = _walletModel; + + overviewPage->setWalletModel(_walletModel); + receiveCoinsPage->setModel(_walletModel); + sendCoinsPage->setModel(_walletModel); + ipcdialogPage->setModel(_walletModel); + setdialogPage->setModel(_walletModel); + pTallySelectAddressPage->setWalletModel(_walletModel); + pTallyApply->setModel(_walletModel); + pTallyOutAccount->setModel(_walletModel); + ecoinDialogPage->setModel(_walletModel); + pTallyAccount->setModel(_walletModel); + + + unionaccountPage->setModel(_walletModel); + + + if (_walletModel) + { + // Receive and pass through messages from wallet model + connect(_walletModel, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int))); + + // Handle changes in encryption status + connect(_walletModel, SIGNAL(encryptionStatusChanged(int)), this, SIGNAL(encryptionStatusChanged(int))); + updateEncryptionStatus(); + + // update HD status + Q_EMIT hdEnabledStatusChanged(_walletModel->hdEnabled()); + + // Balloon pop-up for new transaction + connect(_walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)), + this, SLOT(processNewTransaction(QModelIndex,int,int))); + + // Ask for passphrase if needed + connect(_walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet())); + // Show progress dialog + connect(_walletModel, SIGNAL(showProgress(QString,int)), this, SLOT(showProgress(QString,int))); + } +} + +void WalletView::processNewTransaction(const QModelIndex& parent, int start, int /*end*/) +{ + // Prevent balloon-spam when initial block download is in progress + if (!walletModel || !clientModel || clientModel->inInitialBlockDownload()) + return; + + TransactionTableModel *ttm = walletModel->getTransactionTableModel(); + if (!ttm || ttm->processingQueuedTransactions()) + return; + + QString date = ttm->index(start, TransactionTableModel::Date, parent).data().toString(); + qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent).data(Qt::EditRole).toULongLong(); + QString type = ttm->index(start, TransactionTableModel::Type, parent).data().toString(); + QModelIndex index = ttm->index(start, 0, parent); + QString address = ttm->data(index, TransactionTableModel::AddressRole).toString(); + QString label = ttm->data(index, TransactionTableModel::LabelRole).toString(); + + QString ipctitle = ttm->index(start,TransactionTableModel::IPCTitle,parent).data().toString(); + QString ipctype = ttm->index(start,TransactionTableModel::IPCType,parent).data().toString(); + +} + + +void WalletView::opensendpage(sendhistory *sendpage) +{ + overviewPage->addsendpage(sendpage); +} + + +void WalletView::openrecvpage(RecvHistory *recvpage) +{ + overviewPage->addrecv(recvpage); +} +void WalletView::opensendipcpage(sendipchistory *sendipcpage) +{ + overviewPage->addsendipcpage(sendipcpage); +} +void WalletView::setVerticalLayout2AddWidget(QWidget *page) +{ + overviewPage->setVerticalLayout2AddWidget(page); +} + +void WalletView::openrecvipcpage(recvipchistory *recvipcpage) +{ + overviewPage->addrecvipcpage(recvipcpage); +} + + +void WalletView::opensendtokenpage(SendTokenHistory *sendTokenPage) +{ + overviewPage->addsendtokenpage(sendTokenPage); +} +void WalletView::openrecvtokenpage(RecvTokenHistory *recvTokenPage) +{ + overviewPage->addrecvtokenpage(recvTokenPage); +} + +void WalletView::gotoOverviewPage() +{ + setCurrentWidget(overviewPage); +} + + +void WalletView::gotoReceiveCoinsPage() +{ + setCurrentWidget(receiveCoinsPage); +} + +void WalletView::gotopsdsetpage(PasswordSettingWidget *PasswordSettingPage,int tag) +{ + if(5==tag) + { + PasswordSettingPage->setTag(5); + setdialogPage->setPsdshow(PasswordSettingPage); + } + else + { + PasswordSettingPage->setTag(2); + if(this->indexOf(PasswordSettingPage)==-1) + addWidget(PasswordSettingPage); + setCurrentWidget(PasswordSettingPage); + + } +} +void WalletView::gotoResultPage() +{ + sendresultpage =new SendResultWidget(this); + addWidget(sendresultpage); + connect(sendresultpage,SIGNAL(backmain()),this,SLOT(gotoWalletViewPage())); + + setCurrentWidget(sendresultpage); + +} + +void WalletView::gotoIpcPage() +{ + ipcdialogPage->updatalist(); + setCurrentWidget(ipcdialogPage); +} +void WalletView::gotoUnionAccountPage() +{ + setCurrentWidget(unionaccountPage); + +} +void WalletView::gotoSetPage() +{ + setCurrentWidget(setdialogPage); + + Q_EMIT openadd(); +} +void WalletView::gotoSetDialogExportPage() +{ + setdialogPage->on_pushButton_export_pressed(); + setCurrentWidget(setdialogPage); +} + +void WalletView::gotoTallyPage() +{ + + try{ + if(!CDpocInfo::Instance().IsHasLocalAccount()) + { + LOG_WRITE(LOG_INFO,"CDpocInfo::Instance().IsHasLocalAccount false "); + if(tallyDialogPageStack&&pTallyDscribe) + tallyDialogPageStack->setCurrentWidget(pTallyDscribe); + } + else + { + LOG_WRITE(LOG_INFO,"CDpocInfo::Instance().IsHasLocalAccount true "); + pTallyAccount->resettime(); + if(tallyDialogPageStack&&pTallyAccount) + { + pTallyAccount->SetnewInfo(); + tallyDialogPageStack->setCurrentWidget(pTallyAccount); + + } + } + if(tallyDialogPage) + setCurrentWidget(tallyDialogPage); + } + catch(...){ + LOG_WRITE(LOG_INFO,"WalletView::gotoTallyPage() try Error!"); + } + LOG_WRITE(LOG_INFO,"WalletView::gotoTallyPage finish!"); +} +void WalletView::gotoeCoinPage(){ + ecoinDialogPage->updatalist(); + setCurrentWidget(ecoinDialogPage); + +} + +void WalletView::backtoSendCoinsPage() +{ + setCurrentWidget(sendCoinsPage); +} +void WalletView::gotoSendCoinsPage(QString addr,QString label) +{ + + setCurrentWidget(sendCoinsPage); + + if (!addr.isEmpty()) + { + sendCoinsPage->setAddress(addr,label); + } + else + { + sendCoinsPage->clearInfo(); + } +} + + +void WalletView::updateEncryptionStatus() +{ + Q_EMIT encryptionStatusChanged(walletModel->getEncryptionStatus()); +} + +void WalletView::encryptWallet(bool status) +{ + if(!walletModel) + return; + + + updateEncryptionStatus(); +} + +void WalletView::backupWallet() +{ + QString filename = GUIUtil::getSaveFileName(this, + tr("Backup Wallet"), QString(), + tr("Wallet Data (*.dat)"), NULL); + + if (filename.isEmpty()) + return; + + if (!walletModel->backupWallet(filename)) { + Q_EMIT message(tr("Backup Failed"), tr("There was an error trying to save the wallet data to %1.").arg(filename), + CClientUIInterface::MSG_ERROR); + } + else { + Q_EMIT message(tr("Backup Successful"), tr("The wallet data was successfully saved to %1.").arg(filename), + CClientUIInterface::MSG_INFORMATION); + } +} + + + +void WalletView::unlockWallet() +{ + if(!walletModel) + return; + // Unlock wallet when requested by wallet model + if (walletModel->getEncryptionStatus() == WalletModel::Locked) + { + SecureString oldpass; + //oldpass.assign("1"); + oldpass = pwalletMain->curstrWalletPassphrase; + + if(!walletModel->setWalletLocked(false, oldpass)) + { + QMessageBox::critical(this, tr("Wallet unlock failed"), + tr("The passphrase entered for the wallet decryption was incorrect.")); + } + else + { + // QDialog::accept(); // Success + } + } +} + + +void WalletView::showProgress(const QString &title, int nProgress) +{ + if (nProgress == 0) + { + progressDialog = new QProgressDialog(title, "", 0, 100); + progressDialog->setWindowModality(Qt::ApplicationModal); + progressDialog->setMinimumDuration(0); + progressDialog->setCancelButton(0); + progressDialog->setAutoClose(false); + progressDialog->setValue(0); + Qt::WindowFlags flags=Qt::Dialog; + flags |=Qt::WindowCloseButtonHint; + progressDialog->setWindowFlags(flags); + } + else if (nProgress == 100) + { + if (progressDialog) + { + progressDialog->close(); + progressDialog->deleteLater(); + } + } + else if (progressDialog) + progressDialog->setValue(nProgress); +} + +void WalletView::requestedSyncWarningInfo() +{ + Q_EMIT outOfSyncWarningClicked(); +} +void WalletView::gotoClausePage() +{ + tallyDialogPageStack->setCurrentWidget(pTallyClause); +} +void WalletView::gotoDscribePage() +{ + tallyDialogPageStack->setCurrentWidget(pTallyDscribe); +} + +void WalletView::gotoTallyApplyPage(QString address) +{ + pTallyApply->resetinfo(); + if(!address.isEmpty()){ + pTallyApply->setAddress(address); + } + tallyDialogPageStack->setCurrentWidget(pTallyApply); +} +void WalletView::gotoTallyAccountPage(QString add,CAmount num) +{ + tallyDialogPageStack->setCurrentWidget(pTallyAccount); + WalletModel::keepupaccountInfo info; + info.Add_ =add; + info.Coin_ = num; + + pTallyAccount->setinfo(info); +} +void WalletView::setIsTallying(bool IsTally) +{ + m_IsTallying= IsTally; +} +bool WalletView::getIsTallying() +{ + return m_IsTallying; +} +void WalletView::gotoTallyOutAccountPage(QString add,CAmount num) +{ + tallyDialogPageStack->setCurrentWidget(pTallyOutAccount); + WalletModel::keepupaccountInfo accinfo; + accinfo.Add_ =add; + accinfo.Coin_ = num; + pTallyOutAccount->setinfo(accinfo); +} +void WalletView::gotoBackTallyAccountPage(bool isok) +{ + if(isok) + pTallyAccount->setfinishinfo(); + tallyDialogPageStack->setCurrentWidget(pTallyAccount); +} +void WalletView::gotoTallyAddressPage() +{ + tallyDialogPageStack->setCurrentWidget(pTallySelectAddressPage); +} diff --git a/.svn/pristine/6b/6bab445d07f30e840930fe40ce718c383e0b66d1.svn-base b/.svn/pristine/6b/6bab445d07f30e840930fe40ce718c383e0b66d1.svn-base new file mode 100644 index 0000000..fc2c6ed --- /dev/null +++ b/.svn/pristine/6b/6bab445d07f30e840930fe40ce718c383e0b66d1.svn-base @@ -0,0 +1,373 @@ + + + ipcconfirmtransfertransaction + + + + 0 + 0 + 551 + 593 + + + + Form + + + + 0 + + + 40 + + + 0 + + + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + background-image: url(:/res/png/back.png);border:none + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 0 + 100 + + + + + 16777215 + 100 + + + + + 0 + + + 0 + + + 0 + + + + + color: rgb(51, 51, 51);font-size : 28px; + + + Transfer confirmation + + + + + + + Qt::Horizontal + + + + 359 + 20 + + + + + + + + + + + + 0 + 48 + + + + + 16777215 + 16777215 + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + IPCname + + + + + + + + 0 + 0 + + + + + 0 + 48 + + + + + 16777215 + 16777215 + + + + font-size : 14px; +color: rgb(51, 51, 51); + + + TextLabel + + + true + + + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + Address + + + + + + + font-size : 14px; +color: rgb(51, 51, 51); + + + TextLabel + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Qt::Horizontal + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 417 + 20 + + + + + + + + + + + Qt::Vertical + + + + 20 + 75 + + + + + + + + + + + Qt::Horizontal + + + + 207 + 20 + + + + + + + + + 421 + 50 + + + + + 421 + 50 + + + + border:none; +color: rgb(255, 255, 255); +background-image: url(:/res/png/buttons/421_50.png); + + + Confirm transaction + + + + + + + Qt::Horizontal + + + + 206 + 20 + + + + + + + + + + + Qt::Vertical + + + + 20 + 74 + + + + + + + + + diff --git a/.svn/pristine/6d/6d2b206881bd882510454460502ba47b38a38a38.svn-base b/.svn/pristine/6d/6d2b206881bd882510454460502ba47b38a38a38.svn-base new file mode 100644 index 0000000..2ee3508 --- /dev/null +++ b/.svn/pristine/6d/6d2b206881bd882510454460502ba47b38a38a38.svn-base @@ -0,0 +1,140 @@ +#include "unionaccountjoin.h" +#include "ui_unionaccountjoin.h" +#include "log/log.h" +#include +#include +#ifdef ENABLE_WALLET +#include "walletmodel.h" +#endif +unionaccountjoin::unionaccountjoin(QWidget *parent) : + QWidget(parent), + ui(new Ui::unionaccountjoin) +{ + ui->setupUi(this); + QRegExp regx("^\\S+$"); + QValidator *validator = new QRegExpValidator(regx, ui->lineEdit_name ); + ui->lineEdit_name->setValidator( validator ); +} + +unionaccountjoin::~unionaccountjoin() +{ + delete ui; +} +void unionaccountjoin::setModel(WalletModel *_model) +{ + this->model = _model; +} +void unionaccountjoin::on_joinBtn_pressed() +{ + if(ui->lineEdit_name->text() == "" || ui->textEdit_add->document()->toPlainText().toStdString() == "") + { + ui->label_err->setText(tr("input info")); + return; + } + std::string m_failreason; + if(model->joinunionaccount(ui->lineEdit_name->text().toStdString(),m_failreason,ui->textEdit_add->document()->toPlainText().toStdString())) + { + ui->label_err->setText(tr("Join success. For your asset safety, please backup your wallet again!")); + Q_EMIT refreshunionaccount(); + // Q_EMIT opensuccessjoinPage(); + } + else + { + if("script is not p2sh script!" ==m_failreason ) + { + ui->label_err->setText(tr("script is not p2sh script!")); + } + else if("AddMultiAddress failed!" ==m_failreason) + { + ui->label_err->setText(tr("AddMultiAddress failed!")); + } + else if("MultiAdd is not yours" == m_failreason) + { + ui->label_err->setText(tr("MultiAdd is not yours")); + } + else if("Address duplication!" == m_failreason) + { + ui->label_err->setText(tr("Address duplication!")); + } + else if("Password error."== m_failreason) + { + ui->label_err->setText(tr("Password error.")); + } + else + { + LOG_WRITE(LOG_INFO,"JOIN FAIL",m_failreason.c_str()); + ui->label_err->setText(tr("join error")); + } + } +} +void unionaccountjoin::showEvent(QShowEvent *event) +{ + ui->lineEdit_name->setText(""); + ui->textEdit_add->clear(); + ui->label_err->setText(""); + +} + + +void unionaccountjoin::on_btn_import_pressed() +{ + ui->textEdit_add->clear(); + ui->label_err->setText(""); + QString path = QFileDialog::getOpenFileName(this,tr("Open File"),".",tr("Text Files(*.txt)")); + + if(!path.isEmpty()) { + + QFile file(path); + + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + + // QMessageBox::warning(this, tr("Read File"),tr("Cannot open file:\n%1").arg(path)); + LOG_WRITE(LOG_INFO,"file open fail"); + return; + + } + + QTextStream in(&file); + + + QString str = in.readAll(); + int pos1 ; + + QLocale locale; + QString timestr; + if( locale.language() == QLocale::Chinese ) + { + pos1 = str.indexOf("邀请ç :") ; + }else{ + pos1 = str.indexOf("script:"); + } + + if(-1 == pos1) + { + ui->label_err->setText(tr("Please reselect the file")); + } + else + { + + QString m_str; + if( locale.language() == QLocale::Chinese ) + { + m_str =str.mid(pos1+5 ,-1); + }else{ + m_str =str.mid(pos1+7 ,-1); + } + + + + m_str.replace(" ", ""); + ui->textEdit_add->setText(m_str); + } + file.close(); + + } else { + + // QMessageBox::warning(this, tr("Path"),tr("You did not select any file.")); + + } + +} diff --git a/.svn/pristine/71/7162a54a1f15ebb214826b3c839b1373b52b125e.svn-base b/.svn/pristine/71/7162a54a1f15ebb214826b3c839b1373b52b125e.svn-base new file mode 100644 index 0000000..cff4a8c --- /dev/null +++ b/.svn/pristine/71/7162a54a1f15ebb214826b3c839b1373b52b125e.svn-base @@ -0,0 +1,554 @@ +// Copyright (c) 2011-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "overviewpage.h" +#include "ui_overviewpage.h" +#include "ipchainunits.h" +#include "clientmodel.h" +#include "guiconstants.h" +#include "guiutil.h" +#include "optionsmodel.h" +#include "platformstyle.h" +#include "transactionfilterproxy.h" +#include "transactiontablemodel.h" +#include "walletmodel.h" +#include "transactionview.h" +#include "transactionrecord.h" +#include "infowidget.h" +#include "sendhistory.h" +#include "recvhistory.h" +#include "sendipchistory.h" +#include "recvipchistory.h" +#include "sendtokenhistory.h" +#include "recvtokenhistory.h" +#include +#include +#include +#include +#include +#include "log/log.h" +#include +#define DECORATION_SIZE 54 +#define NUM_ITEMS 4//5 + +QModelIndex selectindex_ ; +CAmount _balance =0 ; +class TxViewDelegate : public QAbstractItemDelegate +{ + Q_OBJECT +public: + TxViewDelegate(const PlatformStyle *_platformStyle, QObject *parent=nullptr): + QAbstractItemDelegate(parent), unit(BitcoinUnits::IPC), + platformStyle(_platformStyle) + { + } + inline void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index ) const + { + painter->save(); + QIcon icon = qvariant_cast(index.data(TransactionTableModel::RawDecorationRole)); + int type = index.data(TransactionTableModel::TypeRole).toInt(); + QString date = index.data(TransactionTableModel::DateRole).toString();//.toDateTime(); + bool involvesWatchAddress = index.data(TransactionTableModel::WatchonlyRole).toBool(); + QString address = index.data(TransactionTableModel::AddressRole).toString(); + QString labelr = index.data(TransactionTableModel::LabelRole).toString(); + qint64 amount = index.data(TransactionTableModel::AmountRole).toLongLong(); + QString amountText = BitcoinUnits::formatWithUnit4(0, amount, true, BitcoinUnits::separatorAlways); + if("0.0000 IPC"==amountText || "+0.0000 IPC"==amountText||"-0.0000 IPC"==amountText) + { + amountText = BitcoinUnits::formatWithUnit(0, amount, true, BitcoinUnits::separatorAlways); + } + bool confirmed = index.data(TransactionTableModel::IsConfirmedRole).toBool(); + int status = index.data(TransactionTableModel::StatusRole).toInt(); + int watchOnlyFilter =index.data(TransactionFilterProxy::WatchOnlyFilter_No).toInt(); + int watchOnlyFilter1 =index.data(TransactionFilterProxy::WatchOnlyFilter_Yes).toInt(); + QString name=index.data(TransactionTableModel::IPCTitle).toString(); + QString ecoinname=index.data(TransactionTableModel::eCoinType).toString(); + QString ecoinnum = index.data(TransactionTableModel::eCoinNum).toString(); + QString label; + int xspace = DECORATION_SIZE + 8; + int ypad = 6; + QRect mainRect = option.rect; + QRect decorationRect(mainRect.left()+7,mainRect.top()+25, 41, 41); + int halfheight = (mainRect.height() - 2*ypad)/2; + QRect amountRect(mainRect.left()+ xspace*0.7, mainRect.top()-ypad+halfheight/2, mainRect.width() - xspace, halfheight); + QRect addressRect(mainRect.left() + xspace*0.7, mainRect.top()+ypad+halfheight*4/5, mainRect.width() - xspace, halfheight); + QRect labelRect(mainRect.left() -xspace*1.7, mainRect.top()+ypad+halfheight/3, mainRect.width() - xspace, halfheight); + QRect checkRect(mainRect.right() -8, mainRect.top()+ypad, 9,71); + QIcon icon1,icon2; + + if( TransactionRecord::Other == type || TransactionRecord::SendToAddress== type || TransactionRecord::SendToOther== type ) + { + if(!confirmed) + { + label =tr("IsSended"); + icon1 = QIcon(":/res/png/coinsend.png"); + } + else + { + label =tr("IsSended"); + icon1 = QIcon(":/res/png/coinsend.png"); + } + } + else if( TransactionRecord::SendToSelf == type || TransactionRecord::Senddeposit == type) + { + label =tr("IsSended"); + icon1 = QIcon(":/res/png/coinsend.png"); + } + else if (TransactionRecord::SendeCoin == type || TransactionRecord::SendeCointoself == type) + { + label =tr("IsSended"); + icon1 = QIcon(":/res/png/ecoinsend.png"); + } + else if (TransactionRecord::SendCoin == type ) + { + label =tr("IsSended"); + icon1 = QIcon(":/res/png/coinsend.png"); + } + else if (TransactionRecord::RecveCoin == type) + { + label = tr("IsRecved"); + icon1 = QIcon(":/res/png/ecoinrecv.png"); + } + else if(TransactionRecord::SendIPC == type) + { + if(!confirmed) + { + label =tr("IsSended"); + icon1 = QIcon(":/res/png/ipcsend.png"); + } + else + { + label = tr("IsSended"); + icon1 = QIcon(":/res/png/ipcsend.png"); + } + } + else if(TransactionRecord::RecvIPC == type) + { + if(!confirmed) + { + label = tr("IsRecved"); + icon1 = QIcon(":/res/png/ipcrecv.png"); + } + else + { + label = tr("IsRecved"); + icon1 = QIcon(":/res/png/ipcrecv.png"); + } + } + else if (TransactionRecord::Sendbookkeep == type) + { + label = tr("IsSended"); + icon1 = QIcon(":/res/png/coinsend.png"); + } + else if (TransactionRecord::Recvbookkeep == type) + { + label = tr("IsRecved"); + icon1 = QIcon(":/res/png/coinsend.png"); + } + else if(TransactionRecord::RecveCoin == type ) + { + if(!confirmed) + { + label = tr("IsRecved"); + icon1 = QIcon(":/res/png/coinrecv.png"); + } + else + { + label = tr("IsRecved"); + icon1 = QIcon(":/res/png/coinrecv.png"); + } + } + else if( TransactionRecord::Generated||TransactionRecord::Recvbookkeep == type ||TransactionRecord::RecvCoin == type ||TransactionRecord::RecvFromOther == type || TransactionRecord::RecvWithAddress ==type || TransactionRecord::Recvdeposit == type) + { + if(!confirmed) + { + label = tr("IsRecved"); + icon1 = QIcon(":/res/png/coinrecv.png"); + } + else + { + label = tr("IsRecved"); + icon1 = QIcon(":/res/png/coinrecv.png"); + } + } + icon1.paint(painter, mainRect); + icon.paint(painter, decorationRect); + QSpacerItem* horizontalSpacer = new QSpacerItem(40,20,QSizePolicy::Expanding); + QStyleOptionViewItem itemOption(option); + + if (itemOption.state & QStyle::State_HasFocus && selectindex_ == index) + { + icon2 =QIcon(":/res/png/triangle.png"); + icon2.paint(painter, checkRect); + } + QVariant value = index.data(Qt::ForegroundRole); + QColor foreground = option.palette.color(QPalette::Text); + if(value.canConvert()) + { + QBrush brush = qvariant_cast(value); + foreground = brush.color(); + } + painter->setPen(QColor(255, 255,255)); + QRect boundingRect; + + if(amount < 0) + { + foreground = COLOR_NEGATIVE; + } + else if(!confirmed) + { + foreground = COLOR_UNCONFIRMED; + } + else + { + foreground = option.palette.color(QPalette::Text); + } + painter->setPen(QColor(255, 255,255)); + if(TransactionRecord::RecvIPC == type || TransactionRecord::SendIPC == type) + { + if(!confirmed) + { + painter->setPen(QColor(255, 0,0)); + } + else + { + painter->setPen(QColor(255, 255,255)); + } + std::string tempname = name.toStdString(); + if(name.size()>12 && tempname.length()>12*3){ + QString nametemp = name.mid(0,12); + nametemp+="..."; + name = nametemp; + } + painter->drawText(amountRect, Qt::AlignRight|Qt::AlignTop, name); + } + else if(TransactionRecord::RecveCoin == type ) + { + if(!confirmed) + { + painter->setPen(QColor(255,0,0)); + } + else + { + painter->setPen(QColor(255, 255,255)); + } + + QString nameeCoin ="+"+ecoinnum+" "+ecoinname; + std::string tempname = nameeCoin.toStdString(); + if(nameeCoin.size()>12 && tempname.length()>12*3){ + QString nametemp = nameeCoin.mid(0,12); + nametemp+="..."; + nameeCoin = nametemp; + } + painter->drawText(amountRect, Qt::AlignRight|Qt::AlignTop,nameeCoin); + } + else if(TransactionRecord::SendeCoin == type) + { + if(!confirmed) + { + painter->setPen(QColor(255,0,0)); + } + else + { + painter->setPen(QColor(255, 255,255)); + } + + QString nameeCoin ="-"+ecoinnum+" "+ecoinname; + std::string tempname = nameeCoin.toStdString(); + if(nameeCoin.size()>12 && tempname.length()>12*3){ + QString nametemp = nameeCoin.mid(0,12); + nametemp+="..."; + nameeCoin = nametemp; + } + painter->drawText(amountRect, Qt::AlignRight|Qt::AlignTop, nameeCoin); + } + else{ + if(!confirmed) + { + painter->setPen(QColor(255,0,0)); + } + else + { + painter->setPen(QColor(255, 255,255)); + } + painter->drawText(amountRect, Qt::AlignRight|Qt::AlignTop, amountText); + } + painter->setPen(option.palette.color(QPalette::Text)); + painter->setPen(QColor(255, 255,255)); + painter->drawText(addressRect, Qt::AlignRight|Qt::AlignBottom, date); + + QFont font; + font.setPixelSize(16); + painter->setFont(font); + painter->setPen(QColor(255, 255,255)); + painter->drawText(labelRect, Qt::AlignRight|Qt::AlignBottom, label); + painter->restore(); + } + inline QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const + { + return QSize(90, 90); + } + int unit; + bool isselected; + const PlatformStyle *platformStyle; +}; + +#include "overviewpage.moc" + +OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent) : + QWidget(parent), + ui(new Ui::overviewpage), + clientModel(0), + walletModel(0), + currentBalance(-1), + currentUnconfirmedBalance(-1), + currentImmatureBalance(-1), + currentWatchOnlyBalance(-1), + currentWatchUnconfBalance(-1), + currentWatchImmatureBalance(-1), + //wWidget(NULL), + txdelegate(new TxViewDelegate(platformStyle, this)) +{ + ui->setupUi(this); + // use a SingleColorIcon for the "out of sync warning" icon + QIcon icon = platformStyle->SingleColorIcon(":/icons/warning"); + icon.addPixmap(icon.pixmap(QSize(64,64), QIcon::Normal), QIcon::Disabled); // also set the disabled icon because we are using a disabled QPushButton to work around missing HiDPI support of QLabel (https://bugreports.qt.io/browse/QTBUG-42503) + ui->listTransactions->setEditTriggers(QAbstractItemView::AnyKeyPressed + | QAbstractItemView::DoubleClicked); + ui->listTransactions->setAutoScroll(true); + ui->listTransactions->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + ui->listTransactions->setSpacing(3); + ui->listTransactions->setItemDelegate(txdelegate); + ui->listTransactions->setIconSize(QSize(DECORATION_SIZE, DECORATION_SIZE)); + ui->listTransactions->setAttribute(Qt::WA_MacShowFocusRect, false); + singleton1 = InfoWidget::GetInstance(); + //ui->verticalLayout_2->addWidget(singleton1); + ui->stackedWidget->addWidget(singleton1); + //wWidget = singleton1; + singleton1->setuserRequest(true); + singleton1->showHide(false); + ui->showdetailButton->hide(); + ui->stackedWidget->setCurrentWidget(singleton1); +} + +void OverviewPage::chooseDate(int idx) +{ + if(!this->walletModel->getTransactionTableModel()) + return; + QDate current = QDate::currentDate(); +} + +void OverviewPage::handleOutOfSyncWarningClicks() +{ + Q_EMIT outOfSyncWarningClicked(); +} + +OverviewPage::~OverviewPage() +{ + delete ui; +} + +void OverviewPage::setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance, const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance, const CAmount& depositBalance) +{ + int unit = walletModel->getOptionsModel()->getDisplayUnit(); + unit = 0; + _balance = balance; + currentBalance = balance; + currentUnconfirmedBalance = unconfirmedBalance; + currentImmatureBalance = immatureBalance; + currentWatchOnlyBalance = watchOnlyBalance; + currentWatchUnconfBalance = watchUnconfBalance; + currentWatchImmatureBalance = watchImmatureBalance; + currentdepositBalance = depositBalance; + + QString a = BitcoinUnits::formatWithUnit2(unit, depositBalance, false, BitcoinUnits::separatorNever); + QString b; + QString c; + + if(depositBalance > 0) + { + ui->labeldetain->setVisible(true); + ui->labeldetainvalue->setVisible(true); + ui->labeldetainvalue->setText(BitcoinUnits::formatWithUnit2(unit, depositBalance, false, BitcoinUnits::separatorAlways)); + ui->labelBalance->setText(BitcoinUnits::formatWithUnit2(unit, balance, false, BitcoinUnits::separatorAlways)); + ui->labelImmature->setText(BitcoinUnits::formatWithUnit2(unit, immatureBalance + unconfirmedBalance, false, BitcoinUnits::separatorAlways)); + b = BitcoinUnits::formatWithUnit2(unit, balance, false, BitcoinUnits::separatorNever); + c = BitcoinUnits::formatWithUnit2(unit, immatureBalance + unconfirmedBalance, false, BitcoinUnits::separatorNever); + } + else + { + ui->labeldetain->setVisible(false); + ui->labeldetainvalue->setVisible(false); + ui->labelBalance->setText(BitcoinUnits::formatWithUnit2(unit, balance, false, BitcoinUnits::separatorAlways)); + ui->labelImmature->setText(BitcoinUnits::formatWithUnit2(unit, immatureBalance+unconfirmedBalance, false, BitcoinUnits::separatorAlways)); + b= BitcoinUnits::formatWithUnit2(unit, balance, false, BitcoinUnits::separatorNever); + c=BitcoinUnits::formatWithUnit2(unit, immatureBalance+unconfirmedBalance, false, BitcoinUnits::separatorNever); + } + double deposit = a.mid(0,a.length()-3).toDouble(); + double blance = b.mid(0,b.length()-3).toDouble(); + double immature = c.mid(0,c.length()-3).toDouble(); + double total = deposit+blance+immature; + char buf[100]={'\0'}; + sprintf(buf,"%.2lf",total); + std::string str(buf, sizeof(buf)); + ui->labelTotal->setText(QString::fromStdString(buf)+" IPC"); + bool showImmature = immatureBalance != 0; + bool showWatchOnlyImmature = watchImmatureBalance != 0; +} + + +void OverviewPage::setClientModel(ClientModel *model) +{ + this->clientModel = model; + if(singleton1) + singleton1->setClientModel(model); +} +void OverviewPage::setWalletModel(WalletModel *model) +{ + this->walletModel = model; + if(model && model->getOptionsModel() && model->getTransactionTableModel()) + { + singleton1->setWalletModel(this->walletModel); + filter.reset(); + filter.reset(new TransactionFilterProxy()); + filter->setSourceModel(model->getTransactionTableModel()); + filter->setDynamicSortFilter(true); + filter->setSortRole(Qt::EditRole); + filter->setShowInactive(false); + filter->setWatchOnlyFilter(TransactionFilterProxy::WatchOnlyFilter_No); + filter->sort(TransactionTableModel::Date, Qt::DescendingOrder); + ui->listTransactions->setModel(filter.get()); + ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress); + ui->listTransactions->setVerticalScrollMode(QAbstractItemView::ScrollPerItem); + setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance(), + model->getWatchBalance(), model->getWatchUnconfirmedBalance(), model->getWatchImmatureBalance(),model->GetDetained()); + connect(model, SIGNAL(balanceChanged(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)), this, SLOT(setBalance(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)),Qt::QueuedConnection); + + connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + } + updateDisplayUnit(); +} + + +void OverviewPage::updateDisplayUnit() +{ + if(walletModel && walletModel->getOptionsModel()) + { + if(currentBalance != -1) + { + setBalance(currentBalance, currentUnconfirmedBalance, currentImmatureBalance, + currentWatchOnlyBalance, currentWatchUnconfBalance, currentWatchImmatureBalance,currentdepositBalance); + } + // Update txdelegate->unit with the current unit + txdelegate->unit = walletModel->getOptionsModel()->getDisplayUnit(); + + ui->listTransactions->setEditTriggers(QAbstractItemView::AnyKeyPressed + | QAbstractItemView::DoubleClicked + |QAbstractItemView::EditKeyPressed ); + ui->listTransactions->edit(selectindex_); + ui->listTransactions->update(); + } +} +void OverviewPage::on_listTransactions_clicked(const QModelIndex &index) +{ + selectindex_ = index; + updatetime =0; + txdelegate->isselected = true; + + ui->listTransactions->update(); + if(filter) + typerole= index.data(TransactionTableModel::TypeRole).toInt(); + + int tag; + if(TransactionRecord::Type::SendIPC== typerole) + { + tag = 1; + } + else if(TransactionRecord::Type::RecvIPC== typerole) + { + tag = 2; + } + else if(TransactionRecord::Sendbookkeep == typerole ) + { + tag = 3; + } + else if(TransactionRecord::Recvbookkeep == typerole) + { + tag =4; + } + else if(TransactionRecord::SendeCointoself==typerole || TransactionRecord::SendeCoin==typerole) + { + tag = 5; + } + else if( TransactionRecord::RecveCoin== typerole) + { + tag = 6; + } + else if(TransactionRecord::SendCoin == typerole ||TransactionRecord::SendToAddress== typerole + || TransactionRecord::SendToOther== typerole || TransactionRecord::SendToSelf == typerole || TransactionRecord::Senddeposit == typerole) + { + tag = 7; + } + else if( TransactionRecord::Recvdeposit == typerole || TransactionRecord::RecvCoin == typerole || TransactionRecord::Generated == typerole|| TransactionRecord::Other == typerole) + { + tag = 8; + } + Q_EMIT transactionnnClicked(filter->mapToSource(index),tag); + +} +void OverviewPage::addinfo(InfoWidget *infopage){ + ui->stackedWidget->setCurrentWidget(infopage); + //infopage->showHide(false); +} +void OverviewPage::addsendpage(sendhistory *sendpage) +{ + ui->stackedWidget->setCurrentWidget(sendpage); + sendpage->showVisual(true); + ui->showdetailButton->show(); +} +void OverviewPage::addrecv(RecvHistory *recvpage) +{ + ui->stackedWidget->setCurrentWidget(recvpage); + recvpage->showVisual(true); + ui->showdetailButton->show(); +} +void OverviewPage::setVerticalLayout2AddWidget(QWidget* pwidget) +{ + ui->stackedWidget->addWidget(pwidget); +} + +void OverviewPage::addsendipcpage(sendipchistory *sendipcpage) +{ + ui->stackedWidget->setCurrentWidget(sendipcpage); + sendipcpage->showVisual(true); + ui->showdetailButton->show(); +} + +void OverviewPage::addsendtokenpage(SendTokenHistory *sendTokenPage) +{ + ui->stackedWidget->setCurrentWidget(sendTokenPage); + sendTokenPage->showVisual(true); + ui->showdetailButton->show(); +} +void OverviewPage::addrecvtokenpage(RecvTokenHistory *recvTokenPage) +{ + ui->stackedWidget->setCurrentWidget(recvTokenPage); + recvTokenPage->showVisual(true); + ui->showdetailButton->show(); +} + +void OverviewPage::addrecvipcpage(recvipchistory *recvipcpage) +{ + ui->stackedWidget->setCurrentWidget(recvipcpage); + recvipcpage->showVisual(true); + ui->showdetailButton->show(); +} +void OverviewPage::on_showdetailButton_pressed() +{ + QModelIndex index = this->walletModel->getTransactionTableModel()->index(-1,-1); + selectindex_ = index_; + ui->showdetailButton->hide(); + addinfo(singleton1); +} diff --git a/.svn/pristine/72/72d31112a1c94bb6738cea75829602875bff1d70.svn-base b/.svn/pristine/72/72d31112a1c94bb6738cea75829602875bff1d70.svn-base new file mode 100644 index 0000000..2efbbfa --- /dev/null +++ b/.svn/pristine/72/72d31112a1c94bb6738cea75829602875bff1d70.svn-base @@ -0,0 +1,540 @@ +#include "walletpagebuttons.h" +#include "forms/ui_walletpagebuttons.h" +#include +#include +#include "util.h" +#include +#include "intro.h" +#include "cmessagebox.h" +#include "ipchaingui.h" +#include "log/log.h" +#include +extern bool isfirstfullloaded ; +extern Gerxy Gerxy_; +extern int titleBarHeight; +QString walletpagebuttons::formatLang() +{ + QSettings settings; + // Get desired locale (e.g. "de_DE") + // 1) System default language + QString lang_territory = QLocale::system().name(); + // 2) Language from QSettings + QString lang_territory_qsettings = settings.value("language", "").toString(); + if(!lang_territory_qsettings.isEmpty()) + lang_territory = lang_territory_qsettings; + // 3) -lang command line argument + lang_territory = QString::fromStdString(GetArg("-lang", lang_territory.toStdString())); + // return lang_territory; + + + + QLocale locale; + if( locale.language() == QLocale::English ) + { + + return "English"; + } + else if( locale.language() == QLocale::Chinese ) + { + return "Chinese"; + } +} +walletpagebuttons::walletpagebuttons(QWidget *parent) : + QWidget(parent), + ui(new Ui::walletpagebuttons) +{ + ui->setupUi(this); + + QString m_lang =formatLang(); + + is_uniond = true; + + if(Intro::m_clienttype == "test") + { + if("Chinese"==m_lang) + { + ui->label->setPixmap(QPixmap(":/res/png/titlelogo_d.png")); + } + else + { + ui->label->setPixmap(QPixmap(":/res/png/titlelogo_en.png")); + } + ui->label->show(); + } + else + { + if("Chinese"==m_lang) + { + ui->label->setPixmap(QPixmap(":/res/png/titlelogo.png")); + } + else + { + ui->label->setPixmap(QPixmap(":/res/png/titlelogo_nen.png")); + } + + ui->label->show(); + } + + if(is_uniond) + { + ui->pushButton_wallet->setChecked(true); + connect(ui->pushButton_ipc,SIGNAL(pressed()),this,SLOT(getWalletPageButtonsStatus())); + connect(ui->pushButton_recive,SIGNAL(pressed()),this,SLOT(getWalletPageButtonsStatus())); + connect(ui->pushButton_send,SIGNAL(pressed()),this,SLOT(getWalletPageButtonsStatus())); + connect(ui->pushButton_set,SIGNAL(pressed()),this,SLOT(getWalletPageButtonsStatus())); + connect(ui->pushButton_wallet,SIGNAL(pressed()),this,SLOT(getWalletPageButtonsStatus())); + connect(ui->pushButton_markbill,SIGNAL(pressed()),this,SLOT(getWalletPageButtonsStatus())); + + connect(ui->pushButton_eipc,SIGNAL(pressed()),this,SLOT(getWalletPageButtonsStatus())); + + connect(ui->pushButton_unionaccount,SIGNAL(pressed()),this,SLOT(getWalletPageButtonsStatus())); + + + QString button_style= + "QPushButton{image:url(:/res/png/wallet.png);color: white; border: none}" + "QPushButton:pressed{image:url(:/res/png/wallet_d.png);color:black; }"; + ui->pushButton_wallet->setStyleSheet(button_style); + + + ui->pushButton_send->setStyleSheet("background-image:url(:/res/png/send.png);color: white;border:none;font-size:16px; "); + ui->pushButton_recive->setStyleSheet("background-image:url(:/res/png/recv.png);color: white;border:none;font-size:16px"); + ui->pushButton_ipc->setStyleSheet("background-image:url(:/res/png/ipc.png);color: white;border:none;font-size:16px;"); + ui->pushButton_eipc->setStyleSheet("background-image:url(:/res/png/eIPC.png);color: white;border:none;font-size:16px;"); + ui->pushButton_markbill->setStyleSheet("background-image:url(:/res/png/markbill.png);color: white;border:none;font-size:16px;"); + ui->pushButton_set->setStyleSheet("background-image:url(:/res/png/setting.png);color: white;border:none;font-size:16px;"); + + ui->pushButton_unionaccount->setStyleSheet("background-image:url(:/res/png/union.png);color: white;border:none;font-size:16px;"); + + setpushbuttonchecked("pushButton_wallet",ui->pushButton_wallet,"wallet.png","wallet_d.png"); + + ui->pushButton_wallet->setText(tr("\n\n\n")+tr("wallet")); + + ui->pushButton_send->setText(tr("\n\n\n")+tr("send")); + ui->pushButton_recive->setText(tr("\n\n\n")+tr("receive")); + ui->pushButton_ipc->setText(tr("\n\n\n")+tr("IP")); + ui->pushButton_eipc->setText(tr("\n\n\n")+tr("token")); + ui->pushButton_markbill->setText(tr("\n\n\n")+tr("markbill")); + ui->pushButton_set->setText(tr("\n\n\n")+tr("set")); + ui->pushButton_unionaccount->setText(tr("\n\n\n")+tr("union")); + + } + else + { + ui->pushButton_wallet->setVisible(false); + ui->pushButton_send->setChecked(true); + connect(ui->pushButton_ipc,SIGNAL(pressed()),this,SLOT(getWalletPageButtonsStatus())); + connect(ui->pushButton_recive,SIGNAL(pressed()),this,SLOT(getWalletPageButtonsStatus())); + connect(ui->pushButton_send,SIGNAL(pressed()),this,SLOT(getWalletPageButtonsStatus())); + connect(ui->pushButton_set,SIGNAL(pressed()),this,SLOT(getWalletPageButtonsStatus())); + connect(ui->pushButton_wallet,SIGNAL(pressed()),this,SLOT(getWalletPageButtonsStatus())); + connect(ui->pushButton_markbill,SIGNAL(pressed()),this,SLOT(getWalletPageButtonsStatus())); + + connect(ui->pushButton_eipc,SIGNAL(pressed()),this,SLOT(getWalletPageButtonsStatus())); + + + QString button_style= + "QPushButton{image:url(:/res/png/wallet.png);color: white; border: none}" + "QPushButton:pressed{image:url(:/res/png/wallet_d.png);color:black; }"; + ui->pushButton_send->setStyleSheet(button_style); + + + ui->pushButton_recive->setStyleSheet("background-image:url(:/res/png/send.png);color: white;border:none;font-size:16px; "); + ui->pushButton_ipc->setStyleSheet("background-image:url(:/res/png/recv.png);color: white;border:none;font-size:16px"); + ui->pushButton_eipc->setStyleSheet("background-image:url(:/res/png/ipc.png);color: white;border:none;font-size:16px;"); + ui->pushButton_markbill->setStyleSheet("background-image:url(:/res/png/eIPC.png);color: white;border:none;font-size:16px;"); + ui->pushButton_set->setStyleSheet("background-image:url(:/res/png/markbill.png);color: white;border:none;font-size:16px;"); + ui->pushButton_unionaccount->setStyleSheet("background-image:url(:/res/png/setting.png);color: white;border:none;font-size:16px;"); + + setpushbuttonchecked("pushButton_wallet",ui->pushButton_send,"send.png","send_d.png"); + + ui->pushButton_send->setText(tr("\n\n\n")+tr("wallet")); + + ui->pushButton_recive->setText(tr("\n\n\n")+tr("send")); + ui->pushButton_ipc->setText(tr("\n\n\n")+tr("receive")); + ui->pushButton_eipc->setText(tr("\n\n\n")+tr("IP")); + ui->pushButton_markbill->setText(tr("\n\n\n")+tr("token")); + ui->pushButton_set->setText(tr("\n\n\n")+tr("markbill")); + ui->pushButton_unionaccount->setText(tr("\n\n\n")+tr("set")); + + } +} + +walletpagebuttons::~walletpagebuttons() +{ + delete ui; +} + + +void walletpagebuttons::fresh(int concount,int count) +{ + ui->nodenum->setText(QString::number(concount)); + ui->heightnum->setText(QString::number(count)); +} + + +void walletpagebuttons::on_pushButton_sendpic_pressed() +{ + if(isfirstfullloaded) + { + + if(is_uniond) + { + Q_EMIT sendpressed(); + } + else + { + Q_EMIT walletpressed(); + + } + } + else + { + CMessageBox msg; + setMsgDlgPlace(&msg); + msg.setIsClose(false); + msg.setCacelVisible(false); + msg.setMessage(3); + msg.exec(); + } +} + +void walletpagebuttons::on_pushButton_send_pressed() +{ + + + if(isfirstfullloaded) + { + Q_EMIT sendpressed(); + } + else + { + CMessageBox msg; + setMsgDlgPlace(&msg); + msg.setIsClose(false); + msg.setCacelVisible(false); + msg.setMessage(3); + msg.exec(); + + } +} + +void walletpagebuttons::on_pushButton_recivepic_pressed() +{ + if(isfirstfullloaded) + { + + Q_EMIT recivepressed(); + } + else + { + CMessageBox msg; + setMsgDlgPlace(&msg); + msg.setIsClose(false); + msg.setCacelVisible(false); + msg.setMessage(3); + msg.exec(); + + } +} + +void walletpagebuttons::on_pushButton_recive_pressed() +{ + if(isfirstfullloaded) + { + + if(is_uniond) + { + Q_EMIT recivepressed(); + } + else + { + Q_EMIT sendpressed(); + + } + } + else + { + CMessageBox msg; + setMsgDlgPlace(&msg); + msg.setIsClose(false); + msg.setCacelVisible(false); + msg.setMessage(3); + msg.exec(); + ui->pushButton_wallet->setChecked(true); + + } +} + +void walletpagebuttons::on_pushButton_ipcpic_pressed() +{ + if(isfirstfullloaded) + { + + Q_EMIT ipcpressed(); + } + else + { + CMessageBox msg; + setMsgDlgPlace(&msg); + msg.setIsClose(false); + msg.setCacelVisible(false); + msg.setMessage(3); + msg.exec(); + ui->pushButton_wallet->setChecked(true); + + } +} + +void walletpagebuttons::on_pushButton_ipc_pressed() +{ + if(isfirstfullloaded) + { + + if(is_uniond) + { + Q_EMIT ipcpressed(); + } + else + { + + Q_EMIT recivepressed(); + } + } + else + { + CMessageBox msg; + setMsgDlgPlace(&msg); + msg.setIsClose(false); + msg.setCacelVisible(false); + msg.setMessage(3); + msg.exec(); + ui->pushButton_wallet->setChecked(true); + + } +} + +void walletpagebuttons::on_pushButton_setpic_pressed() +{ + if(isfirstfullloaded) + { + + Q_EMIT setpressed(); + } + else + { + CMessageBox msg; + setMsgDlgPlace(&msg); + msg.setIsClose(false); + msg.setCacelVisible(false); + msg.setMessage(3); + msg.exec(); + ui->pushButton_wallet->setChecked(true); + + } +} + +void walletpagebuttons::on_pushButton_set_pressed() +{ + if(isfirstfullloaded) + { + if(is_uniond) + { + Q_EMIT setpressed(); + } + else + { + Q_EMIT tallypressed(); + } + } + else + { + CMessageBox msg; + setMsgDlgPlace(&msg); + msg.setIsClose(false); + msg.setCacelVisible(false); + msg.setMessage(3); + msg.exec(); + ui->pushButton_wallet->setChecked(true); + } +} +void walletpagebuttons::getWalletPageButtonsStatus() +{ + QPushButton* button = qobject_cast (sender()); + QString name = button->objectName(); + + if(is_uniond) + { + setpushbuttonchecked(name,ui->pushButton_wallet,"wallet.png","wallet_d.png"); + } + else + { + setpushbuttonchecked(name,ui->pushButton_send,"send.png","send_d.png"); + + } + if(isfirstfullloaded) + { + setpushbuttonchecked(name,ui->pushButton_send,"send.png","send_d.png"); + setpushbuttonchecked(name,ui->pushButton_recive,"recv.png","recv_d.png"); + setpushbuttonchecked(name,ui->pushButton_ipc,"ipc.png","ipc_d.png"); + setpushbuttonchecked(name,ui->pushButton_set,"setting.png","setting_d.png"); + setpushbuttonchecked(name,ui->pushButton_markbill,"markbill.png","markbill_d.png"); + + setpushbuttonchecked(name,ui->pushButton_eipc,"eIPC.png","eIPC_d.png"); + setpushbuttonchecked(name,ui->pushButton_unionaccount,"union.png","union_d.png"); + + } + else + { + if(is_uniond) + { + setpushbuttonchecked("pushButton_wallet",ui->pushButton_wallet,"wallet.png","wallet_d.png"); + } + else + { + setpushbuttonchecked("pushButton_send",ui->pushButton_send,"send.png","send_d.png"); + + } + } +} +void walletpagebuttons::setpushbuttonchecked(QString name,QPushButton* wallet,\ + QString graypicname,QString greenpicname) +{ + + QString picbuttonstyle; + picbuttonstyle = "QPushButton{border:none;background-image: \ + url(:/res/png/" ; + QString wordbuttonstyle = "QPushButton{border:none;font-size:10px;color:"; + + if(name == wallet->objectName()) + { + picbuttonstyle.append( greenpicname + ");"); + picbuttonstyle.append("color: white;border:none;font-size:16px;};"); + } + else + { + picbuttonstyle.append( graypicname + ");"); + picbuttonstyle.append("color: white;border:none;font-size:16px;};"); +} + wallet->setStyleSheet(picbuttonstyle); +} + + +void walletpagebuttons::on_pushButton_markbill_pressed() +{ + if(isfirstfullloaded) + { + if(is_uniond) + { + Q_EMIT tallypressed(); + } + else + { + Q_EMIT eipcpressed(); + } + } + else + { + CMessageBox msg; + setMsgDlgPlace(&msg); + msg.setIsClose(false); + msg.setCacelVisible(false); + msg.setMessage(3); + msg.exec(); + ui->pushButton_wallet->setChecked(true); + } +} + +void walletpagebuttons::on_pushButton_eipc_pressed() +{ + if(isfirstfullloaded) + { + if(is_uniond) + { + Q_EMIT eipcpressed(); + } + else + { + Q_EMIT ipcpressed(); + } + } + else + { + CMessageBox msg; + + setMsgDlgPlace(&msg); + msg.setIsClose(false); + msg.setCacelVisible(false); + msg.setMessage(3); + msg.exec(); + ui->pushButton_wallet->setChecked(true); + + } +} +void walletpagebuttons::setMsgDlgPlace(CMessageBox* pmsgdlg) +{ + QDesktopWidget* desktopWidget = QApplication::desktop(); + QRect applicationRect = desktopWidget->screenGeometry(); + QRect rectgeometry = QApplication::desktop()->geometry(); + QPoint xy = mapToGlobal(mapToParent(mapToParent(this->pos()))); + pmsgdlg->move(applicationRect.x()+1000/2-524/2+xy.x(),applicationRect.y()+660/2-287/2+xy.y()); + + +} + +void walletpagebuttons::on_pushButton_unionaccount_pressed() +{ + + if(isfirstfullloaded) + { + if(is_uniond) + { + Q_EMIT unionpressed(); + } + else + { + Q_EMIT setpressed(); + } + } + else + { + // Q_EMIT unionpressed(); + + CMessageBox msg; + setMsgDlgPlace(&msg); + msg.setIsClose(false); + msg.setCacelVisible(false); + msg.setMessage(3); + msg.exec(); + + + } + + +} + +void walletpagebuttons::on_pushButton_wallet_pressed() +{ + + + if(isfirstfullloaded) + { + if(is_uniond) + { + Q_EMIT walletpressed(); + } + else + { + } + } + else + { + CMessageBox msg; + setMsgDlgPlace(&msg); + msg.setIsClose(false); + msg.setCacelVisible(false); + msg.setMessage(3); + msg.exec(); + + } + +} diff --git a/.svn/pristine/73/736c72ad52ad9a2c84eed1d0b5270ae90b910f3d.svn-base b/.svn/pristine/73/736c72ad52ad9a2c84eed1d0b5270ae90b910f3d.svn-base new file mode 100644 index 0000000..aa2402f --- /dev/null +++ b/.svn/pristine/73/736c72ad52ad9a2c84eed1d0b5270ae90b910f3d.svn-base @@ -0,0 +1,36 @@ +#ifndef UNIONACCOUNTCREATE_H +#define UNIONACCOUNTCREATE_H + +#include +#include "wallet/wallet.h" +class WalletModel; +class QSortFilterProxyModel; +namespace Ui { +class unionaccountcreate; +} + +class unionaccountcreate : public QWidget +{ + Q_OBJECT + +public: + explicit unionaccountcreate(QWidget *parent = 0); + ~unionaccountcreate(); + void setModel(WalletModel *_model); + void showEvent(QShowEvent *event); + void setInit(); +Q_SIGNALS: + void opensuccesscreatePage(QString s1,QString s2); + void refreshunionaccount(); +private Q_SLOTS: + void on_createBtn_pressed(); + void coinUpdate(int idx); + + void on_btn_genkey_pressed(); + +private: + Ui::unionaccountcreate *ui; + WalletModel *model; +}; + +#endif // UNIONACCOUNTCREATE_H diff --git a/.svn/pristine/73/73fcedb882943bd444fd19269a9e2cc67195a30c.svn-base b/.svn/pristine/73/73fcedb882943bd444fd19269a9e2cc67195a30c.svn-base new file mode 100644 index 0000000..10c2a8e --- /dev/null +++ b/.svn/pristine/73/73fcedb882943bd444fd19269a9e2cc67195a30c.svn-base @@ -0,0 +1,149 @@ + + + res/icons/bitcoin.png + res/icons/bitcoin.ico + res/png/expose.png + res/png/ioport.png + res/png/history_btn.png + + + res/png/dateloaded.png + res/png/dateloading.png + res/png/update.png + res/png/attention.png + res/png/hide.png + res/png/updatebtn.png + res/png/smalllogo.png + res/png/sendlogo.png + res/png/add.png + res/png/ren.png + res/png/scan.png + res/png/go.png + res/png/safety.png + res/png/GoSetting.png + res/png/Nosetting.png + res/png/save.png + res/png/sendico.png + res/png/add_add.png + res/png/back.png + res/png/done.png + res/png/finish.png + res/png/gofee.png + res/png/logo.png + res/png/nextpage.png + res/png/search.png + res/png/set/about.png + res/png/set/addressbook.png + res/png/set/export.png + res/png/set/message.png + res/png/set/recovery.png + res/png/set/setpassword.png + res/png/ipctype/file.png + res/png/ipctype/music.png + res/png/ipctype/news.png + res/png/ipctype/patent.png + res/png/ipctype/picture.png + res/png/ipctype/securitycode.png + res/png/ipctype/trademark.png + res/png/ipctype/video.png + res/png/wallettab/IPCgray28_28.png + res/png/wallettab/IPCgreen28_28.png + res/png/wallettab/recivegray28_28.png + res/png/wallettab/recivegreen28_28.png + res/png/wallettab/sendgray28_28.png + res/png/wallettab/sendgreen28_28.png + res/png/wallettab/setgray28_28.png + res/png/wallettab/setgreen28_28.png + res/png/wallettab/walletgray28_28.png + res/png/wallettab/walletgreen28_28.png + res/png/recvicon.png + res/png/btnsbackpage.png + res/png/eIPC.png + res/png/ipc.png + res/png/markbill.png + res/png/recv.png + res/png/send.png + res/png/titlelogo.png + res/png/wallet.png + res/png/setting.png + res/png/coinrecv.png + res/png/coinsend.png + res/png/ecoinrecv.png + res/png/ecoinsend.png + res/png/ipcrecv.png + res/png/ipcsend.png + res/png/triangle.png + res/png/set/verification.png + res/png/set/selected.png + res/png/ren1.png + res/png/tx_input.png + res/png/tx_output.png + res/png/wallet_d.png + res/png/eIPC_d.png + res/png/setting_d.png + res/png/recv_d.png + res/png/send_d.png + res/png/ipc_d.png + res/png/markbill_d.png + res/png/loaded.png + res/png/loading.png + res/png/titlelogo_d.png + res/png/node.png + res/png/titlelogo_en.png + res/png/loading.gif + res/png/ipcinfoEnglish.png + res/png/loading0.png + res/png/loading1.png + res/png/loading2.png + res/png/loading3.png + res/png/loading/loading0.png + res/png/loading/loading1.png + res/png/loading/loading2.png + res/png/loading/loading3.png + res/png/loading/loading4.png + res/png/loading/loading5.png + res/png/loading/loading6.png + res/png/loading/loading7.png + res/png/loading/loading8.png + res/png/loading/loading9.png + res/png/loading/loading10.png + res/png/loading/loading11.png + res/png/loading/loading12.png + res/png/loading/loading13.png + res/png/loading/loading14.png + res/png/loading/loading15.png + res/png/loading/loading16.png + res/png/loading/loading17.png + res/png/loading/loading18.png + res/png/loading/loading19.png + res/png/loading/loading20.png + res/png/loading/loading21.png + res/png/loading/loading22.png + res/png/loading/loading23.png + res/png/loading/loading24.png + res/png/titlelogo_nen.png + res/png/hight.png + res/png/buttons/59_26.png + res/png/buttons/74_34.png + res/png/buttons/100_30.png + res/png/buttons/120_35.png + res/png/buttons/168_51.png + res/png/buttons/186_47.png + res/png/buttons/205_44.png + res/png/buttons/235_50.png + res/png/buttons/235_50gray.png + res/png/buttons/254_54.png + res/png/buttons/279_45.png + res/png/buttons/279_54.png + res/png/buttons/335_35.png + res/png/buttons/375_55.png + res/png/buttons/375_100.png + res/png/buttons/421_50.png + res/png/buttons/492_50.png + res/png/buttons/scan.png + res/png/buttons/260_35.png + res/png/union.png + res/png/union_d.png + res/png/item.png + + diff --git a/.svn/pristine/75/75b2bb4f3e518bacaf4d34a051557235fe469f4e.svn-base b/.svn/pristine/75/75b2bb4f3e518bacaf4d34a051557235fe469f4e.svn-base new file mode 100644 index 0000000..700472c --- /dev/null +++ b/.svn/pristine/75/75b2bb4f3e518bacaf4d34a051557235fe469f4e.svn-base @@ -0,0 +1,246 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2009-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "rpc/client.h" +#include "rpc/protocol.h" +#include "util.h" + +#include +#include + +#include // for to_lower() +#include + +using namespace std; + +class CRPCConvertParam +{ +public: + std::string methodName; //!< method whose params want conversion + int paramIdx; //!< 0-based idx of param to convert + std::string paramName; //!< parameter name +}; + +/** + * Specifiy a (method, idx, name) here if the argument is a non-string RPC + * argument and needs to be converted from JSON. + * + * @note Parameter indexes start from 0. + */ +static const CRPCConvertParam vRPCConvertParams[] = +{ + { "setmocktime", 0, "timestamp" }, + { "generate", 0, "nblocks" }, + { "generate", 1, "maxtries" }, + + { "generatedpoc", 0, "nblocks" }, + { "generatedpoc", 1, "nPeriodCount" }, + { "generatedpoc", 2, "nPeriodStartTime" }, + { "generatedpoc", 3, "nTimePeriod" }, + + { "getdpoclist", 0, "num" }, + + { "generatetoaddress", 0, "nblocks" }, + { "generatetoaddress", 2, "maxtries" }, + { "getnetworkhashps", 0, "nblocks" }, + { "getnetworkhashps", 1, "height" }, + { "sendtoaddress", 1, "amount" }, + { "sendtoaddress", 4, "subtractfeefromamount" }, + { "settxfee", 0, "amount" }, + { "getreceivedbyaddress", 1, "minconf" }, + { "getreceivedbyaccount", 1, "minconf" }, + { "listreceivedbyaddress", 0, "minconf" }, + { "listreceivedbyaddress", 1, "include_empty" }, + { "listreceivedbyaddress", 2, "include_watchonly" }, + { "listreceivedbyaccount", 0, "minconf" }, + { "listreceivedbyaccount", 1, "include_empty" }, + { "listreceivedbyaccount", 2, "include_watchonly" }, + { "getbalance", 1, "minconf" }, + { "getbalance", 2, "include_watchonly" }, + { "getblockhash", 0, "height" }, + { "waitforblockheight", 0, "height" }, + { "waitforblockheight", 1, "timeout" }, + { "waitforblock", 1, "timeout" }, + { "waitfornewblock", 0, "timeout" }, + { "move", 2, "amount" }, + { "move", 3, "minconf" }, + { "sendfrom", 2, "amount" }, + { "sendfrom", 3, "minconf" }, + { "listtransactions", 1, "count" }, + { "listtransactions", 2, "skip" }, + { "listtransactions", 3, "include_watchonly" }, + { "listtokentransactions", 1, "count" }, + { "listtokentransactions", 2, "skip" }, + { "listtokentransactions", 3, "include_watchonly" }, + { "listaccounts", 0, "minconf" }, + { "listaccounts", 1, "include_watchonly" }, + { "walletpassphrase", 1, "timeout" }, + { "getblocktemplate", 0, "template_request" }, + { "listsinceblock", 1, "target_confirmations" }, + { "listsinceblock", 2, "include_watchonly" }, + { "sendmany", 1, "amounts" }, +// { "sendmany", 2, "minconf" }, +// { "sendmany", 4, "subtractfeefrom" }, + { "sendtokenmany", 2, "amounts" }, + { "addmultisigaddress", 0, "nrequired" }, + { "addmultisigaddress", 1, "keys" }, + { "createmultiaddress", 0, "nrequired" }, + { "createmultiaddress", 1, "keys" }, + { "createmultisig", 0, "nrequired" }, + { "createmultisig", 1, "keys" }, + { "getunioncoins", 0, "addresses" }, + { "listunspent", 0, "minconf" }, + { "listunspent", 1, "maxconf" }, + { "listunspent", 2, "addresses" }, + { "listunspentNormal", 0, "minconf" }, + { "listunspentNormal", 1, "maxconf" }, + { "listunspentNormal", 2, "addresses" }, + { "listunspentIPC", 0, "minconf" }, + { "listunspentIPC", 1, "maxconf" }, + { "listunspentIPC", 2, "addresses" }, + { "listunspentToken", 0, "minconf" }, + { "listunspentToken", 1, "maxconf" }, + { "listunspentToken", 2, "addresses" }, + { "getblock", 1, "verbose" }, + { "getblockheader", 1, "verbose" }, + { "gettransaction", 1, "include_watchonly" }, + { "gettokentransaction", 1, "include_watchonly" }, + { "getrawtransaction", 1, "verbose" }, + { "createrawtransaction", 0, "inputs" }, + { "createrawtransaction", 1, "outputs" }, + { "createrawtransactionForIsolation", 0, "inputs" }, + { "createrawtransactionForIsolation", 1, "outputs" }, + { "signrawtransaction", 1, "prevtxs" }, + { "signrawtransaction", 2, "privkeys" }, + { "sendrawtransaction", 1, "allowhighfees" }, + { "fundrawtransaction", 1, "options" }, + { "gettxout", 1, "n" }, + { "gettxout", 2, "include_mempool" }, + { "gettxoutproof", 0, "txids" }, + { "lockunspent", 0, "unlock" }, + { "lockunspent", 1, "transactions" }, + { "importprivkey", 2, "rescan" }, + { "importaddress", 2, "rescan" }, + { "importaddress", 3, "p2sh" }, + { "importpubkey", 2, "rescan" }, + { "importmulti", 0, "requests" }, + { "importmulti", 1, "options" }, + { "verifychain", 0, "checklevel" }, + { "verifychain", 1, "nblocks" }, + { "pruneblockchain", 0, "height" }, + { "keypoolrefill", 0, "newsize" }, + { "getrawmempool", 0, "verbose" }, + { "estimatefee", 0, "nblocks" }, + { "estimatepriority", 0, "nblocks" }, + { "estimatesmartfee", 0, "nblocks" }, + { "estimatesmartpriority", 0, "nblocks" }, + { "prioritisetransaction", 1, "priority_delta" }, + { "prioritisetransaction", 2, "fee_delta" }, + { "setban", 2, "bantime" }, + { "setban", 3, "absolute" }, + { "setnetworkactive", 0, "state" }, + { "getmempoolancestors", 1, "verbose" }, + { "getmempooldescendants", 1, "verbose" }, + { "bumpfee", 1, "options" }, + // Echo with conversion (For testing only) + { "echojson", 0, "arg0" }, + { "echojson", 1, "arg1" }, + { "echojson", 2, "arg2" }, + { "echojson", 3, "arg3" }, + { "echojson", 4, "arg4" }, + { "echojson", 5, "arg5" }, + { "echojson", 6, "arg6" }, + { "echojson", 7, "arg7" }, + { "echojson", 8, "arg8" }, + { "echojson", 9, "arg9" }, +}; + +class CRPCConvertTable +{ +private: + std::set> members; + std::set> membersByName; + +public: + CRPCConvertTable(); + + bool convert(const std::string& method, int idx) { + return (members.count(std::make_pair(method, idx)) > 0); + } + bool convert(const std::string& method, const std::string& name) { + return (membersByName.count(std::make_pair(method, name)) > 0); + } +}; + +CRPCConvertTable::CRPCConvertTable() +{ + const unsigned int n_elem = + (sizeof(vRPCConvertParams) / sizeof(vRPCConvertParams[0])); + + for (unsigned int i = 0; i < n_elem; i++) { + members.insert(std::make_pair(vRPCConvertParams[i].methodName, + vRPCConvertParams[i].paramIdx)); + membersByName.insert(std::make_pair(vRPCConvertParams[i].methodName, + vRPCConvertParams[i].paramName)); + } +} + +static CRPCConvertTable rpcCvtTable; + +/** Non-RFC4627 JSON parser, accepts internal values (such as numbers, true, false, null) + * as well as objects and arrays. + */ +UniValue ParseNonRFCJSONValue(const std::string& strVal) +{ + UniValue jVal; + if (!jVal.read(std::string("[")+strVal+std::string("]")) || + !jVal.isArray() || jVal.size()!=1) + throw runtime_error(string("Error parsing JSON:")+strVal); + return jVal[0]; +} + +UniValue RPCConvertValues(const std::string &strMethod, const std::vector &strParams) +{ + UniValue params(UniValue::VARR); + + for (unsigned int idx = 0; idx < strParams.size(); idx++) { + const std::string& strVal = strParams[idx]; + + if (!rpcCvtTable.convert(strMethod, idx)) { + // insert string value directly + params.push_back(strVal); + } else { + // parse string as JSON, insert bool/number/object/etc. value + params.push_back(ParseNonRFCJSONValue(strVal)); + } + } + + return params; +} + +UniValue RPCConvertNamedValues(const std::string &strMethod, const std::vector &strParams) +{ + UniValue params(UniValue::VOBJ); + + for (const std::string &s: strParams) { + size_t pos = s.find("="); + if (pos == std::string::npos) { + throw(std::runtime_error("No '=' in named argument '"+s+"', this needs to be present for every argument (even if it is empty)")); + } + + std::string name = s.substr(0, pos); + std::string value = s.substr(pos+1); + + if (!rpcCvtTable.convert(strMethod, name)) { + // insert string value directly + params.pushKV(name, value); + } else { + // parse string as JSON, insert bool/number/object/etc. value + params.pushKV(name, ParseNonRFCJSONValue(value)); + } + } + + return params; +} diff --git a/.svn/pristine/7a/7a44d3cf69afbf74e138231e7bc92bff26b745cd.svn-base b/.svn/pristine/7a/7a44d3cf69afbf74e138231e7bc92bff26b745cd.svn-base new file mode 100644 index 0000000..f6f5024 --- /dev/null +++ b/.svn/pristine/7a/7a44d3cf69afbf74e138231e7bc92bff26b745cd.svn-base @@ -0,0 +1,238 @@ + + + unionaccounttrasend + + + + 0 + 0 + 556 + 492 + + + + Form + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + background-image: url(:/res/png/back.png);border:none + + + + + + + + + + + 0 + 103 + + + + + 16777215 + 103 + + + + font-size : 28px; +color: rgb(51, 51, 51); + + + create transaction + + + + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + address + + + + + + + address + + + + + + + + + + Qt::Horizontal + + + + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + num + + + + + + + num + + + + + + + + + + + + + true + + + + + + + background-color: rgb(242, 241, 240);border:none + + + true + + + + + + + Qt::Vertical + + + + 20 + 121 + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 421 + 50 + + + + + 421 + 50 + + + + ;color: rgb(255,255,255);font-size : 16px; +background-image: url(:/res/png/buttons/421_50.png);border:none + + + send + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Qt::Vertical + + + + 20 + 121 + + + + + + + + + diff --git a/.svn/pristine/7c/7cc5de6d144a64f3dda41d5cfee5b1bf61cec166.svn-base b/.svn/pristine/7c/7cc5de6d144a64f3dda41d5cfee5b1bf61cec166.svn-base new file mode 100644 index 0000000..c16f571 --- /dev/null +++ b/.svn/pristine/7c/7cc5de6d144a64f3dda41d5cfee5b1bf61cec166.svn-base @@ -0,0 +1,407 @@ + + + RecvTokenHistory + + + + 0 + 0 + 863 + 783 + + + + Form + + + + 0 + + + + + + 0 + 191 + + + + + 16777215 + 191 + + + + border:none + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 30 + + + + + + + + + + 41 + 41 + + + + + 41 + 41 + + + + background-image: url(:/res/png/recvicon.png); + + + + + + + + + + + 0 + 76 + + + + + 16777215 + 76 + + + + RecvToken + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + 13 + + + + background-color: rgb(242, 241, 240); + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + true + + + + + + + + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 61 + + + + + 16777215 + 61 + + + + + 30 + + + + + add + + + + + + + Qt::Horizontal + + + + 497 + 20 + + + + + + + + TextLabel + + + Qt::TextSelectableByMouse + + + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 61 + + + + + 16777215 + 61 + + + + + 30 + + + + + fee + + + + + + + Qt::Horizontal + + + + 634 + 20 + + + + + + + + TextLabel + + + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 61 + + + + + 16777215 + 61 + + + + border:none + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 30 + + + + + date + + + + + + + Qt::Horizontal + + + + 144 + 20 + + + + + + + + TextLabel + + + + + + + + + + Qt::Horizontal + + + + + + + + 0 + 61 + + + + + 16777215 + 61 + + + + border:none + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 30 + + + + + info + + + + + + + Qt::Horizontal + + + + 201 + 20 + + + + + + + + TextLabel + + + + + label_4 + horizontalSpacer_2 + infolabel + + + + + + Qt::Horizontal + + + + + + + Qt::Vertical + + + + 20 + 254 + + + + + + + + + diff --git a/.svn/pristine/84/8482d5810f47e5e66a7cb7c7f117e3a5ac02a73e.svn-base b/.svn/pristine/84/8482d5810f47e5e66a7cb7c7f117e3a5ac02a73e.svn-base new file mode 100644 index 0000000..98ec6b4 --- /dev/null +++ b/.svn/pristine/84/8482d5810f47e5e66a7cb7c7f117e3a5ac02a73e.svn-base @@ -0,0 +1,37 @@ +#ifndef SUCCESSFULTRADE_H +#define SUCCESSFULTRADE_H + +#include + +namespace Ui { +class SuccessfulTrade; +} + +class SuccessfulTrade : public QWidget +{ + Q_OBJECT + +public: + explicit SuccessfulTrade(QWidget *parent = 0); + ~SuccessfulTrade(); + enum SuccessText{ + successtrade, + successexport, + successrevovery, + successpsdset + }; + void setSuccessText(int); + void setsendSuccessText_(QString s1,QString s2); + void setSuccessText_(QString s1,QString s2); +private Q_SLOTS: + void on_pushButton_ok_pressed(); + + void on_btn_import_pressed(); + +Q_SIGNALS: + void back(); +private: + Ui::SuccessfulTrade *ui; +}; + +#endif // SUCCESSFULTRADE_H diff --git a/.svn/pristine/84/849ff0584390548b19b21879620b75ee48f93022.svn-base b/.svn/pristine/84/849ff0584390548b19b21879620b75ee48f93022.svn-base new file mode 100644 index 0000000..709b403 --- /dev/null +++ b/.svn/pristine/84/849ff0584390548b19b21879620b75ee48f93022.svn-base @@ -0,0 +1,43 @@ +#ifndef UNIONACCOUNTTRASEND_H +#define UNIONACCOUNTTRASEND_H + +#include +#include "wallet/wallet.h" +#include "walletmodel.h" +class WalletModel; +namespace Ui { +class unionaccounttrasend; +} + +class unionaccounttrasend : public QWidget +{ + Q_OBJECT + +public: + explicit unionaccounttrasend(QWidget *parent = 0); + ~unionaccounttrasend(); + void setModel(WalletModel *_model); + + void setaddress(QString add); + + QString getaddress(); + + void processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn); + +Q_SIGNALS: + void opensendsuccessPage(QString s1,QString s2); + void backtotraPage(); + +private Q_SLOTS: + void on_sendbtn_pressed(); + + void on_pushButton_back_pressed(); + +private: + Ui::unionaccounttrasend *ui; + std::string m_sendcoinerror;//,m_error; + WalletModel *model; + QString m_add; +}; + +#endif // UNIONACCOUNTTRASEND_H diff --git a/.svn/pristine/85/856703e32bfbbebbc35faf6b7cdcada88de0d2da.svn-base b/.svn/pristine/85/856703e32bfbbebbc35faf6b7cdcada88de0d2da.svn-base new file mode 100644 index 0000000..5e26f41 --- /dev/null +++ b/.svn/pristine/85/856703e32bfbbebbc35faf6b7cdcada88de0d2da.svn-base @@ -0,0 +1,315 @@ + + + unionaccount + + + + 0 + 0 + 667 + 617 + + + + Form + + + + + + + 310 + 0 + + + + + 310 + 16777215 + + + + + 0 + + + 0 + + + + + + 0 + 177 + + + + + 16777215 + 177 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + font-size :30px; +color: rgb(31, 168, 123); + + + TextLabel + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 13 + + + 0 + + + 0 + + + + + + 17 + + + 5 + + + 0 + + + 0 + + + + + + 120 + 35 + + + + + 120 + 35 + + + + Qt::NoFocus + + + background-image: url(:/res/png/buttons/120_35.png);border:none;color: rgb(255,255,255);font-size : 16px; + + + create + + + + + + + + 120 + 35 + + + + + 120 + 35 + + + + Qt::NoFocus + + + background-image: url(:/res/png/buttons/120_35.png);border:none;color: rgb(255,255,255);font-size : 16px; + + + join + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 260 + 35 + + + + + 260 + 35 + + + + Qt::NoFocus + + + background-image: url(:/res/png/buttons/260_35.png);border:none;color: rgb(255,255,255);font-size : 16px; + + + genkey + + + + + + + + + + + + + + + + + 310 + 0 + + + + + 310 + 16777215 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 310 + 0 + + + + + 310 + 16777215 + + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 308 + 377 + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.svn/pristine/89/89a718f29484054780efa8c9ab8f78f8eb183e58.svn-base b/.svn/pristine/89/89a718f29484054780efa8c9ab8f78f8eb183e58.svn-base new file mode 100644 index 0000000..26ee40d --- /dev/null +++ b/.svn/pristine/89/89a718f29484054780efa8c9ab8f78f8eb183e58.svn-base @@ -0,0 +1,268 @@ +// Copyright (c) 2011-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "receivecoinsdialog.h" +#include "ui_receivecoinsdialog.h" +#include "addresstablemodel.h" +#include "ipchainunits.h" +#include "guiutil.h" +#include "optionsmodel.h" +#include "platformstyle.h" +#include "recentrequeststablemodel.h" +#include "walletmodel.h" +#include "addresstablemodel.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "config/bitcoin-config.h" /* for USE_QRCODE */ +#include +#include "clickqlabel.h" +#include "cmessagebox.h" +ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *_platformStyle, QWidget *parent) : + QDialog(parent), + ui(new Ui::ReceiveCoinsDialog), + columnResizingFixer(0), + model(0), + platformStyle(_platformStyle) +{ + ui->setupUi(this); + contextMenu = new QMenu(this); + QAction *copyURIAction = new QAction(tr("Copy"), this); + + contextMenu = new QMenu(this); + contextMenu->addAction(copyURIAction); + + connect(ui->recentRequestsView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showMenu(QPoint))); + connect(copyURIAction, SIGNAL(triggered()), this, SLOT(copyURI())); + ClickQLabel* labelben = (ClickQLabel*)ui->AddLabel; + connect(labelben, SIGNAL(clicked()), this, SLOT(AddLabelClicked())); + +} +void ReceiveCoinsDialog::setModel(WalletModel *_model) +{ + this->model = _model; + if(_model && _model->getOptionsModel()) + { + _model->getRecentRequestsTableModel()->sort(RecentRequestsTableModel::Date, Qt::DescendingOrder); + QTableView* tableView = ui->recentRequestsView; + tableView->verticalHeader()->hide(); + tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + proxyModel = new QSortFilterProxyModel(this); + proxyModel->setSourceModel(_model->getAddressTableModel()); + proxyModel->setDynamicSortFilter(true); + proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); + proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); + proxyModel->setFilterRole(AddressTableModel::TypeRole); + proxyModel->setFilterFixedString(AddressTableModel::Receive); + tableView->setModel(proxyModel); + tableView->setColumnHidden(0,true); + tableView->setColumnWidth(1,508); + tableView->verticalHeader()->setDefaultSectionSize(54);//shezhihanggao + tableView->setAlternatingRowColors(true); + tableView->setSelectionBehavior(QAbstractItemView::SelectRows); + // Last 2 columns are set by the columnResizingFixer, when the table geometry is ready. + columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH, this); + QModelIndex buttomindex= proxyModel->index(0,1, QModelIndex()); + QVariant bumvar= buttomindex.data(); + QString str = bumvar.toString();; + char* ch; + QByteArray ba = str.toLatin1(); + ch=ba.data(); + QRcode *code = QRcode_encodeString(ch, 0, QR_ECLEVEL_L, QR_MODE_8, 1); + if (!code) + { + ui->label->setText(tr("Error encoding URI into QR Code.")); + return; + } + QImage qrImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32); + qrImage.fill(0xffffff); + unsigned char *p = code->data; + for (int y = 0; y < code->width; y++) + { + for (int x = 0; x < code->width; x++) + { + qrImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff)); + p++; + } + } + QRcode_free(code); + QImage qrAddrImage = QImage(200, 200, QImage::Format_RGB32); + qrAddrImage.fill(0xffffff); + QPainter painter(&qrAddrImage); + painter.drawImage(0, 0, qrImage.scaled(200, 200)); + QFont font = GUIUtil::fixedPitchFont(); + font.setPixelSize(25); + painter.setFont(font); + QRect paddedRect = qrAddrImage.rect(); + paddedRect.setHeight(200+25);//12 + painter.end(); + ui->AddLabel->setText(str); + ui->label->setPixmap(QPixmap::fromImage(qrAddrImage)); + + } +} + +ReceiveCoinsDialog::~ReceiveCoinsDialog() +{ + delete ui; +} +void ReceiveCoinsDialog::setRandString(QString & randString){ + int max = 8; + QString tmp = QString("0123456789ABCDEFGHIJKLMNOPQRSTUVWZYZ"); + QString str = QString(); + QTime t; + t= QTime::currentTime(); + qsrand(t.msec()+t.second()*1000); + for(int i=0;igetAddressTableModel()->addRow( AddressTableModel::Receive, + "",""); + std::string str = newadd.toStdString(); + + const char* ch = str.c_str(); + QRcode *code = QRcode_encodeString(ch, 0, QR_ECLEVEL_L, QR_MODE_8, 1); + if (!code) + { + ui->label->setText(tr("Error encoding URI into QR Code.")); + return; + } + QImage qrImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32); + qrImage.fill(0xffffff); + unsigned char *p = code->data; + for (int y = 0; y < code->width; y++) + { + for (int x = 0; x < code->width; x++) + { + qrImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff)); + p++; + } + } + QRcode_free(code); + QImage qrAddrImage = QImage(200, 200, QImage::Format_RGB32); + qrAddrImage.fill(0xffffff); + + QPainter painter(&qrAddrImage); + painter.drawImage(0, 0, qrImage.scaled(200, 200)); + QFont font = GUIUtil::fixedPitchFont(); + font.setPixelSize(25);//12);// + painter.setFont(font); + QRect paddedRect = qrAddrImage.rect(); + paddedRect.setHeight(200+25);//12); + painter.end(); + ui->AddLabel->setText(QString::fromStdString(str)); + ui->label->setPixmap(QPixmap::fromImage(qrAddrImage)); + + CMessageBox msg; + msg.setIsClose(false); + msg.setMessage(7); + msg.exec(); + if(msg.m_answertype == 1) + Q_EMIT gotoSetDialogExportPage(); +} + +void ReceiveCoinsDialog::on_recentRequestsView_clicked(const QModelIndex &index) +{ + + QString newadd = index.data().toString(); + std::string str = newadd.toStdString(); + + const char* ch = str.c_str(); + + QRcode *code = QRcode_encodeString(ch, 0, QR_ECLEVEL_L, QR_MODE_8, 1); + if (!code) + { + ui->label->setText(tr("Error encoding URI into QR Code.")); + return; + } + QImage qrImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32); + qrImage.fill(0xffffff); + unsigned char *p = code->data; + for (int y = 0; y < code->width; y++) + { + for (int x = 0; x < code->width; x++) + { + qrImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff)); + p++; + } + } + QRcode_free(code); + QImage qrAddrImage = QImage(200, 200, QImage::Format_RGB32); + qrAddrImage.fill(0xffffff); + QPainter painter(&qrAddrImage); + painter.drawImage(0, 0, qrImage.scaled(200, 200)); + QFont font = GUIUtil::fixedPitchFont(); + font.setPixelSize(25); + painter.setFont(font); + QRect paddedRect = qrAddrImage.rect(); + paddedRect.setHeight(200+25); + painter.end(); + ui->AddLabel->setText(QString::fromStdString(str)); + ui->label->setPixmap(QPixmap::fromImage(qrAddrImage)); +} + +QModelIndex ReceiveCoinsDialog::selectedRow() +{ + if(!proxyModel || !ui->recentRequestsView->selectionModel()) + { + return QModelIndex(); + } + + QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows(1); + if(selection.empty()) + return QModelIndex(); + + if(selection.size()>1) + return QModelIndex(); + QModelIndex firstIndex = selection.at(0); + + return firstIndex; +} + + +void ReceiveCoinsDialog::showMenu(const QPoint &point) +{ + if (!selectedRow().isValid()) { + return; + } + contextMenu->exec(QCursor::pos()); +} + + +void ReceiveCoinsDialog::copyURI() +{ + QModelIndex sel = selectedRow(); + if (!sel.isValid()) { + return; + } + QString address = sel.data().toString(); + GUIUtil::setClipboard(address); +} + +void ReceiveCoinsDialog::AddLabelClicked() +{ + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setText(ui->AddLabel->text()); +} + + + diff --git a/.svn/pristine/95/95437c829d0bdb258dfe18ffbfe9e73eaeb757ea.svn-base b/.svn/pristine/95/95437c829d0bdb258dfe18ffbfe9e73eaeb757ea.svn-base new file mode 100644 index 0000000..99bece6 --- /dev/null +++ b/.svn/pristine/95/95437c829d0bdb258dfe18ffbfe9e73eaeb757ea.svn-base @@ -0,0 +1,1468 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2009-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "amount.h" +#include "chain.h" +#include "chainparams.h" +#include "checkpoints.h" +#include "coins.h" +#include "consensus/validation.h" +#include "validation.h" +#include "policy/policy.h" +#include "primitives/transaction.h" +#include "rpc/server.h" +#include "streams.h" +#include "sync.h" +#include "txmempool.h" +#include "util.h" +#include "utilstrencodings.h" +#include "hash.h" + +#include + +#include + +#include // boost::thread::interrupt + +#include +#include +using namespace std; + +struct CUpdatedBlock +{ + uint256 hash; + int height; +}; + +static std::mutex cs_blockchange; +static std::condition_variable cond_blockchange; +static CUpdatedBlock latestblock; + +extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); +void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); + +double GetDifficulty(const CBlockIndex* blockindex) +{ + // Floating point number that is a multiple of the minimum difficulty, + // minimum difficulty = 1.0. + if (blockindex == NULL) + { + if (chainActive.Tip() == NULL) + return 1.0; + else + blockindex = chainActive.Tip(); + } + + int nShift = (blockindex->nBits >> 24) & 0xff; + + double dDiff = + (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff); + + while (nShift < 29) + { + dDiff *= 256.0; + nShift++; + } + while (nShift > 29) + { + dDiff /= 256.0; + nShift--; + } + + return dDiff; +} + +UniValue blockheaderToJSON(const CBlockIndex* blockindex) +{ + UniValue result(UniValue::VOBJ); + result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex())); + int confirmations = -1; + // Only report confirmations if the block is on the main chain + if (chainActive.Contains(blockindex)) + confirmations = chainActive.Height() - blockindex->nHeight + 1; + result.push_back(Pair("confirmations", confirmations)); + result.push_back(Pair("height", blockindex->nHeight)); + result.push_back(Pair("version", blockindex->nVersion)); + result.push_back(Pair("versionHex", strprintf("%08x", blockindex->nVersion))); + result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex())); + result.push_back(Pair("time", (int64_t)blockindex->nTime)); + result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast())); + result.push_back(Pair("nonce", (uint64_t)blockindex->nNonce)); + result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits))); + + result.push_back(Pair("nPeriodCount", (int)blockindex->nPeriodCount)); + result.push_back(Pair("nPeriodStartTime", (uint64_t)blockindex->nPeriodStartTime)); + result.push_back(Pair("nTimePeriod", (int)blockindex->nTimePeriod)); + + + result.push_back(Pair("difficulty", GetDifficulty(blockindex))); + result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); + + if (blockindex->pprev) + result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); + CBlockIndex *pnext = chainActive.Next(blockindex); + if (pnext) + result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex())); + return result; +} + +UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) +{ + UniValue result(UniValue::VOBJ); + result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex())); + int confirmations = -1; + // Only report confirmations if the block is on the main chain + if (chainActive.Contains(blockindex)) + confirmations = chainActive.Height() - blockindex->nHeight + 1; + result.push_back(Pair("confirmations", confirmations)); + result.push_back(Pair("strippedsize", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS))); + result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); + result.push_back(Pair("weight", (int)::GetBlockWeight(block))); + result.push_back(Pair("height", blockindex->nHeight)); + result.push_back(Pair("version", block.nVersion)); + result.push_back(Pair("versionHex", strprintf("%08x", block.nVersion))); + result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); + + UniValue txs(UniValue::VARR); + for(const auto& tx : block.vtx) + { + if(txDetails) + { + UniValue objTx(UniValue::VOBJ); + TxToJSON(*tx, uint256(), objTx); + txs.push_back(objTx); + } + else + txs.push_back(tx->GetHash().GetHex()); + + + } + + result.push_back(Pair("tx", txs)); + result.push_back(Pair("time", block.GetBlockTime())); + result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast())); + result.push_back(Pair("nonce", (uint64_t)block.nNonce)); + result.push_back(Pair("bits", strprintf("%08x", block.nBits))); + result.push_back(Pair("difficulty", GetDifficulty(blockindex))); + + result.push_back(Pair("nPeriodCount", (int)blockindex->nPeriodCount)); + result.push_back(Pair("nPeriodStartTime", (uint64_t)blockindex->nPeriodStartTime)); + result.push_back(Pair("nTimePeriod", (int)blockindex->nTimePeriod)); + + result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); + + if (blockindex->pprev) + result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); + CBlockIndex *pnext = chainActive.Next(blockindex); + if (pnext) + result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex())); + return result; +} + +UniValue getblockcount(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 0) + throw runtime_error( + "getblockcount\n" + "\nReturns the number of blocks in the longest blockchain.\n" + "\nResult:\n" + "n (numeric) The current block count\n" + "\nExamples:\n" + + HelpExampleCli("getblockcount", "") + + HelpExampleRpc("getblockcount", "") + ); + + LOCK(cs_main); + return chainActive.Height(); +} + +UniValue getbestblockhash(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 0) + throw runtime_error( + "getbestblockhash\n" + "\nReturns the hash of the best (tip) block in the longest blockchain.\n" + "\nResult:\n" + "\"hex\" (string) the block hash hex encoded\n" + "\nExamples:\n" + + HelpExampleCli("getbestblockhash", "") + + HelpExampleRpc("getbestblockhash", "") + ); + + LOCK(cs_main); + return chainActive.Tip()->GetBlockHash().GetHex(); +} + +void RPCNotifyBlockChange(bool ibd, const CBlockIndex * pindex) +{ + if(pindex) { + std::lock_guard lock(cs_blockchange); + latestblock.hash = pindex->GetBlockHash(); + latestblock.height = pindex->nHeight; + } + cond_blockchange.notify_all(); +} + +UniValue waitfornewblock(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() > 1) + throw runtime_error( + "waitfornewblock (timeout)\n" + "\nWaits for a specific new block and returns useful info about it.\n" + "\nReturns the current block on timeout or exit.\n" + "\nArguments:\n" + "1. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n" + "\nResult:\n" + "{ (json object)\n" + " \"hash\" : { (string) The blockhash\n" + " \"height\" : { (int) Block height\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("waitfornewblock", "1000") + + HelpExampleRpc("waitfornewblock", "1000") + ); + int timeout = 0; + if (request.params.size() > 0) + timeout = request.params[0].get_int(); + + CUpdatedBlock block; + { + std::unique_lock lock(cs_blockchange); + block = latestblock; + if(timeout) + cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&block]{return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning(); }); + else + cond_blockchange.wait(lock, [&block]{return latestblock.height != block.height || latestblock.hash != block.hash || !IsRPCRunning(); }); + block = latestblock; + } + UniValue ret(UniValue::VOBJ); + ret.push_back(Pair("hash", block.hash.GetHex())); + ret.push_back(Pair("height", block.height)); + return ret; +} + +UniValue waitforblock(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) + throw runtime_error( + "waitforblock (timeout)\n" + "\nWaits for a specific new block and returns useful info about it.\n" + "\nReturns the current block on timeout or exit.\n" + "\nArguments:\n" + "1. \"blockhash\" (required, string) Block hash to wait for.\n" + "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n" + "\nResult:\n" + "{ (json object)\n" + " \"hash\" : { (string) The blockhash\n" + " \"height\" : { (int) Block height\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000") + + HelpExampleRpc("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000") + ); + int timeout = 0; + + uint256 hash = uint256S(request.params[0].get_str()); + + if (request.params.size() > 1) + timeout = request.params[1].get_int(); + + CUpdatedBlock block; + { + std::unique_lock lock(cs_blockchange); + if(timeout) + cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&hash]{return latestblock.hash == hash || !IsRPCRunning();}); + else + cond_blockchange.wait(lock, [&hash]{return latestblock.hash == hash || !IsRPCRunning(); }); + block = latestblock; + } + + UniValue ret(UniValue::VOBJ); + ret.push_back(Pair("hash", block.hash.GetHex())); + ret.push_back(Pair("height", block.height)); + return ret; +} + +UniValue waitforblockheight(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) + throw runtime_error( + "waitforblockheight (timeout)\n" + "\nWaits for (at least) block height and returns the height and hash\n" + "of the current tip.\n" + "\nReturns the current block on timeout or exit.\n" + "\nArguments:\n" + "1. height (required, int) Block height to wait for (int)\n" + "2. timeout (int, optional, default=0) Time in milliseconds to wait for a response. 0 indicates no timeout.\n" + "\nResult:\n" + "{ (json object)\n" + " \"hash\" : { (string) The blockhash\n" + " \"height\" : { (int) Block height\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("waitforblockheight", "\"100\", 1000") + + HelpExampleRpc("waitforblockheight", "\"100\", 1000") + ); + int timeout = 0; + + int height = request.params[0].get_int(); + + if (request.params.size() > 1) + timeout = request.params[1].get_int(); + + CUpdatedBlock block; + { + std::unique_lock lock(cs_blockchange); + if(timeout) + cond_blockchange.wait_for(lock, std::chrono::milliseconds(timeout), [&height]{return latestblock.height >= height || !IsRPCRunning();}); + else + cond_blockchange.wait(lock, [&height]{return latestblock.height >= height || !IsRPCRunning(); }); + block = latestblock; + } + UniValue ret(UniValue::VOBJ); + ret.push_back(Pair("hash", block.hash.GetHex())); + ret.push_back(Pair("height", block.height)); + return ret; +} + +UniValue getdifficulty(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 0) + throw runtime_error( + "getdifficulty\n" + "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n" + "\nResult:\n" + "n.nnn (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty.\n" + "\nExamples:\n" + + HelpExampleCli("getdifficulty", "") + + HelpExampleRpc("getdifficulty", "") + ); + + LOCK(cs_main); + return GetDifficulty(); +} + +std::string EntryDescriptionString() +{ + return " \"size\" : n, (numeric) virtual transaction size as defined in BIP 141. This is different from actual serialized size for witness transactions as witness data is discounted.\n" + " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n" + " \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority\n" + " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n" + " \"height\" : n, (numeric) block height when transaction entered pool\n" + " \"startingpriority\" : n, (numeric) DEPRECATED. Priority when transaction entered pool\n" + " \"currentpriority\" : n, (numeric) DEPRECATED. Transaction priority now\n" + " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n" + " \"descendantsize\" : n, (numeric) virtual transaction size of in-mempool descendants (including this one)\n" + " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n" + " \"ancestorcount\" : n, (numeric) number of in-mempool ancestor transactions (including this one)\n" + " \"ancestorsize\" : n, (numeric) virtual transaction size of in-mempool ancestors (including this one)\n" + " \"ancestorfees\" : n, (numeric) modified fees (see above) of in-mempool ancestors (including this one)\n" + " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n" + " \"transactionid\", (string) parent transaction id\n" + " ... ]\n"; +} + +void entryToJSON(UniValue &info, const CTxMemPoolEntry &e) +{ + AssertLockHeld(mempool.cs); + + info.push_back(Pair("size", (int)e.GetTxSize())); + info.push_back(Pair("fee", ValueFromAmount(e.GetFee()))); + info.push_back(Pair("modifiedfee", ValueFromAmount(e.GetModifiedFee()))); + info.push_back(Pair("time", e.GetTime())); + info.push_back(Pair("height", (int)e.GetHeight())); + info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight()))); + info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height()))); + info.push_back(Pair("descendantcount", e.GetCountWithDescendants())); + info.push_back(Pair("descendantsize", e.GetSizeWithDescendants())); + info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants())); + info.push_back(Pair("ancestorcount", e.GetCountWithAncestors())); + info.push_back(Pair("ancestorsize", e.GetSizeWithAncestors())); + info.push_back(Pair("ancestorfees", e.GetModFeesWithAncestors())); + const CTransaction& tx = e.GetTx(); + set setDepends; + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + if (mempool.exists(txin.prevout.hash)) + setDepends.insert(txin.prevout.hash.ToString()); + } + + UniValue depends(UniValue::VARR); + BOOST_FOREACH(const string& dep, setDepends) + { + depends.push_back(dep); + } + + info.push_back(Pair("depends", depends)); +} + +UniValue mempoolToJSON(bool fVerbose = false) +{ + if (fVerbose) + { + LOCK(mempool.cs); + UniValue o(UniValue::VOBJ); + BOOST_FOREACH(const CTxMemPoolEntry& e, mempool.mapTx) + { + const uint256& hash = e.GetTx().GetHash(); + UniValue info(UniValue::VOBJ); + entryToJSON(info, e); + o.push_back(Pair(hash.ToString(), info)); + } + return o; + } + else + { + vector vtxid; + mempool.queryHashes(vtxid); + + UniValue a(UniValue::VARR); + BOOST_FOREACH(const uint256& hash, vtxid) + a.push_back(hash.ToString()); + + return a; + } +} + +UniValue getrawmempool(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() > 1) + throw runtime_error( + "getrawmempool ( verbose )\n" + "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n" + "\nArguments:\n" + "1. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n" + "\nResult: (for verbose = false):\n" + "[ (json array of string)\n" + " \"transactionid\" (string) The transaction id\n" + " ,...\n" + "]\n" + "\nResult: (for verbose = true):\n" + "{ (json object)\n" + " \"transactionid\" : { (json object)\n" + + EntryDescriptionString() + + " }, ...\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("getrawmempool", "true") + + HelpExampleRpc("getrawmempool", "true") + ); + + bool fVerbose = false; + if (request.params.size() > 0) + fVerbose = request.params[0].get_bool(); + + return mempoolToJSON(fVerbose); +} + +UniValue getmempoolancestors(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { + throw runtime_error( + "getmempoolancestors txid (verbose)\n" + "\nIf txid is in the mempool, returns all in-mempool ancestors.\n" + "\nArguments:\n" + "1. \"txid\" (string, required) The transaction id (must be in mempool)\n" + "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n" + "\nResult (for verbose=false):\n" + "[ (json array of strings)\n" + " \"transactionid\" (string) The transaction id of an in-mempool ancestor transaction\n" + " ,...\n" + "]\n" + "\nResult (for verbose=true):\n" + "{ (json object)\n" + " \"transactionid\" : { (json object)\n" + + EntryDescriptionString() + + " }, ...\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("getmempoolancestors", "\"mytxid\"") + + HelpExampleRpc("getmempoolancestors", "\"mytxid\"") + ); + } + + bool fVerbose = false; + if (request.params.size() > 1) + fVerbose = request.params[1].get_bool(); + + uint256 hash = ParseHashV(request.params[0], "parameter 1"); + + LOCK(mempool.cs); + + CTxMemPool::txiter it = mempool.mapTx.find(hash); + if (it == mempool.mapTx.end()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool"); + } + + CTxMemPool::setEntries setAncestors; + uint64_t noLimit = std::numeric_limits::max(); + std::string dummy; + mempool.CalculateMemPoolAncestors(*it, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false); + + if (!fVerbose) { + UniValue o(UniValue::VARR); + BOOST_FOREACH(CTxMemPool::txiter ancestorIt, setAncestors) { + o.push_back(ancestorIt->GetTx().GetHash().ToString()); + } + + return o; + } else { + UniValue o(UniValue::VOBJ); + BOOST_FOREACH(CTxMemPool::txiter ancestorIt, setAncestors) { + const CTxMemPoolEntry &e = *ancestorIt; + const uint256& _hash = e.GetTx().GetHash(); + UniValue info(UniValue::VOBJ); + entryToJSON(info, e); + o.push_back(Pair(_hash.ToString(), info)); + } + return o; + } +} + +UniValue getmempooldescendants(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) { + throw runtime_error( + "getmempooldescendants txid (verbose)\n" + "\nIf txid is in the mempool, returns all in-mempool descendants.\n" + "\nArguments:\n" + "1. \"txid\" (string, required) The transaction id (must be in mempool)\n" + "2. verbose (boolean, optional, default=false) True for a json object, false for array of transaction ids\n" + "\nResult (for verbose=false):\n" + "[ (json array of strings)\n" + " \"transactionid\" (string) The transaction id of an in-mempool descendant transaction\n" + " ,...\n" + "]\n" + "\nResult (for verbose=true):\n" + "{ (json object)\n" + " \"transactionid\" : { (json object)\n" + + EntryDescriptionString() + + " }, ...\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("getmempooldescendants", "\"mytxid\"") + + HelpExampleRpc("getmempooldescendants", "\"mytxid\"") + ); + } + + bool fVerbose = false; + if (request.params.size() > 1) + fVerbose = request.params[1].get_bool(); + + uint256 hash = ParseHashV(request.params[0], "parameter 1"); + + LOCK(mempool.cs); + + CTxMemPool::txiter it = mempool.mapTx.find(hash); + if (it == mempool.mapTx.end()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool"); + } + + CTxMemPool::setEntries setDescendants; + mempool.CalculateDescendants(it, setDescendants); + // CTxMemPool::CalculateDescendants will include the given tx + setDescendants.erase(it); + + if (!fVerbose) { + UniValue o(UniValue::VARR); + BOOST_FOREACH(CTxMemPool::txiter descendantIt, setDescendants) { + o.push_back(descendantIt->GetTx().GetHash().ToString()); + } + + return o; + } else { + UniValue o(UniValue::VOBJ); + BOOST_FOREACH(CTxMemPool::txiter descendantIt, setDescendants) { + const CTxMemPoolEntry &e = *descendantIt; + const uint256& _hash = e.GetTx().GetHash(); + UniValue info(UniValue::VOBJ); + entryToJSON(info, e); + o.push_back(Pair(_hash.ToString(), info)); + } + return o; + } +} + +UniValue getmempoolentry(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 1) { + throw runtime_error( + "getmempoolentry txid\n" + "\nReturns mempool data for given transaction\n" + "\nArguments:\n" + "1. \"txid\" (string, required) The transaction id (must be in mempool)\n" + "\nResult:\n" + "{ (json object)\n" + + EntryDescriptionString() + + "}\n" + "\nExamples:\n" + + HelpExampleCli("getmempoolentry", "\"mytxid\"") + + HelpExampleRpc("getmempoolentry", "\"mytxid\"") + ); + } + + uint256 hash = ParseHashV(request.params[0], "parameter 1"); + + LOCK(mempool.cs); + + CTxMemPool::txiter it = mempool.mapTx.find(hash); + if (it == mempool.mapTx.end()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not in mempool"); + } + + const CTxMemPoolEntry &e = *it; + UniValue info(UniValue::VOBJ); + entryToJSON(info, e); + return info; +} + +UniValue getblockhash(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "getblockhash height\n" + "\nReturns hash of block in best-block-chain at height provided.\n" + "\nArguments:\n" + "1. height (numeric, required) The height index\n" + "\nResult:\n" + "\"hash\" (string) The block hash\n" + "\nExamples:\n" + + HelpExampleCli("getblockhash", "1000") + + HelpExampleRpc("getblockhash", "1000") + ); + + LOCK(cs_main); + + int nHeight = request.params[0].get_int(); + if (nHeight < 0 || nHeight > chainActive.Height()) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); + + CBlockIndex* pblockindex = chainActive[nHeight]; + return pblockindex->GetBlockHash().GetHex(); +} + +UniValue getblockheader(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) + throw runtime_error( + "getblockheader \"hash\" ( verbose )\n" + "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n" + "If verbose is true, returns an Object with information about blockheader .\n" + "\nArguments:\n" + "1. \"hash\" (string, required) The block hash\n" + "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n" + "\nResult (for verbose = true):\n" + "{\n" + " \"hash\" : \"hash\", (string) the block hash (same as provided)\n" + " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n" + " \"height\" : n, (numeric) The block height or index\n" + " \"version\" : n, (numeric) The block version\n" + " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n" + " \"merkleroot\" : \"xxxx\", (string) The merkle root\n" + " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n" + " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n" + " \"nonce\" : n, (numeric) The nonce\n" + " \"bits\" : \"1d00ffff\", (string) The bits\n" + " \"difficulty\" : x.xxx, (numeric) The difficulty\n" + " \"chainwork\" : \"0000...1f3\" (string) Expected number of hashes required to produce the current chain (in hex)\n" + " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n" + " \"nextblockhash\" : \"hash\", (string) The hash of the next block\n" + "}\n" + "\nResult (for verbose=false):\n" + "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n" + "\nExamples:\n" + + HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") + + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") + ); + + LOCK(cs_main); + + std::string strHash = request.params[0].get_str(); + uint256 hash(uint256S(strHash)); + + bool fVerbose = true; + if (request.params.size() > 1) + fVerbose = request.params[1].get_bool(); + + if (mapBlockIndex.count(hash) == 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + + CBlockIndex* pblockindex = mapBlockIndex[hash]; + + if (!fVerbose) + { + CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); + ssBlock << pblockindex->GetBlockHeader(); + std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); + return strHex; + } + + return blockheaderToJSON(pblockindex); +} + +UniValue getblock(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) + throw runtime_error( + "getblock \"blockhash\" ( verbose )\n" + "\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash'.\n" + "If verbose is true, returns an Object with information about block .\n" + "\nArguments:\n" + "1. \"blockhash\" (string, required) The block hash\n" + "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n" + "\nResult (for verbose = true):\n" + "{\n" + " \"hash\" : \"hash\", (string) the block hash (same as provided)\n" + " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n" + " \"size\" : n, (numeric) The block size\n" + " \"strippedsize\" : n, (numeric) The block size excluding witness data\n" + " \"weight\" : n (numeric) The block weight as defined in BIP 141\n" + " \"height\" : n, (numeric) The block height or index\n" + " \"version\" : n, (numeric) The block version\n" + " \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n" + " \"merkleroot\" : \"xxxx\", (string) The merkle root\n" + " \"tx\" : [ (array of string) The transaction ids\n" + " \"transactionid\" (string) The transaction id\n" + " ,...\n" + " ],\n" + " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n" + " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n" + " \"nonce\" : n, (numeric) The nonce\n" + " \"bits\" : \"1d00ffff\", (string) The bits\n" + " \"difficulty\" : x.xxx, (numeric) The difficulty\n" + " \"chainwork\" : \"xxxx\", (string) Expected number of hashes required to produce the chain up to this block (in hex)\n" + " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n" + " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n" + "}\n" + "\nResult (for verbose=false):\n" + "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n" + "\nExamples:\n" + + HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") + + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") + ); + + LOCK(cs_main); + + std::string strHash = request.params[0].get_str(); + uint256 hash(uint256S(strHash)); + + bool fVerbose = true; + if (request.params.size() > 1) + fVerbose = request.params[1].get_bool(); + + if (mapBlockIndex.count(hash) == 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + + CBlock block; + CBlockIndex* pblockindex = mapBlockIndex[hash]; + + if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) + throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)"); + + if(!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) + throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); + + if (!fVerbose) + { + CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); + ssBlock << block; + std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); + return strHex; + } + + return blockToJSON(block, pblockindex); +} + +struct CCoinsStats +{ + int nHeight; + uint256 hashBlock; + uint64_t nTransactions; + uint64_t nTransactionOutputs; + uint64_t nSerializedSize; + uint256 hashSerialized; + CAmount nTotalAmount; + + CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), nTotalAmount(0) {} +}; + +//! Calculate statistics about the unspent transaction output set +static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats) +{ + std::unique_ptr pcursor(view->Cursor()); + + CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); + stats.hashBlock = pcursor->GetBestBlock(); + { + LOCK(cs_main); + stats.nHeight = mapBlockIndex.find(stats.hashBlock)->second->nHeight; + } + ss << stats.hashBlock; + CAmount nTotalAmount = 0; + while (pcursor->Valid()) { + boost::this_thread::interruption_point(); + uint256 key; + CCoins coins; + if (pcursor->GetKey(key) && pcursor->GetValue(coins)) { + stats.nTransactions++; + ss << key; + for (unsigned int i=0; iGetValueSize(); + ss << VARINT(0); + } else { + return error("%s: unable to read value", __func__); + } + pcursor->Next(); + } + stats.hashSerialized = ss.GetHash(); + stats.nTotalAmount = nTotalAmount; + return true; +} + +UniValue pruneblockchain(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "pruneblockchain\n" + "\nArguments:\n" + "1. \"height\" (numeric, required) The block height to prune up to. May be set to a discrete height, or a unix timestamp\n" + " to prune blocks whose block time is at least 2 hours older than the provided timestamp.\n" + "\nResult:\n" + "n (numeric) Height of the last block pruned.\n" + "\nExamples:\n" + + HelpExampleCli("pruneblockchain", "1000") + + HelpExampleRpc("pruneblockchain", "1000")); + + if (!fPruneMode) + throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Cannot prune blocks because node is not in prune mode."); + + LOCK(cs_main); + + int heightParam = request.params[0].get_int(); + if (heightParam < 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative block height."); + + // Height value more than a billion is too high to be a block height, and + // too low to be a block time (corresponds to timestamp from Sep 2001). + if (heightParam > 1000000000) { + // Add a 2 hour buffer to include blocks which might have had old timestamps + CBlockIndex* pindex = chainActive.FindEarliestAtLeast(heightParam - 7200); + if (!pindex) { + throw JSONRPCError(RPC_INTERNAL_ERROR, "Could not find block with at least the specified timestamp."); + } + heightParam = pindex->nHeight; + } + + unsigned int height = (unsigned int) heightParam; + unsigned int chainHeight = (unsigned int) chainActive.Height(); + if (chainHeight < Params().PruneAfterHeight()) + throw JSONRPCError(RPC_INTERNAL_ERROR, "Blockchain is too short for pruning."); + else if (height > chainHeight) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Blockchain is shorter than the attempted prune height."); + else if (height > chainHeight - MIN_BLOCKS_TO_KEEP) { + LogPrint("rpc", "Attempt to prune blocks close to the tip. Retaining the minimum number of blocks."); + height = chainHeight - MIN_BLOCKS_TO_KEEP; + } + + PruneBlockFilesManual(height); + return uint64_t(height); +} + +UniValue gettxoutsetinfo(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 0) + throw runtime_error( + "gettxoutsetinfo\n" + "\nReturns statistics about the unspent transaction output set.\n" + "Note this call may take some time.\n" + "\nResult:\n" + "{\n" + " \"height\":n, (numeric) The current block height (index)\n" + " \"bestblock\": \"hex\", (string) the best block hash hex\n" + " \"transactions\": n, (numeric) The number of transactions\n" + " \"txouts\": n, (numeric) The number of output transactions\n" + " \"bytes_serialized\": n, (numeric) The serialized size\n" + " \"hash_serialized\": \"hash\", (string) The serialized hash\n" + " \"total_amount\": x.xxx (numeric) The total amount\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("gettxoutsetinfo", "") + + HelpExampleRpc("gettxoutsetinfo", "") + ); + + UniValue ret(UniValue::VOBJ); + + CCoinsStats stats; + FlushStateToDisk(); + if (GetUTXOStats(pcoinsTip, stats)) { + ret.push_back(Pair("height", (int64_t)stats.nHeight)); + ret.push_back(Pair("bestblock", stats.hashBlock.GetHex())); + ret.push_back(Pair("transactions", (int64_t)stats.nTransactions)); + ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs)); + ret.push_back(Pair("bytes_serialized", (int64_t)stats.nSerializedSize)); + ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex())); + ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount))); + } else { + throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set"); + } + return ret; +} + +UniValue gettxout(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) + throw runtime_error( + "gettxout \"txid\" n ( include_mempool )\n" + "\nReturns details about an unspent transaction output.\n" + "\nArguments:\n" + "1. \"txid\" (string, required) The transaction id\n" + "2. n (numeric, required) vout number\n" + "3. include_mempool (boolean, optional) Whether to include the mempool\n" + "\nResult:\n" + "{\n" + " \"bestblock\" : \"hash\", (string) the block hash\n" + " \"confirmations\" : n, (numeric) The number of confirmations\n" + " \"value\" : x.xxx, (numeric) The transaction value in " + CURRENCY_UNIT + "\n" + " \"scriptPubKey\" : { (json object)\n" + " \"asm\" : \"code\", (string) \n" + " \"hex\" : \"hex\", (string) \n" + " \"reqSigs\" : n, (numeric) Number of required signatures\n" + " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n" + " \"addresses\" : [ (array of string) array of ipchain addresses\n" + " \"address\" (string) ipchain address\n" + " ,...\n" + " ]\n" + " },\n" + " \"version\" : n, (numeric) The version\n" + " \"coinbase\" : true|false (boolean) Coinbase or not\n" + "}\n" + + "\nExamples:\n" + "\nGet unspent transactions\n" + + HelpExampleCli("listunspent", "") + + "\nView the details\n" + + HelpExampleCli("gettxout", "\"txid\" 1") + + "\nAs a json rpc call\n" + + HelpExampleRpc("gettxout", "\"txid\", 1") + ); + + LOCK(cs_main); + + UniValue ret(UniValue::VOBJ); + + std::string strHash = request.params[0].get_str(); + uint256 hash(uint256S(strHash)); + int n = request.params[1].get_int(); + bool fMempool = true; + if (request.params.size() > 2) + fMempool = request.params[2].get_bool(); + + CCoins coins; + if (fMempool) { + LOCK(mempool.cs); + CCoinsViewMemPool view(pcoinsTip, mempool); + if (!view.GetCoins(hash, coins)) + return NullUniValue; + mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool + } else { + if (!pcoinsTip->GetCoins(hash, coins)) + return NullUniValue; + } + if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull()) + return NullUniValue; + + BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); + CBlockIndex *pindex = it->second; + ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex())); + if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT) + ret.push_back(Pair("confirmations", 0)); + else + ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1)); + ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue))); + UniValue o(UniValue::VOBJ); + ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true); + ret.push_back(Pair("scriptPubKey", o)); + ret.push_back(Pair("version", coins.nVersion)); + ret.push_back(Pair("coinbase", coins.fCoinBase)); + + return ret; +} + +UniValue verifychain(const JSONRPCRequest& request) +{ + int nCheckLevel = GetArg("-checklevel", DEFAULT_CHECKLEVEL); + int nCheckDepth = GetArg("-checkblocks", DEFAULT_CHECKBLOCKS); + if (request.fHelp || request.params.size() > 2) + throw runtime_error( + "verifychain ( checklevel nblocks )\n" + "\nVerifies blockchain database.\n" + "\nArguments:\n" + "1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel) + ") How thorough the block verification is.\n" + "2. nblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth) + ", 0=all) The number of blocks to check.\n" + "\nResult:\n" + "true|false (boolean) Verified or not\n" + "\nExamples:\n" + + HelpExampleCli("verifychain", "") + + HelpExampleRpc("verifychain", "") + ); + + LOCK(cs_main); + + if (request.params.size() > 0) + nCheckLevel = request.params[0].get_int(); + if (request.params.size() > 1) + nCheckDepth = request.params[1].get_int(); + + return CVerifyDB().VerifyDB(Params(), pcoinsTip, nCheckLevel, nCheckDepth); +} + +/** Implementation of IsSuperMajority with better feedback */ +static UniValue SoftForkMajorityDesc(int version, CBlockIndex* pindex, const Consensus::Params& consensusParams) +{ + UniValue rv(UniValue::VOBJ); + bool activated = false; + switch(version) + { + case 2: + activated = pindex->nHeight >= consensusParams.BIP34Height; + break; + case 3: + activated = pindex->nHeight >= consensusParams.BIP66Height; + break; + case 4: + activated = pindex->nHeight >= consensusParams.BIP65Height; + break; + } + rv.push_back(Pair("status", activated)); + return rv; +} + +static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams) +{ + UniValue rv(UniValue::VOBJ); + rv.push_back(Pair("id", name)); + rv.push_back(Pair("version", version)); + rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams))); + return rv; +} + +static UniValue BIP9SoftForkDesc(const Consensus::Params& consensusParams, Consensus::DeploymentPos id) +{ + UniValue rv(UniValue::VOBJ); + const ThresholdState thresholdState = VersionBitsTipState(consensusParams, id); + switch (thresholdState) { + case THRESHOLD_DEFINED: rv.push_back(Pair("status", "defined")); break; + case THRESHOLD_STARTED: rv.push_back(Pair("status", "started")); break; + case THRESHOLD_LOCKED_IN: rv.push_back(Pair("status", "locked_in")); break; + case THRESHOLD_ACTIVE: rv.push_back(Pair("status", "active")); break; + case THRESHOLD_FAILED: rv.push_back(Pair("status", "failed")); break; + } + if (THRESHOLD_STARTED == thresholdState) + { + rv.push_back(Pair("bit", consensusParams.vDeployments[id].bit)); + } + rv.push_back(Pair("startTime", consensusParams.vDeployments[id].nStartTime)); + rv.push_back(Pair("timeout", consensusParams.vDeployments[id].nTimeout)); + rv.push_back(Pair("since", VersionBitsTipStateSinceHeight(consensusParams, id))); + return rv; +} + +void BIP9SoftForkDescPushBack(UniValue& bip9_softforks, const std::string &name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id) +{ + // Deployments with timeout value of 0 are hidden. + // A timeout value of 0 guarantees a softfork will never be activated. + // This is used when softfork codes are merged without specifying the deployment schedule. + if (consensusParams.vDeployments[id].nTimeout > 0) + bip9_softforks.push_back(Pair(name, BIP9SoftForkDesc(consensusParams, id))); +} + +UniValue getblockchaininfo(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 0) + throw runtime_error( + "getblockchaininfo\n" + "Returns an object containing various state info regarding blockchain processing.\n" + "\nResult:\n" + "{\n" + " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n" + " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n" + " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n" + " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n" + " \"difficulty\": xxxxxx, (numeric) the current difficulty\n" + " \"mediantime\": xxxxxx, (numeric) median time for the current best block\n" + " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n" + " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n" + " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n" + " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored\n" + " \"softforks\": [ (array) status of softforks in progress\n" + " {\n" + " \"id\": \"xxxx\", (string) name of softfork\n" + " \"version\": xx, (numeric) block version\n" + " \"reject\": { (object) progress toward rejecting pre-softfork blocks\n" + " \"status\": xx, (boolean) true if threshold reached\n" + " },\n" + " }, ...\n" + " ],\n" + " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n" + " \"xxxx\" : { (string) name of the softfork\n" + " \"status\": \"xxxx\", (string) one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\"\n" + " \"bit\": xx, (numeric) the bit (0-28) in the block version field used to signal this softfork (only for \"started\" status)\n" + " \"startTime\": xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n" + " \"timeout\": xx, (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n" + " \"since\": xx (numeric) height of the first block to which the status applies\n" + " }\n" + " }\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("getblockchaininfo", "") + + HelpExampleRpc("getblockchaininfo", "") + ); + + LOCK(cs_main); + + UniValue obj(UniValue::VOBJ); + obj.push_back(Pair("chain", Params().NetworkIDString())); + obj.push_back(Pair("blocks", (int)chainActive.Height())); + obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1)); + obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex())); + obj.push_back(Pair("difficulty", (double)GetDifficulty())); + obj.push_back(Pair("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast())); + obj.push_back(Pair("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive.Tip()))); + obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex())); + obj.push_back(Pair("pruned", fPruneMode)); + + const Consensus::Params& consensusParams = Params().GetConsensus(); + CBlockIndex* tip = chainActive.Tip(); + UniValue softforks(UniValue::VARR); + UniValue bip9_softforks(UniValue::VOBJ); + softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams)); + softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams)); + softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams)); + BIP9SoftForkDescPushBack(bip9_softforks, "csv", consensusParams, Consensus::DEPLOYMENT_CSV); + BIP9SoftForkDescPushBack(bip9_softforks, "segwit", consensusParams, Consensus::DEPLOYMENT_SEGWIT); + obj.push_back(Pair("softforks", softforks)); + obj.push_back(Pair("bip9_softforks", bip9_softforks)); + + if (fPruneMode) + { + CBlockIndex *block = chainActive.Tip(); + while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA)) + block = block->pprev; + + obj.push_back(Pair("pruneheight", block->nHeight)); + } + return obj; +} + +/** Comparison function for sorting the getchaintips heads. */ +struct CompareBlocksByHeight +{ + bool operator()(const CBlockIndex* a, const CBlockIndex* b) const + { + /* Make sure that unequal blocks with the same height do not compare + equal. Use the pointers themselves to make a distinction. */ + + if (a->nHeight != b->nHeight) + return (a->nHeight > b->nHeight); + + return a < b; + } +}; + +UniValue getchaintips(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 0) + throw runtime_error( + "getchaintips\n" + "Return information about all known tips in the block tree," + " including the main chain as well as orphaned branches.\n" + "\nResult:\n" + "[\n" + " {\n" + " \"height\": xxxx, (numeric) height of the chain tip\n" + " \"hash\": \"xxxx\", (string) block hash of the tip\n" + " \"branchlen\": 0 (numeric) zero for main chain\n" + " \"status\": \"active\" (string) \"active\" for the main chain\n" + " },\n" + " {\n" + " \"height\": xxxx,\n" + " \"hash\": \"xxxx\",\n" + " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n" + " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n" + " }\n" + "]\n" + "Possible values for status:\n" + "1. \"invalid\" This branch contains at least one invalid block\n" + "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n" + "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n" + "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n" + "5. \"active\" This is the tip of the active main chain, which is certainly valid\n" + "\nExamples:\n" + + HelpExampleCli("getchaintips", "") + + HelpExampleRpc("getchaintips", "") + ); + + LOCK(cs_main); + + /* + * Idea: the set of chain tips is chainActive.tip, plus orphan blocks which do not have another orphan building off of them. + * Algorithm: + * - Make one pass through mapBlockIndex, picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers. + * - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip. + * - add chainActive.Tip() + */ + std::set setTips; + std::set setOrphans; + std::set setPrevs; + + BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex) + { + if (!chainActive.Contains(item.second)) { + setOrphans.insert(item.second); + setPrevs.insert(item.second->pprev); + } + } + + for (std::set::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it) + { + if (setPrevs.erase(*it) == 0) { + setTips.insert(*it); + } + } + + // Always report the currently active tip. + setTips.insert(chainActive.Tip()); + + /* Construct the output array. */ + UniValue res(UniValue::VARR); + BOOST_FOREACH(const CBlockIndex* block, setTips) + { + UniValue obj(UniValue::VOBJ); + obj.push_back(Pair("height", block->nHeight)); + obj.push_back(Pair("hash", block->phashBlock->GetHex())); + + const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight; + obj.push_back(Pair("branchlen", branchLen)); + + string status; + if (chainActive.Contains(block)) { + // This block is part of the currently active chain. + status = "active"; + } else if (block->nStatus & BLOCK_FAILED_MASK) { + // This block or one of its ancestors is invalid. + status = "invalid"; + } else if (block->nChainTx == 0) { + // This block cannot be connected because full block data for it or one of its parents is missing. + status = "headers-only"; + } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) { + // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized. + status = "valid-fork"; + } else if (block->IsValid(BLOCK_VALID_TREE)) { + // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain. + status = "valid-headers"; + } else { + // No clue. + status = "unknown"; + } + obj.push_back(Pair("status", status)); + + res.push_back(obj); + } + + return res; +} + +UniValue mempoolInfoToJSON() +{ + UniValue ret(UniValue::VOBJ); + ret.push_back(Pair("size", (int64_t) mempool.size())); + ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); + ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage())); + size_t maxmempool = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; + ret.push_back(Pair("maxmempool", (int64_t) maxmempool)); + ret.push_back(Pair("mempoolminfee", ValueFromAmount(mempool.GetMinFee(maxmempool).GetFeePerK()))); + + return ret; +} + +UniValue getmempoolinfo(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 0) + throw runtime_error( + "getmempoolinfo\n" + "\nReturns details on the active state of the TX memory pool.\n" + "\nResult:\n" + "{\n" + " \"size\": xxxxx, (numeric) Current tx count\n" + " \"bytes\": xxxxx, (numeric) Sum of all virtual transaction sizes as defined in BIP 141. Differs from actual serialized size because witness data is discounted\n" + " \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n" + " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n" + " \"mempoolminfee\": xxxxx (numeric) Minimum fee for tx to be accepted\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("getmempoolinfo", "") + + HelpExampleRpc("getmempoolinfo", "") + ); + + return mempoolInfoToJSON(); +} + +UniValue preciousblock(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "preciousblock \"blockhash\"\n" + "\nTreats a block as if it were received before others with the same work.\n" + "\nA later preciousblock call can override the effect of an earlier one.\n" + "\nThe effects of preciousblock are not retained across restarts.\n" + "\nArguments:\n" + "1. \"blockhash\" (string, required) the hash of the block to mark as precious\n" + "\nResult:\n" + "\nExamples:\n" + + HelpExampleCli("preciousblock", "\"blockhash\"") + + HelpExampleRpc("preciousblock", "\"blockhash\"") + ); + + std::string strHash = request.params[0].get_str(); + uint256 hash(uint256S(strHash)); + CBlockIndex* pblockindex; + + { + LOCK(cs_main); + if (mapBlockIndex.count(hash) == 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + + pblockindex = mapBlockIndex[hash]; + } + + CValidationState state; + PreciousBlock(state, Params(), pblockindex); + + if (!state.IsValid()) { + throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); + } + + return NullUniValue; +} + +UniValue invalidateblock(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "invalidateblock \"blockhash\"\n" + "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n" + "\nArguments:\n" + "1. \"blockhash\" (string, required) the hash of the block to mark as invalid\n" + "\nResult:\n" + "\nExamples:\n" + + HelpExampleCli("invalidateblock", "\"blockhash\"") + + HelpExampleRpc("invalidateblock", "\"blockhash\"") + ); + + std::string strHash = request.params[0].get_str(); + uint256 hash(uint256S(strHash)); + CValidationState state; + + { + LOCK(cs_main); + if (mapBlockIndex.count(hash) == 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + + CBlockIndex* pblockindex = mapBlockIndex[hash]; + InvalidateBlock(state, Params(), pblockindex); + } + + if (state.IsValid()) { + ActivateBestChain(state, Params()); + } + + if (!state.IsValid()) { + throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); + } + + return NullUniValue; +} + +UniValue reconsiderblock(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "reconsiderblock \"blockhash\"\n" + "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n" + "This can be used to undo the effects of invalidateblock.\n" + "\nArguments:\n" + "1. \"blockhash\" (string, required) the hash of the block to reconsider\n" + "\nResult:\n" + "\nExamples:\n" + + HelpExampleCli("reconsiderblock", "\"blockhash\"") + + HelpExampleRpc("reconsiderblock", "\"blockhash\"") + ); + + std::string strHash = request.params[0].get_str(); + uint256 hash(uint256S(strHash)); + + { + LOCK(cs_main); + if (mapBlockIndex.count(hash) == 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + + CBlockIndex* pblockindex = mapBlockIndex[hash]; + ResetBlockFailureFlags(pblockindex); + } + + CValidationState state; + ActivateBestChain(state, Params()); + + if (!state.IsValid()) { + throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); + } + + return NullUniValue; +} + +static const CRPCCommand commands[] = +{ // category name actor (function) okSafe argNames + // --------------------- ------------------------ ----------------------- ------ ---------- + { "blockchain", "getblockchaininfo", &getblockchaininfo, true, {} }, + { "blockchain", "getbestblockhash", &getbestblockhash, true, {} }, + { "blockchain", "getblockcount", &getblockcount, true, {} }, + { "blockchain", "getblock", &getblock, true, {"blockhash","verbose"} }, + { "blockchain", "getblockhash", &getblockhash, true, {"height"} }, + { "blockchain", "getblockheader", &getblockheader, true, {"blockhash","verbose"} }, + { "blockchain", "getchaintips", &getchaintips, true, {} }, +// { "blockchain", "getdifficulty", &getdifficulty, true, {} }, +// { "blockchain", "getmempoolancestors", &getmempoolancestors, true, {"txid","verbose"} }, +// { "blockchain", "getmempooldescendants", &getmempooldescendants, true, {"txid","verbose"} }, + { "blockchain", "getmempoolentry", &getmempoolentry, true, {"txid"} }, + { "blockchain", "getmempoolinfo", &getmempoolinfo, true, {} }, + { "blockchain", "getrawmempool", &getrawmempool, true, {"verbose"} }, + { "blockchain", "gettxout", &gettxout, true, {"txid","n","include_mempool"} }, + { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, {} }, +// { "blockchain", "pruneblockchain", &pruneblockchain, true, {"height"} }, +// { "blockchain", "verifychain", &verifychain, true, {"checklevel","nblocks"} }, + +// { "blockchain", "preciousblock", &preciousblock, true, {"blockhash"} }, + + /* Not shown in help */ + { "hidden", "invalidateblock", &invalidateblock, true, {"blockhash"} }, + { "hidden", "reconsiderblock", &reconsiderblock, true, {"blockhash"} }, + { "hidden", "waitfornewblock", &waitfornewblock, true, {"timeout"} }, + { "hidden", "waitforblock", &waitforblock, true, {"blockhash","timeout"} }, + { "hidden", "waitforblockheight", &waitforblockheight, true, {"height","timeout"} }, +}; + +void RegisterBlockchainRPCCommands(CRPCTable &t) +{ + for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) + t.appendCommand(commands[vcidx].name, &commands[vcidx]); +} diff --git a/.svn/pristine/97/973f4aa9ffd14f0f972b64a716c997a4890d196c.svn-base b/.svn/pristine/97/973f4aa9ffd14f0f972b64a716c997a4890d196c.svn-base new file mode 100644 index 0000000..d81496f --- /dev/null +++ b/.svn/pristine/97/973f4aa9ffd14f0f972b64a716c997a4890d196c.svn-base @@ -0,0 +1,254 @@ + + + ecoindialog + + + + 0 + 0 + 800 + 501 + + + + Form + + + + + + + + + + + + + 310 + 0 + + + + + 310 + 16777215 + + + + + + + + 310 + 177 + + + + + 310 + 177 + + + + + + + Qt::Vertical + + + + 20 + 30 + + + + + + + + + + Qt::Horizontal + + + + 28 + 17 + + + + + + + + font-size :30px; +color: rgb(31, 168, 123); + + + TokenNum: + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + font-size :24px; +color: rgb(31, 168, 123); + + + 0 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 29 + + + + + + + + + + + + + + + + + + chooseadd + + + + + + + + 279 + 45 + + + + + 279 + 45 + + + + Qt::NoFocus + + + background-image: url(:/res/png/buttons/279_45.png);border:none;color: rgb(255,255,255);font-size : 16px; + + + CreateToken + + + + + + + Qt::Vertical + + + + 20 + 2 + + + + + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Qt::CustomContextMenu + + + + + + QFrame::NoFrame + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 292 + 282 + + + + + + + + + + widget_2 + stackedWidget + + + + diff --git a/.svn/pristine/97/97da5a46891af66ab1715db6077e38142c0b01df.svn-base b/.svn/pristine/97/97da5a46891af66ab1715db6077e38142c0b01df.svn-base new file mode 100644 index 0000000..bec168a --- /dev/null +++ b/.svn/pristine/97/97da5a46891af66ab1715db6077e38142c0b01df.svn-base @@ -0,0 +1,76 @@ +#include "unionacounthistorydetailr.h" +#include "ui_unionacounthistorydetailr.h" +#include "ipchainunits.h" +#include "log/log.h" +#include "walletmodel.h" +extern std::map vCoins; +unionacounthistorydetailR::unionacounthistorydetailR(QWidget *parent) : + QWidget(parent), + ui(new Ui::unionacounthistorydetailR) +{ + ui->setupUi(this); +} + +unionacounthistorydetailR::~unionacounthistorydetailR() +{ + delete ui; +} +void unionacounthistorydetailR::onmessagetra(QString &status) +{ + LOG_WRITE(LOG_INFO,"STATUS",status.toStdString().c_str()); + if(status.indexOf("Open")!=-1) + { + int i = status.indexOf("Open until"); + QString s1= status.mid(i,-1); + ui->label_info->setText(tr("Open until") + s1); + } + else if(status.indexOf("conflicted")!=-1) + { + int i = status.indexOf("conflicted with a transaction with"); + QString s1= status.mid(i,-1); + ui->label_info->setText(tr("conflicted with a transaction with") + s1); + } + else if(status.indexOf("offline")!=-1) + { + int i = status.indexOf("offline"); + QString s1= status.mid(0,i); + ui->label_info->setText(s1+ tr("offline")); + } + else if(status.indexOf("unconfirmed") !=-1) + { + int i = status.indexOf("unconfirmed"); + QString s1= status.mid(0,i); + ui->label_info->setText(s1+ tr("unconfirmed")); + } + else if(status.indexOf("confirmations") != -1) + { + int i = status.indexOf("confirmations"); + QString s1= status.mid(0,i); + LOG_WRITE(LOG_INFO,"confirmations",s1.toStdString().c_str()); + ui->label_info->setText(s1+ tr("confirmations")); + } + else + ui->label_info->setText(tr("unconfirmed")); +} + +void unionacounthistorydetailR::setinfo(std::string add, CAmount fee,bool isSend,CAmount num,QString status,QString strtime,QString txid) +{ + m_txid = txid; + ui->label_add->setText(QString::fromStdString(add)); + ui->textEdit->setText("+"+BitcoinUnits::formatWithUnit(0, num, false, BitcoinUnits::separatorAlways)); + ui->label_date->setText(strtime); + //ui->label_info->setText(status); + uint256 rv; + rv.SetHex(m_txid.toStdString()); + auto itor = vCoins.find(rv); + if(itor!= vCoins.end()){ + status = m_walletmodel->FormatTxStatus(*(itor->second)); + } + onmessagetra(status); + +} + +void unionacounthistorydetailR::on_btn_back_pressed() +{ + Q_EMIT unionRPage_back(); +} diff --git a/.svn/pristine/98/9846a8e7f062d578f4ec0f7946f1cfd047d759c2.svn-base b/.svn/pristine/98/9846a8e7f062d578f4ec0f7946f1cfd047d759c2.svn-base new file mode 100644 index 0000000..e80c68b --- /dev/null +++ b/.svn/pristine/98/9846a8e7f062d578f4ec0f7946f1cfd047d759c2.svn-base @@ -0,0 +1,40 @@ +#ifndef UNIONACCOUNTTRASIGN_H +#define UNIONACCOUNTTRASIGN_H + +#include +#include "wallet/wallet.h" +#include "cmessagebox.h" +class WalletModel; +namespace Ui { +class unionaccounttrasign; +} + +class unionaccounttrasign : public QWidget +{ + Q_OBJECT + +public: + explicit unionaccounttrasign(QWidget *parent = 0); + ~unionaccounttrasign(); + void setModel(WalletModel *_model); + void set0Text(); + bool getSignInfo(); + void setSourceAddress(std::string address){m_strSourceaddress = address;} +Q_SIGNALS: + void backtotraPage(); + void opensignsuccessPage(); +private Q_SLOTS: + void on_signBtn_pressed(); + + void on_backbtn_pressed(); + + void on_btn_sign_pressed(); + +private: + void setMsgDlgPlace(CMessageBox* pmsgdlg); + Ui::unionaccounttrasign *ui; + WalletModel *model; + std::string m_strSourceaddress; +}; + +#endif // UNIONACCOUNTTRASIGN_H diff --git a/.svn/pristine/98/98fd8ed94ae3d3bbe59d61fd8853803b5238664c.svn-base b/.svn/pristine/98/98fd8ed94ae3d3bbe59d61fd8853803b5238664c.svn-base new file mode 100644 index 0000000..ec9060c --- /dev/null +++ b/.svn/pristine/98/98fd8ed94ae3d3bbe59d61fd8853803b5238664c.svn-base @@ -0,0 +1,161 @@ +#include "cmessagebox.h" +#include "forms/ui_cmessagebox.h" +#include "dpoc/DpocInfo.h" +#include "log/stateinfo.h" +#include "walletmodel.h" +#include "log/log.h" +#include "init.h" +#include +CMessageBox::CMessageBox(QWidget *parent) : + QDialog(parent),m_isShutDown(false), + ui(new Ui::CMessageBox) +{ + ui->setupUi(this); + + Qt::WindowFlags flags=Qt::Dialog; + flags |=Qt::WindowCloseButtonHint; + this->setWindowFlags(flags); + + + + m_answertype = 0; + m_issend = 0; + m_msg = 0; + this->setFixedSize(524, 287); + this->resize(524, 287); + if( true == getIsClose()) + { + try{ + if(!CDpocInfo::Instance().IsHasLocalAccount()) + { + ui->label_message->setText(tr("Confirm exit?")); + } + else + { + ui->label_message->setText(tr("Is Bookkeeping,Confirm exit?")); + QPalette pa; + pa.setColor(QPalette::WindowText,Qt::red); + ui->label_message->setPalette(pa); + ui->pushButton_ok->setText(tr("forced return")); + ui->pushButton__cancle->setText(tr("wait for exit")); + } + + + + } + catch(...){ + } + } +} + +CMessageBox::~CMessageBox() +{ + delete ui; +} +void CMessageBox::setCacelVisible(bool isVisible) +{ + if(!isVisible) + { + ui->pushButton__cancle->setVisible(false); + + ui->horizontalLayout->removeWidget(ui->pushButton__cancle); + ui->pushButton_ok->setGeometry(ui->widget->width()/2,ui->pushButton_ok->y(),205,44); + } + +} +void CMessageBox::on_pushButton_ok_pressed() +{ + m_answertype = 1; + this->accept(); + if(4 == m_msg){ + StartShutdown(); + } + else if(5 == m_msg){ + m_issend = 1; + } +} +void CMessageBox::setWalletModel(WalletModel *model_) +{ + this->model=model_; +} +void CMessageBox::on_pushButton__cancle_pressed() +{ + if( true == getIsClose()) + { + try{ + if(CDpocInfo::Instance().IsHasLocalAccount()) + { + /* + pollTimer = new QTimer(this); + connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer())); + pollTimer->start(250); + */ + + model->startTimerControl(); + + + + // killTimer(m_nTimerID); + // m_nTimerID = this->startTimer(100); + + // timerEvent(NULL); + } + } + catch(...){ + } + } + m_answertype = 0; + m_issend = 0; + this->accept(); +} + + +void CMessageBox::updateTimer() +{ + + + + +} + + +void CMessageBox::setMessage(QString msg) +{ + ui->label_message->setText(msg); +} +void CMessageBox::setMessage(int msg) +{ + if(msg == 1) + ui->label_message->setText(tr("General punishment.Long term abnormal bookkeeping, please standardize bookkeeping behavior.")); + else if(msg == 2) + ui->label_message->setText(tr("Password input error more than 5 times, please prohibit input within a day!")); + else if(msg == 3) + ui->label_message->setText(tr("Date Updating,please waiting...")); + else if(msg == 4) + { + m_msg = 4; + ui->label_message->setText(tr("You have quit the bookkeeping ,do you close your wallet")); + } + else if(msg == 5) + { + m_msg = 5; + ui->pushButton_ok->setText(tr("OK")); + ui->pushButton__cancle->setText(tr("cancle")); + ui->label_message->setText(tr("Reach the confirmation number, whether the transaction is sent or not")); + } + else if(msg == 6) + { + m_msg = 6; + ui->label_message->setText(tr("The data is being loaded. Please wait a moment...")); + ui->pushButton_ok->hide(); + ui->pushButton__cancle->hide(); + } + else if(msg == 7) + { + m_msg = 7; + ui->label_message->setText(tr("For your asset safety, please backup your wallet again!")); + ui->pushButton_ok->show(); + ui->pushButton__cancle->show(); + } + +} diff --git a/.svn/pristine/9e/9eeb67a2ab5549782e13ac69f5f8db7e18c66bb8.svn-base b/.svn/pristine/9e/9eeb67a2ab5549782e13ac69f5f8db7e18c66bb8.svn-base new file mode 100644 index 0000000..98f03c9 --- /dev/null +++ b/.svn/pristine/9e/9eeb67a2ab5549782e13ac69f5f8db7e18c66bb8.svn-base @@ -0,0 +1,1109 @@ +// Copyright (c) 2009-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "base58.h" +#include "chain.h" +#include "rpc/server.h" +#include "init.h" +#include "validation.h" +#include "script/script.h" +#include "script/standard.h" +#include "sync.h" +#include "util.h" +#include "utiltime.h" +#include "wallet.h" +#include "merkleblock.h" +#include "core_io.h" + +#include +#include + +#include +#include + +#include + +#include +#include + +using namespace std; + +void EnsureWalletIsUnlocked(); +bool EnsureWalletIsAvailable(bool avoidException); + +std::string EncodeDumpTime(int64_t nTime) { + return DateTimeStrFormat("%Y-%m-%dT%H:%M:%SZ", nTime); +} + +int64_t DecodeDumpTime(const std::string &str) { + static const boost::posix_time::ptime epoch = boost::posix_time::from_time_t(0); + static const std::locale loc(std::locale::classic(), + new boost::posix_time::time_input_facet("%Y-%m-%dT%H:%M:%SZ")); + std::istringstream iss(str); + iss.imbue(loc); + boost::posix_time::ptime ptime(boost::date_time::not_a_date_time); + iss >> ptime; + if (ptime.is_not_a_date_time()) + return 0; + return (ptime - epoch).total_seconds(); +} + +std::string EncodeDumpString(const std::string &str) { + std::stringstream ret; + BOOST_FOREACH(unsigned char c, str) { + if (c <= 32 || c >= 128 || c == '%') { + ret << '%' << HexStr(&c, &c + 1); + } else { + ret << c; + } + } + return ret.str(); +} + +std::string DecodeDumpString(const std::string &str) { + std::stringstream ret; + for (unsigned int pos = 0; pos < str.length(); pos++) { + unsigned char c = str[pos]; + if (c == '%' && pos+2 < str.length()) { + c = (((str[pos+1]>>6)*9+((str[pos+1]-'0')&15)) << 4) | + ((str[pos+2]>>6)*9+((str[pos+2]-'0')&15)); + pos += 2; + } + ret << c; + } + return ret.str(); +} + +UniValue importprivkey(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) + throw runtime_error( + "importprivkey \"ipchainprivkey\" ( \"label\" ) ( rescan )\n" + "\nAdds a private key (as returned by dumpprivkey) to your wallet.\n" + "\nArguments:\n" + "1. \"ipchainprivkey\" (string, required) The private key (see dumpprivkey)\n" + "2. \"label\" (string, optional, default=\"\") An optional label\n" + "3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\n" + "\nNote: This call can take minutes to complete if rescan is true.\n" + "\nExamples:\n" + "\nDump a private key\n" + + HelpExampleCli("dumpprivkey", "\"myaddress\"") + + "\nImport the private key with rescan\n" + + HelpExampleCli("importprivkey", "\"mykey\"") + + "\nImport using a label and without rescan\n" + + HelpExampleCli("importprivkey", "\"mykey\" \"testing\" false") + + "\nImport using default blank label and without rescan\n" + + HelpExampleCli("importprivkey", "\"mykey\" \"\" false") + + "\nAs a JSON-RPC call\n" + + HelpExampleRpc("importprivkey", "\"mykey\", \"testing\", false") + ); + + + LOCK2(cs_main, pwalletMain->cs_wallet); + + EnsureWalletIsUnlocked(); + + string strSecret = request.params[0].get_str(); + string strLabel = ""; + if (request.params.size() > 1) + strLabel = request.params[1].get_str(); + + // Whether to perform rescan after import + bool fRescan = true; + if (request.params.size() > 2) + fRescan = request.params[2].get_bool(); + + if (fRescan && fPruneMode) + throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode"); + + CBitcoinSecret vchSecret; + bool fGood = vchSecret.SetString(strSecret); + + if (!fGood) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key encoding"); + + CKey key = vchSecret.GetKey(); + if (!key.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range"); + + CPubKey pubkey = key.GetPubKey(); + assert(key.VerifyPubKey(pubkey)); + CKeyID vchAddress = pubkey.GetID(); + { + pwalletMain->MarkDirty(); + pwalletMain->SetAddressBook(vchAddress, "", "receive"); + + // Don't throw error in case a key is already there + if (pwalletMain->HaveKey(vchAddress)) + return NullUniValue; + + pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = 1; + + if (!pwalletMain->AddKeyPubKey(key, pubkey)) + throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet"); + + // whenever a key is imported, we need to scan the whole chain + pwalletMain->UpdateTimeFirstKey(1); + + if (fRescan) { + pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true); + } + } + + return NullUniValue; +} + +void ImportAddress(const CBitcoinAddress& address, const string& strLabel); +void ImportScript(const CScript& script, const string& strLabel, bool isRedeemScript) +{ + if (!isRedeemScript && ::IsMine(*pwalletMain, script) == ISMINE_SPENDABLE) + throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script"); + + pwalletMain->MarkDirty(); + + if (!pwalletMain->HaveWatchOnly(script) && !pwalletMain->AddWatchOnly(script, 0 /* nCreateTime */)) + throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); + + if (isRedeemScript) { + if (!pwalletMain->HaveCScript(script) && !pwalletMain->AddCScript(script)) + throw JSONRPCError(RPC_WALLET_ERROR, "Error adding p2sh redeemScript to wallet"); + ImportAddress(CBitcoinAddress(CScriptID(script)), strLabel); + } else { + CTxDestination destination; + if (ExtractDestination(script, destination)) { + pwalletMain->SetAddressBook(destination, strLabel, "receive"); + } + } +} + +void ImportAddress(const CBitcoinAddress& address, const string& strLabel) +{ + CScript script = GetScriptForDestination(address.Get()); + ImportScript(script, strLabel, false); + // add to address book or update label + if (address.IsValid()) + pwalletMain->SetAddressBook(address.Get(), strLabel, "receive"); +} + +UniValue importaddress(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) + throw runtime_error( + "importaddress \"address\" ( \"label\" rescan p2sh )\n" + "\nAdds a script (in hex) or address that can be watched as if it were in your wallet but cannot be used to spend.\n" + "\nArguments:\n" + "1. \"script\" (string, required) The hex-encoded script (or address)\n" + "2. \"label\" (string, optional, default=\"\") An optional label\n" + "3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\n" + "4. p2sh (boolean, optional, default=false) Add the P2SH version of the script as well\n" + "\nNote: This call can take minutes to complete if rescan is true.\n" + "If you have the full public key, you should call importpubkey instead of this.\n" + "\nNote: If you import a non-standard raw script in hex form, outputs sending to it will be treated\n" + "as change, and not show up in many RPCs.\n" + "\nExamples:\n" + "\nImport a script with rescan\n" + + HelpExampleCli("importaddress", "\"myscript\"") + + "\nImport using a label without rescan\n" + + HelpExampleCli("importaddress", "\"myscript\" \"testing\" false") + + "\nAs a JSON-RPC call\n" + + HelpExampleRpc("importaddress", "\"myscript\", \"testing\", false") + ); + + + string strLabel = ""; + if (request.params.size() > 1) + strLabel = request.params[1].get_str(); + + // Whether to perform rescan after import + bool fRescan = true; + if (request.params.size() > 2) + fRescan = request.params[2].get_bool(); + + if (fRescan && fPruneMode) + throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode"); + + // Whether to import a p2sh version, too + bool fP2SH = false; + if (request.params.size() > 3) + fP2SH = request.params[3].get_bool(); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + CBitcoinAddress address(request.params[0].get_str()); + if (address.IsValid()) { + if (fP2SH) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot use the p2sh flag with an address - use a script instead"); + ImportAddress(address, strLabel); + } else if (IsHex(request.params[0].get_str())) { + std::vector data(ParseHex(request.params[0].get_str())); + ImportScript(CScript(data.begin(), data.end()), strLabel, fP2SH); + } else { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Ipchain address or script"); + } + + if (fRescan) + { + pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true); + pwalletMain->ReacceptWalletTransactions(); + } + + return NullUniValue; +} + +UniValue importprunedfunds(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() != 2) + throw runtime_error( + "importprunedfunds\n" + "\nImports funds without rescan. Corresponding address or script must previously be included in wallet. Aimed towards pruned wallets. The end-user is responsible to import additional transactions that subsequently spend the imported outputs or rescan after the point in the blockchain the transaction is included.\n" + "\nArguments:\n" + "1. \"rawtransaction\" (string, required) A raw transaction in hex funding an already-existing address in wallet\n" + "2. \"txoutproof\" (string, required) The hex output from gettxoutproof that contains the transaction\n" + ); + + CMutableTransaction tx; + if (!DecodeHexTx(tx, request.params[0].get_str())) + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); + uint256 hashTx = tx.GetHash(); + CWalletTx wtx(pwalletMain, MakeTransactionRef(std::move(tx))); + + CDataStream ssMB(ParseHexV(request.params[1], "proof"), SER_NETWORK, PROTOCOL_VERSION); + CMerkleBlock merkleBlock; + ssMB >> merkleBlock; + + //Search partial merkle tree in proof for our transaction and index in valid block + vector vMatch; + vector vIndex; + unsigned int txnIndex = 0; + if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) == merkleBlock.header.hashMerkleRoot) { + + LOCK(cs_main); + + if (!mapBlockIndex.count(merkleBlock.header.GetHash()) || !chainActive.Contains(mapBlockIndex[merkleBlock.header.GetHash()])) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain"); + + vector::const_iterator it; + if ((it = std::find(vMatch.begin(), vMatch.end(), hashTx))==vMatch.end()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction given doesn't exist in proof"); + } + + txnIndex = vIndex[it - vMatch.begin()]; + } + else { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Something wrong with merkleblock"); + } + + wtx.nIndex = txnIndex; + wtx.hashBlock = merkleBlock.header.GetHash(); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + if (pwalletMain->IsMine(wtx)) { + pwalletMain->AddToWallet(wtx, false); + return NullUniValue; + } + + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No addresses in wallet correspond to included transaction"); +} + +UniValue removeprunedfunds(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "removeprunedfunds \"txid\"\n" + "\nDeletes the specified transaction from the wallet. Meant for use with pruned wallets and as a companion to importprunedfunds. This will effect wallet balances.\n" + "\nArguments:\n" + "1. \"txid\" (string, required) The hex-encoded id of the transaction you are deleting\n" + "\nExamples:\n" + + HelpExampleCli("removeprunedfunds", "\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"") + + "\nAs a JSON-RPC call\n" + + HelpExampleRpc("removprunedfunds", "\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + uint256 hash; + hash.SetHex(request.params[0].get_str()); + vector vHash; + vHash.push_back(hash); + vector vHashOut; + + if(pwalletMain->ZapSelectTx(vHash, vHashOut) != DB_LOAD_OK) { + throw JSONRPCError(RPC_INTERNAL_ERROR, "Could not properly delete the transaction."); + } + + if(vHashOut.empty()) { + throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction does not exist in wallet."); + } + + return NullUniValue; +} + +UniValue importpubkey(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() < 1 || request.params.size() > 4) + throw runtime_error( + "importpubkey \"pubkey\" ( \"label\" rescan )\n" + "\nAdds a public key (in hex) that can be watched as if it were in your wallet but cannot be used to spend.\n" + "\nArguments:\n" + "1. \"pubkey\" (string, required) The hex-encoded public key\n" + "2. \"label\" (string, optional, default=\"\") An optional label\n" + "3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\n" + "\nNote: This call can take minutes to complete if rescan is true.\n" + "\nExamples:\n" + "\nImport a public key with rescan\n" + + HelpExampleCli("importpubkey", "\"mypubkey\"") + + "\nImport using a label without rescan\n" + + HelpExampleCli("importpubkey", "\"mypubkey\" \"testing\" false") + + "\nAs a JSON-RPC call\n" + + HelpExampleRpc("importpubkey", "\"mypubkey\", \"testing\", false") + ); + + + string strLabel = ""; + if (request.params.size() > 1) + strLabel = request.params[1].get_str(); + + // Whether to perform rescan after import + bool fRescan = true; + if (request.params.size() > 2) + fRescan = request.params[2].get_bool(); + + if (fRescan && fPruneMode) + throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode"); + + if (!IsHex(request.params[0].get_str())) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey must be a hex string"); + std::vector data(ParseHex(request.params[0].get_str())); + CPubKey pubKey(data.begin(), data.end()); + if (!pubKey.IsFullyValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey is not a valid public key"); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + ImportAddress(CBitcoinAddress(pubKey.GetID()), strLabel); + ImportScript(GetScriptForRawPubKey(pubKey), strLabel, false); + + if (fRescan) + { + pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true); + pwalletMain->ReacceptWalletTransactions(); + } + + return NullUniValue; +} + + +UniValue importwallet(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "importwallet \"filename\"\n" + "\nImports keys from a wallet dump file (see dumpwallet).\n" + "\nArguments:\n" + "1. \"filename\" (string, required) The wallet file\n" + "\nExamples:\n" + "\nDump the wallet\n" + + HelpExampleCli("dumpwallet", "\"test\"") + + "\nImport the wallet\n" + + HelpExampleCli("importwallet", "\"test\"") + + "\nImport using the json rpc call\n" + + HelpExampleRpc("importwallet", "\"test\"") + ); + + if (fPruneMode) + throw JSONRPCError(RPC_WALLET_ERROR, "Importing wallets is disabled in pruned mode"); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + EnsureWalletIsUnlocked(); + + ifstream file; + file.open(request.params[0].get_str().c_str(), std::ios::in | std::ios::ate); + if (!file.is_open()) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file"); + + int64_t nTimeBegin = chainActive.Tip()->GetBlockTime(); + + bool fGood = true; + + int64_t nFilesize = std::max((int64_t)1, (int64_t)file.tellg()); + file.seekg(0, file.beg); + + pwalletMain->ShowProgress(_("Importing..."), 0); // show progress dialog in GUI + while (file.good()) { + pwalletMain->ShowProgress("", std::max(1, std::min(99, (int)(((double)file.tellg() / (double)nFilesize) * 100)))); + std::string line; + std::getline(file, line); + if (line.empty() || line[0] == '#') + continue; + + std::vector vstr; + boost::split(vstr, line, boost::is_any_of(" ")); + if (vstr.size() < 2) + continue; + CBitcoinSecret vchSecret; + if (!vchSecret.SetString(vstr[0])) + continue; + CKey key = vchSecret.GetKey(); + CPubKey pubkey = key.GetPubKey(); + assert(key.VerifyPubKey(pubkey)); + CKeyID keyid = pubkey.GetID(); + if (pwalletMain->HaveKey(keyid)) { + LogPrintf("Skipping import of %s (key already present)\n", CBitcoinAddress(keyid).ToString()); + continue; + } + int64_t nTime = DecodeDumpTime(vstr[1]); + std::string strLabel; + bool fLabel = true; + for (unsigned int nStr = 2; nStr < vstr.size(); nStr++) { + if (boost::algorithm::starts_with(vstr[nStr], "#")) + break; + if (vstr[nStr] == "change=1") + fLabel = false; + if (vstr[nStr] == "reserve=1") + fLabel = false; + if (boost::algorithm::starts_with(vstr[nStr], "label=")) { + strLabel = DecodeDumpString(vstr[nStr].substr(6)); + fLabel = true; + } + } + LogPrintf("Importing %s...\n", CBitcoinAddress(keyid).ToString()); + if (!pwalletMain->AddKeyPubKey(key, pubkey)) { + fGood = false; + continue; + } + pwalletMain->mapKeyMetadata[keyid].nCreateTime = nTime; + if (fLabel) + pwalletMain->SetAddressBook(keyid, strLabel, "receive"); + nTimeBegin = std::min(nTimeBegin, nTime); + } + file.close(); + pwalletMain->ShowProgress("", 100); // hide progress dialog in GUI + + CBlockIndex *pindex = chainActive.Tip(); + while (pindex && pindex->pprev && pindex->GetBlockTime() > nTimeBegin - 7200) + pindex = pindex->pprev; + + pwalletMain->UpdateTimeFirstKey(nTimeBegin); + + LogPrintf("Rescanning last %i blocks\n", chainActive.Height() - pindex->nHeight + 1); + pwalletMain->ScanForWalletTransactions(pindex); + pwalletMain->MarkDirty(); + + if (!fGood) + throw JSONRPCError(RPC_WALLET_ERROR, "Error adding some keys to wallet"); + + return NullUniValue; +} + +UniValue dumpprivkey(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "dumpprivkey \"address\"\n" + "\nReveals the private key corresponding to 'address'.\n" + "Then the importprivkey can be used with this output\n" + "\nArguments:\n" + "1. \"address\" (string, required) The ipchain address for the private key\n" + "\nResult:\n" + "\"key\" (string) The private key\n" + "\nExamples:\n" + + HelpExampleCli("dumpprivkey", "\"myaddress\"") + + HelpExampleCli("importprivkey", "\"mykey\"") + + HelpExampleRpc("dumpprivkey", "\"myaddress\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + EnsureWalletIsUnlocked(); + + string strAddress = request.params[0].get_str(); + CBitcoinAddress address; + if (!address.SetString(strAddress)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Ipchain address"); + CKeyID keyID; + if (!address.GetKeyID(keyID)) + throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key"); + CKey vchSecret; + if (!pwalletMain->GetKey(keyID, vchSecret)) + throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + strAddress + " is not known"); + return CBitcoinSecret(vchSecret).ToString(); +} + + +UniValue dumpwallet(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() != 1) + throw runtime_error( + "dumpwallet \"filename\"\n" + "\nDumps all wallet keys in a human-readable format.\n" + "\nArguments:\n" + "1. \"filename\" (string, required) The filename\n" + "\nExamples:\n" + + HelpExampleCli("dumpwallet", "\"test\"") + + HelpExampleRpc("dumpwallet", "\"test\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + EnsureWalletIsUnlocked(); + + ofstream file; + file.open(request.params[0].get_str().c_str()); + if (!file.is_open()) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file"); + + std::map mapKeyBirth; + std::set setKeyPool; + pwalletMain->GetKeyBirthTimes(mapKeyBirth); + pwalletMain->GetAllReserveKeys(setKeyPool); + + // sort time/key pairs + std::vector > vKeyBirth; + for (const auto& entry : mapKeyBirth) { + if (const CKeyID* keyID = boost::get(&entry.first)) { // set and test + vKeyBirth.push_back(std::make_pair(entry.second, *keyID)); + } + } + mapKeyBirth.clear(); + std::sort(vKeyBirth.begin(), vKeyBirth.end()); + + // produce output + file << strprintf("# Wallet dump created by IPChain %s\n", CLIENT_BUILD); + file << strprintf("# * Created on %s\n", EncodeDumpTime(GetTime())); + file << strprintf("# * Best block at time of backup was %i (%s),\n", chainActive.Height(), chainActive.Tip()->GetBlockHash().ToString()); + file << strprintf("# mined on %s\n", EncodeDumpTime(chainActive.Tip()->GetBlockTime())); + file << "\n"; + + // add the base58check encoded extended master if the wallet uses HD + CKeyID masterKeyID = pwalletMain->GetHDChain().masterKeyID; + if (!masterKeyID.IsNull()) + { + CKey key; + if (pwalletMain->GetKey(masterKeyID, key)) + { + CExtKey masterKey; + masterKey.SetMaster(key.begin(), key.size()); + + CBitcoinExtKey b58extkey; + b58extkey.SetKey(masterKey); + + file << "# extended private masterkey: " << b58extkey.ToString() << "\n\n"; + } + } + for (std::vector >::const_iterator it = vKeyBirth.begin(); it != vKeyBirth.end(); it++) { + const CKeyID &keyid = it->second; + std::string strTime = EncodeDumpTime(it->first); + std::string strAddr = CBitcoinAddress(keyid).ToString(); + CKey key; + if (pwalletMain->GetKey(keyid, key)) { + file << strprintf("%s %s ", CBitcoinSecret(key).ToString(), strTime); + if (pwalletMain->mapAddressBook.count(keyid)) { + file << strprintf("label=%s", EncodeDumpString(pwalletMain->mapAddressBook[keyid].name)); + } else if (keyid == masterKeyID) { + file << "hdmaster=1"; + } else if (setKeyPool.count(keyid)) { + file << "reserve=1"; + } else if (pwalletMain->mapKeyMetadata[keyid].hdKeypath == "m") { + file << "inactivehdmaster=1"; + } else { + file << "change=1"; + } + file << strprintf(" # addr=%s%s\n", strAddr, (pwalletMain->mapKeyMetadata[keyid].hdKeypath.size() > 0 ? " hdkeypath="+pwalletMain->mapKeyMetadata[keyid].hdKeypath : "")); + } + } + file << "\n"; + file << "# End of dump\n"; + file.close(); + return NullUniValue; +} + + +UniValue ProcessImport(const UniValue& data, const int64_t timestamp) +{ + try { + bool success = false; + + // Required fields. + const UniValue& scriptPubKey = data["scriptPubKey"]; + + // Should have script or JSON with "address". + if (!(scriptPubKey.getType() == UniValue::VOBJ && scriptPubKey.exists("address")) && !(scriptPubKey.getType() == UniValue::VSTR)) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid scriptPubKey"); + } + + // Optional fields. + const string& strRedeemScript = data.exists("redeemscript") ? data["redeemscript"].get_str() : ""; + const UniValue& pubKeys = data.exists("pubkeys") ? data["pubkeys"].get_array() : UniValue(); + const UniValue& keys = data.exists("keys") ? data["keys"].get_array() : UniValue(); + const bool& internal = data.exists("internal") ? data["internal"].get_bool() : false; + const bool& watchOnly = data.exists("watchonly") ? data["watchonly"].get_bool() : false; + const string& label = data.exists("label") && !internal ? data["label"].get_str() : ""; + + bool isScript = scriptPubKey.getType() == UniValue::VSTR; + bool isP2SH = strRedeemScript.length() > 0; + const string& output = isScript ? scriptPubKey.get_str() : scriptPubKey["address"].get_str(); + + // Parse the output. + CScript script; + CBitcoinAddress address; + + if (!isScript) { + address = CBitcoinAddress(output); + if (!address.IsValid()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); + } + script = GetScriptForDestination(address.Get()); + } else { + if (!IsHex(output)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid scriptPubKey"); + } + + std::vector vData(ParseHex(output)); + script = CScript(vData.begin(), vData.end()); + } + + // Watchonly and private keys + if (watchOnly && keys.size()) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Incompatibility found between watchonly and keys"); + } + + // Internal + Label + if (internal && data.exists("label")) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Incompatibility found between internal and label"); + } + + // Not having Internal + Script + if (!internal && isScript) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Internal must be set for hex scriptPubKey"); + } + + // Keys / PubKeys size check. + if (!isP2SH && (keys.size() > 1 || pubKeys.size() > 1)) { // Address / scriptPubKey + throw JSONRPCError(RPC_INVALID_PARAMETER, "More than private key given for one address"); + } + + // Invalid P2SH redeemScript + if (isP2SH && !IsHex(strRedeemScript)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid redeem script"); + } + + // Process. // + + // P2SH + if (isP2SH) { + // Import redeem script. + std::vector vData(ParseHex(strRedeemScript)); + CScript redeemScript = CScript(vData.begin(), vData.end()); + + // Invalid P2SH address + if (!script.IsPayToScriptHash()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid P2SH address / script"); + } + + pwalletMain->MarkDirty(); + + if (!pwalletMain->HaveWatchOnly(redeemScript) && !pwalletMain->AddWatchOnly(redeemScript, timestamp)) { + throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); + } + + if (!pwalletMain->HaveCScript(redeemScript) && !pwalletMain->AddCScript(redeemScript)) { + throw JSONRPCError(RPC_WALLET_ERROR, "Error adding p2sh redeemScript to wallet"); + } + + CBitcoinAddress redeemAddress = CBitcoinAddress(CScriptID(redeemScript)); + CScript redeemDestination = GetScriptForDestination(redeemAddress.Get()); + + if (::IsMine(*pwalletMain, redeemDestination) == ISMINE_SPENDABLE) { + throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script"); + } + + pwalletMain->MarkDirty(); + + if (!pwalletMain->HaveWatchOnly(redeemDestination) && !pwalletMain->AddWatchOnly(redeemDestination, timestamp)) { + throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); + } + + // add to address book or update label + if (address.IsValid()) { + pwalletMain->SetAddressBook(address.Get(), label, "receive"); + } + + // Import private keys. + if (keys.size()) { + for (size_t i = 0; i < keys.size(); i++) { + const string& privkey = keys[i].get_str(); + + CBitcoinSecret vchSecret; + bool fGood = vchSecret.SetString(privkey); + + if (!fGood) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key encoding"); + } + + CKey key = vchSecret.GetKey(); + + if (!key.IsValid()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range"); + } + + CPubKey pubkey = key.GetPubKey(); + assert(key.VerifyPubKey(pubkey)); + + CKeyID vchAddress = pubkey.GetID(); + pwalletMain->MarkDirty(); + pwalletMain->SetAddressBook(vchAddress, label, "receive"); + + if (pwalletMain->HaveKey(vchAddress)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Already have this key"); + } + + pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = timestamp; + + if (!pwalletMain->AddKeyPubKey(key, pubkey)) { + throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet"); + } + + pwalletMain->UpdateTimeFirstKey(timestamp); + } + } + + success = true; + } else { + // Import public keys. + if (pubKeys.size() && keys.size() == 0) { + const string& strPubKey = pubKeys[0].get_str(); + + if (!IsHex(strPubKey)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey must be a hex string"); + } + + std::vector vData(ParseHex(strPubKey)); + CPubKey pubKey(vData.begin(), vData.end()); + + if (!pubKey.IsFullyValid()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey is not a valid public key"); + } + + CBitcoinAddress pubKeyAddress = CBitcoinAddress(pubKey.GetID()); + + // Consistency check. + if (!isScript && !(pubKeyAddress.Get() == address.Get())) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed"); + } + + // Consistency check. + if (isScript) { + CBitcoinAddress scriptAddress; + CTxDestination destination; + + if (ExtractDestination(script, destination)) { + scriptAddress = CBitcoinAddress(destination); + if (!(scriptAddress.Get() == pubKeyAddress.Get())) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed"); + } + } + } + + CScript pubKeyScript = GetScriptForDestination(pubKeyAddress.Get()); + + if (::IsMine(*pwalletMain, pubKeyScript) == ISMINE_SPENDABLE) { + throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script"); + } + + pwalletMain->MarkDirty(); + + if (!pwalletMain->HaveWatchOnly(pubKeyScript) && !pwalletMain->AddWatchOnly(pubKeyScript, timestamp)) { + throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); + } + + // add to address book or update label + if (pubKeyAddress.IsValid()) { + pwalletMain->SetAddressBook(pubKeyAddress.Get(), label, "receive"); + } + + // TODO Is this necessary? + CScript scriptRawPubKey = GetScriptForRawPubKey(pubKey); + + if (::IsMine(*pwalletMain, scriptRawPubKey) == ISMINE_SPENDABLE) { + throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script"); + } + + pwalletMain->MarkDirty(); + + if (!pwalletMain->HaveWatchOnly(scriptRawPubKey) && !pwalletMain->AddWatchOnly(scriptRawPubKey, timestamp)) { + throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); + } + + success = true; + } + + // Import private keys. + if (keys.size()) { + const string& strPrivkey = keys[0].get_str(); + + // Checks. + CBitcoinSecret vchSecret; + bool fGood = vchSecret.SetString(strPrivkey); + + if (!fGood) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key encoding"); + } + + CKey key = vchSecret.GetKey(); + if (!key.IsValid()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range"); + } + + CPubKey pubKey = key.GetPubKey(); + assert(key.VerifyPubKey(pubKey)); + + CBitcoinAddress pubKeyAddress = CBitcoinAddress(pubKey.GetID()); + + // Consistency check. + if (!isScript && !(pubKeyAddress.Get() == address.Get())) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed"); + } + + // Consistency check. + if (isScript) { + CBitcoinAddress scriptAddress; + CTxDestination destination; + + if (ExtractDestination(script, destination)) { + scriptAddress = CBitcoinAddress(destination); + if (!(scriptAddress.Get() == pubKeyAddress.Get())) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed"); + } + } + } + + CKeyID vchAddress = pubKey.GetID(); + pwalletMain->MarkDirty(); + pwalletMain->SetAddressBook(vchAddress, label, "receive"); + + if (pwalletMain->HaveKey(vchAddress)) { + return false; + } + + pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = timestamp; + + if (!pwalletMain->AddKeyPubKey(key, pubKey)) { + throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet"); + } + + pwalletMain->UpdateTimeFirstKey(timestamp); + + success = true; + } + + // Import scriptPubKey only. + if (pubKeys.size() == 0 && keys.size() == 0) { + if (::IsMine(*pwalletMain, script) == ISMINE_SPENDABLE) { + throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script"); + } + + pwalletMain->MarkDirty(); + + if (!pwalletMain->HaveWatchOnly(script) && !pwalletMain->AddWatchOnly(script, timestamp)) { + throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); + } + + if (scriptPubKey.getType() == UniValue::VOBJ) { + // add to address book or update label + if (address.IsValid()) { + pwalletMain->SetAddressBook(address.Get(), label, "receive"); + } + } + + success = true; + } + } + + UniValue result = UniValue(UniValue::VOBJ); + result.pushKV("success", UniValue(success)); + return result; + } catch (const UniValue& e) { + UniValue result = UniValue(UniValue::VOBJ); + result.pushKV("success", UniValue(false)); + result.pushKV("error", e); + return result; + } catch (...) { + UniValue result = UniValue(UniValue::VOBJ); + result.pushKV("success", UniValue(false)); + result.pushKV("error", JSONRPCError(RPC_MISC_ERROR, "Missing required fields")); + return result; + } +} + +int64_t GetImportTimestamp(const UniValue& data, int64_t now) +{ + if (data.exists("timestamp")) { + const UniValue& timestamp = data["timestamp"]; + if (timestamp.isNum()) { + return timestamp.get_int64(); + } else if (timestamp.isStr() && timestamp.get_str() == "now") { + return now; + } + throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Expected number or \"now\" timestamp value for key. got type %s", uvTypeName(timestamp.type()))); + } + throw JSONRPCError(RPC_TYPE_ERROR, "Missing required timestamp field for key"); +} + +UniValue importmulti(const JSONRPCRequest& mainRequest) +{ + // clang-format off + if (mainRequest.fHelp || mainRequest.params.size() < 1 || mainRequest.params.size() > 2) + throw runtime_error( + "importmulti \"requests\" \"options\"\n\n" + "Import addresses/scripts (with private or public keys, redeem script (P2SH)), rescanning all addresses in one-shot-only (rescan can be disabled via options).\n\n" + "Arguments:\n" + "1. requests (array, required) Data to be imported\n" + " [ (array of json objects)\n" + " {\n" + " \"scriptPubKey\": \"