Fabcoin Core  0.16.2
P2P Digital Currency
callcontract.cpp
Go to the documentation of this file.
1 #include <callcontract.h>
2 #include <ui_callcontract.h>
3 #include <platformstyle.h>
4 #include <walletmodel.h>
5 #include <clientmodel.h>
6 #include <guiconstants.h>
7 #include <rpcconsole.h>
8 #include <execrpccommand.h>
9 #include <abifunctionfield.h>
10 #include <contractabi.h>
11 #include <tabbarinfo.h>
12 #include <contractresult.h>
13 #include <contractbookpage.h>
14 #include <editcontractinfodialog.h>
15 #include <contracttablemodel.h>
16 #include <styleSheet.h>
17 #include <guiutil.h>
18 #include <QClipboard>
19 
20 namespace CallContract_NS
21 {
22 // Contract data names
23 static const QString PRC_COMMAND = "callcontract";
24 static const QString PARAM_ADDRESS = "address";
25 static const QString PARAM_DATAHEX = "datahex";
26 static const QString PARAM_SENDER = "sender";
27 }
28 using namespace CallContract_NS;
29 
30 CallContract::CallContract(const PlatformStyle *platformStyle, QWidget *parent) :
31  QWidget(parent),
32  ui(new Ui::CallContract),
33  m_model(0),
34  m_clientModel(0),
35  m_contractModel(0),
36  m_execRPCCommand(0),
37  m_ABIFunctionField(0),
38  m_contractABI(0),
39  m_tabInfo(0),
40  m_results(1)
41 {
42  m_platformStyle = platformStyle;
43  // Setup ui components
44  ui->setupUi(this);
45  ui->saveInfoButton->setIcon(platformStyle->MultiStatesIcon(":/icons/filesave", PlatformStyle::PushButton));
46  ui->loadInfoButton->setIcon(platformStyle->MultiStatesIcon(":/icons/address-book", PlatformStyle::PushButton));
47  ui->pasteAddressButton->setIcon(platformStyle->MultiStatesIcon(":/icons/editpaste", PlatformStyle::PushButton));
48  // Format tool buttons
50 
51  // Set stylesheet
52  SetObjectStyleSheet(ui->pushButtonClearAll, StyleSheetNames::ButtonBlack);
53 
56 
57  ui->labelContractAddress->setToolTip(tr("The account address."));
58  ui->labelSenderAddress->setToolTip(tr("The sender address hex string."));
59  ui->pushButtonCallContract->setEnabled(false);
61 
63  m_tabInfo->addTab(0, tr("Call Contract"));
64 
65  // Create new PRC command line interface
66  QStringList lstMandatory;
67  lstMandatory.append(PARAM_ADDRESS);
68  lstMandatory.append(PARAM_DATAHEX);
69  QStringList lstOptional;
70  lstOptional.append(PARAM_SENDER);
71  QMap<QString, QString> lstTranslations;
72  lstTranslations[PARAM_ADDRESS] = ui->labelContractAddress->text();
73  lstTranslations[PARAM_SENDER] = ui->labelSenderAddress->text();
74  m_execRPCCommand = new ExecRPCCommand(PRC_COMMAND, lstMandatory, lstOptional, lstTranslations, this);
75  m_contractABI = new ContractABI();
76 
77  // Connect signals with slots
78  connect(ui->pushButtonClearAll, SIGNAL(clicked()), SLOT(on_clearAllClicked()));
79  connect(ui->pushButtonCallContract, SIGNAL(clicked()), SLOT(on_callContractClicked()));
80  connect(ui->lineEditContractAddress, SIGNAL(textChanged(QString)), SLOT(on_updateCallContractButton()));
81  connect(ui->textEditInterface, SIGNAL(textChanged()), SLOT(on_newContractABI()));
82  connect(ui->stackedWidget, SIGNAL(currentChanged(int)), SLOT(on_updateCallContractButton()));
83  connect(ui->saveInfoButton, SIGNAL(clicked()), SLOT(on_saveInfoClicked()));
84  connect(ui->loadInfoButton, SIGNAL(clicked()), SLOT(on_loadInfoClicked()));
85  connect(ui->pasteAddressButton, SIGNAL(clicked()), SLOT(on_pasteAddressClicked()));
86  connect(ui->lineEditContractAddress, SIGNAL(textChanged(QString)), SLOT(on_contractAddressChanged()));
87 
88  // Set contract address validator
89  QRegularExpression regEx;
90  regEx.setPattern(paternAddress);
91  QRegularExpressionValidator *addressValidatr = new QRegularExpressionValidator(ui->lineEditContractAddress);
92  addressValidatr->setRegularExpression(regEx);
93  ui->lineEditContractAddress->setCheckValidator(addressValidatr);
94 }
95 
97 {
98  delete m_contractABI;
99  delete ui;
100 }
101 
103 {
104  m_clientModel = _clientModel;
105 
106  if (m_clientModel)
107  {
108  connect(m_clientModel, SIGNAL(tipChanged()), this, SLOT(on_numBlocksChanged()));
110  }
111 }
112 
114 {
115  m_model = _model;
117 }
118 
120 {
123 }
124 
126 {
128  return ui->textEditInterface->isValid();
129 }
130 
132 {
133  bool dataValid = true;
134 
136  dataValid = false;
137  if(!isValidInterfaceABI())
138  dataValid = false;
140  dataValid = false;
142  dataValid = false;
143 
144  return dataValid;
145 }
146 
148 {
149  ui->lineEditContractAddress->setText(address);
150  ui->lineEditContractAddress->setFocus();
151 }
152 
154 {
156  ui->lineEditSenderAddress->setCurrentIndex(-1);
158  m_tabInfo->clear();
159 }
160 
162 {
163  if(isDataValid())
164  {
165  // Initialize variables
166  QMap<QString, QString> lstParams;
167  QVariant result;
168  QString errorMessage;
169  QString resultJson;
171 
172  // Append params to the list
173  ExecRPCCommand::appendParam(lstParams, PARAM_ADDRESS, ui->lineEditContractAddress->text());
174  ExecRPCCommand::appendParam(lstParams, PARAM_DATAHEX, toDataHex(func, errorMessage));
175  ExecRPCCommand::appendParam(lstParams, PARAM_SENDER, ui->lineEditSenderAddress->currentText());
176 
177  // Execute RPC command line
178  if(errorMessage.isEmpty() && m_execRPCCommand->exec(lstParams, result, resultJson, errorMessage))
179  {
180  ContractResult *widgetResult = new ContractResult(ui->stackedWidget);
182  ui->stackedWidget->addWidget(widgetResult);
183  int position = ui->stackedWidget->count() - 1;
184  m_results = position == 1 ? 1 : m_results + 1;
185 
186  m_tabInfo->addTab(position, tr("Result %1").arg(m_results));
187  m_tabInfo->setCurrent(position);
188  }
189  else
190  {
191  QMessageBox::warning(this, tr("Call contract"), errorMessage);
192  }
193  }
194 }
195 
197 {
198  if(m_clientModel)
199  {
201  }
202 }
203 
205 {
207  bool enabled = func != -1;
208  if(ui->lineEditContractAddress->text().isEmpty())
209  {
210  enabled = false;
211  }
212  enabled &= ui->stackedWidget->currentIndex() == 0;
213 
214  ui->pushButtonCallContract->setEnabled(enabled);
215 }
216 
218 {
219  std::string json_data = ui->textEditInterface->toPlainText().toStdString();
220  if(!m_contractABI->loads(json_data))
221  {
222  m_contractABI->clean();
224  }
225  else
226  {
228  }
230 
232 }
233 
235 {
236  if(!m_contractModel)
237  return;
238 
239  bool valid = true;
240 
242  valid = false;
243 
244  if(!isValidInterfaceABI())
245  valid = false;
246 
247  if(!valid)
248  return;
249 
250  QString contractAddress = ui->lineEditContractAddress->text();
251  int row = m_contractModel->lookupAddress(contractAddress);
253  EditContractInfoDialog dlg(dlgMode, this);
256  {
257  dlg.loadRow(row);
258  }
259  dlg.setAddress(ui->lineEditContractAddress->text());
260  dlg.setABI(ui->textEditInterface->toPlainText());
261  if(dlg.exec())
262  {
263  ui->lineEditContractAddress->setText(dlg.getAddress());
264  ui->textEditInterface->setText(dlg.getABI());
266  }
267 }
268 
270 {
273  if(dlg.exec())
274  {
275  ui->lineEditContractAddress->setText(dlg.getAddressValue());
277  }
278 }
279 
281 {
282  setContractAddress(QApplication::clipboard()->text());
283 }
284 
286 {
288  {
289  QString contractAddress = ui->lineEditContractAddress->text();
290  if(m_contractModel->lookupAddress(contractAddress) > -1)
291  {
292  QString contractAbi = m_contractModel->abiForAddress(contractAddress);
293  if(ui->textEditInterface->toPlainText() != contractAbi)
294  {
295  ui->textEditInterface->setText(m_contractModel->abiForAddress(contractAddress));
296  }
297  }
298  }
299 }
300 
301 QString CallContract::toDataHex(int func, QString& errorMessage)
302 {
303  if(func == -1 || m_ABIFunctionField == NULL || m_contractABI == NULL)
304  {
305  return "";
306  }
307 
308  std::string strData;
309  std::vector<std::vector<std::string>> values = m_ABIFunctionField->getValuesVector();
310  FunctionABI function = m_contractABI->functions[func];
311  std::vector<ParameterABI::ErrorType> errors;
312 
313  if(function.abiIn(values, strData, errors))
314  {
315  return QString::fromStdString(strData);
316  }
317  else
318  {
319  errorMessage = function.errorMessage(errors, true);
320  }
321  return "";
322 }
QLabel * labelContractAddress
QToolButton * pasteAddressButton
#define SetObjectStyleSheet(object, name)
Definition: styleSheet.h:10
const QString & getAddressValue() const
int lookupAddress(const QString &address) const
void on_loadInfoClicked()
Dialog for editing a contract information.
const PlatformStyle * m_platformStyle
Definition: callcontract.h:59
void setupUi(QWidget *CallContract)
QToolButton * loadInfoButton
void setABI(const QString &ABI)
void setModel(WalletModel *model)
void on_newContractABI()
CallContract(const PlatformStyle *platformStyle, QWidget *parent=0)
QValidatedLineEdit * lineEditContractAddress
void on_pasteAddressClicked()
void setResultData(QVariant result, FunctionABI function, QList< QStringList > paramValues, ContractTxType type)
WalletModel * m_model
Definition: callcontract.h:52
ContractTableModel * getContractTableModel()
QLabel * labelSenderAddress
QPushButton * pushButtonClearAll
#define paternAddress
Definition: contractabi.h:11
ExecRPCCommand * m_execRPCCommand
Definition: callcontract.h:55
ClientModel * m_clientModel
Definition: callcontract.h:53
void setIsValidManually(bool value)
std::vector< FunctionABI > functions
Definition: contractabi.h:205
Ui::CallContract * ui
Definition: callcontract.h:51
void on_refresh()
on_refresh Refresh the list of addresses
std::vector< std::vector< std::string > > getValuesVector()
getValuesVector Get params values vector List of all parameters that can be sent to a function...
QScrollArea * scrollAreaFunction
void on_updateCallContractButton()
bool exec(const QMap< QString, QString > &params, QVariant &result, QString &resultJson, QString &errorMessage)
exec Execute the RPC command
bool addTab(int index, const QString &name)
addTab Add new tab
Definition: tabbarinfo.cpp:14
QString abiForAddress(const QString &address) const
bytes abiIn(std::string _id, T const &..._t)
Definition: ABI.h:64
void setContractABI(ContractABI *contractABI)
setContractABI Set the contract ABI (list of functions from the contract)
void setCurrent(int index)
setCurrent Set current index
Definition: tabbarinfo.cpp:95
ContractTableModel * m_contractModel
Definition: callcontract.h:54
QStackedWidget * stackedWidget
void on_callContractClicked()
bool isValidInterfaceABI()
AddressField * lineEditSenderAddress
void setClientModel(ClientModel *clientModel)
int getSelectedFunction() const
getSelectedFunction Get the ABI for the selected function from the contract
void on_saveInfoClicked()
void setModel(ContractTableModel *model)
bool isValidAddress()
QToolButton * saveInfoButton
void clear()
clear Remove all tabs except the first one which is not closable
Definition: tabbarinfo.cpp:101
Model for Fabcoin network client.
Definition: clientmodel.h:38
void setModel(ContractTableModel *model)
The ABIFunctionField class ABI functions widget.
void on_numBlocksChanged()
The ExecRPCCommand class Execution of RPC command line.
QList< QStringList > getParamsValues()
getParamsValues Get the values of the whole list of input parameters for the selected function ...
QIcon MultiStatesIcon(const QString &resourcename, StateType type=NavBar, QColor color=Qt::white, QColor colorAlt=0x2d2d2d) const
Get multi-states icon.
QPushButton * pushButtonCallContract
Interface to Fabcoin wallet from Qt view code.
Definition: walletmodel.h:103
virtual QString currentText() const
currentText Get the current text
void setComboBoxEditable(bool editable)
bool isDataValid()
void setCheckValidator(const QValidator *v)
The TabBarInfo class Class for informations about tabs.
Definition: tabbarinfo.h:13
static void appendParam(QMap< QString, QString > &params, const QString &paramName, const QString &paramValue)
appendParam Append paramether to the list
TabBarInfo * m_tabInfo
Definition: callcontract.h:58
QValidatedTextEdit * textEditInterface
bool loads(const std::string &json_data)
Definition: contractabi.cpp:54
void on_contractAddressChanged()
void on_clearAllClicked()
struct evm_uint160be address(struct evm_env *env)
Definition: capi.c:13
void formatToolButtons(QToolButton *btn1, QToolButton *btn2, QToolButton *btn3)
Definition: guiutil.cpp:989
bool isValidContractAddress()
ABIFunctionField * m_ABIFunctionField
Definition: callcontract.h:56
void setAddress(const QString &address)
void setContractAddress(const QString &address)
QString toDataHex(int func, QString &errorMessage)
ContractABI * m_contractABI
Definition: callcontract.h:57