上次写交易的文章是2个月以前了。这两个月,断断续续,进展很慢。
本来的计划是先了解以下比特币的交易流程和原理。然后发送一个比特币,在用单步执行的方法,跟踪交易流程,这样,就可以从根本上掌握比特币的交易流程了。但在实际的操作中发现,难度很大。不懂linux,所以,熟悉linux环境,搭建测试链,查找交易的相关源码,对于我来说,每一步都举步维艰。主要是没有太多大块的时间去学习。而且每次看一点学一点,过一点时间又忘记一点。反反复复的。耐心都被磨没了。这次改变计划,直接从源码开始,还是一点一点的啃源码。源码啃完,再回过去,总结归纳。也许会更好。
我们交易比特币都是设置好交易值和地址,然后点击按钮发送,那么有没有这个关于按钮的函数呢。还真有。
on_sendButton_clicked 点击发送比特币按钮的函数,函数在sendcoinsdialog.cpp中。
下面是该函数交易流程图。
下面会逐步分析每个功能块的代码。
1 检查model是否有效?
if(!model || !model->getOptionsModel())
return;
2 检查entry是否有效
for(int i = 0; i < ui->entries->count(); ++i)
{
SendCoinsEntry *entry =qobject_cast(ui->entries->itemAt(i)->widget());
if(entry)
{
if(entry->validate())
{
recipients.append(entry->getValue());
}
else
{
valid = false;
}
}
}
if(!valid || recipients.isEmpty())
{
return;
}
Btc客户端可以同时发送几个输出,如下图。
每个输出都是一个entry。For循环是检测每个entry是否有效,如果存在任何一个无效的entry,则程序返回,不在执行。
entry是类SendCoinsEntry。该类定义在sendcoinsentry.h库文件中:
/**
* A single entry in the dialog for sendingbitcoins.
* Stacked widget, with different UIs forpayment requests
* with a strong payee identity.
*/
根据注释,可以看出,entry是发送btc的一个对话框。
For循环中的相关函数:
1 Validate()函数
boolSendCoinsEntry::validate()
{
if (!model)
return false;
// Check input validity
bool retval = true;
//检查发送请求是否有效
// Skip checks for payment request
if(recipient.paymentRequest.IsInitialized())
return retval;
//检查地址是否有效
if(!model->validateAddress(ui->payTo->text()))
{
ui->payTo->setValid(false);
retval = false;
}
//检查发送的btc数额是否有效
if (!ui->payAmount->validate())
{
retval = false;
}
//不能发送0个btc
// Sending a zero amount is invalid
if (ui->payAmount->value(0) <= 0)
{
ui->payAmount->setValid(false);
retval = false;
}
//为避免攻击,拒绝小额发送
// Reject dust outputs:
if (retval &&GUIUtil::isDust(ui->payTo->text(), ui->payAmount->value())) {
ui->payAmount->setValid(false);
retval = false;
}
return retval;
}
2 getValue()函数
SendCoinsRecipientSendCoinsEntry::getValue()
{
//检查发送请求是否有效
// Payment request
if(recipient.paymentRequest.IsInitialized())
return recipient;
// Normal payment
recipient.address =ui->payTo->text(); //读取发送
recipient.label =ui->addAsLabel->text(); //读取标签
recipient.amount =ui->payAmount->value(); //读取发送金额
recipient.message =ui->messageTextLabel->text(); //读取消息
recipient.fSubtractFeeFromAmount =(ui->checkboxSubtractFeeFromAmount->checkState() == Qt::Checked);
return recipient;
}
本文由【区块链研习社】优质内容计划支持,更多关于区块链的深度好文,请点击[区块链研习社](http://www.jianshu.com/c/b17f09dc2831)
区块链研习社比特币源码研读班 electroman
以下是广告:
我们区块链研习社已创建“区块链研习社币圈交流”小密圈”,在小密圈中,我们将带领大家一起学习区块链的原理与投资,还将提供区块链基本原理解答、交易所注册与交易操作、ICO交易与操作、投资分析、风险分析等内容。
网友评论