交易是如何被创建和打包的2

Posted alfredzky

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了交易是如何被创建和打包的2相关的知识,希望对你有一定的参考价值。

趁着这时候同事还在给我准备测试数据,有点富余时间就先把第二篇章给写。开整

书接上文SendMoney(address.Get(), nAmount, fSubtractFeeFromAmount, wtx, fUseInstantSend, fUsePrivateSend);

参数都介绍过了,可以参照第一篇。

技术分享图片
 

截图不太好,大家可以自己去看下源码。

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"); //nValue就是你要给要别人发送的token,这里对它进行判断,小于0的会报无效的数量,如果大于钱包的余额,则会报出金额不足,不足以支付此次支出。

对金额检查完毕后

 // Parse Dash address 

 CScript scriptPubKey = GetScriptForDestination(address); // 有注释可知对你要发token的地址进行解析,解析成了脚本。

// Create and send the transaction      //由注释可以看到这是创建和发送事务

 CReserveKey reservekey(pwalletMain); // 从秘钥池申请一个私钥。大家可以去看下这个类

 CAmount nFeeRequired;                             // 这个变量就是用于本次交易的交易费

 std::string strError;                                         // 用于接收交易创建错误信息

 vector <CRecipient>vecSend;                 // 一个向量,里面存储的元素是CRecipient 。CRecipient是一个结构体

 int nChangePosRet = -1;                              // 默认设置为-1 创建交易的函数里面会解释,这里先过去。

CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount};// 对结构体对象recipient  进行初始化。

我们来看下 CRecipient 结构体,这个存储着接收方的信息。

struct CRecipient

{

    CScript scriptPubKey;                                // 用于创建接收方的公钥脚本

    CAmount nAmount;                                    // 接收token金额

    bool fSubtractFeeFromAmount;               // 交易费的递减金额 标志 

};

从上文我们看到,这个标志默认传入是false。

vecSend.push_back(recipient);// 把创建好的接收方信息,推入栈中,注意从可以看出是可以存在多个接收方的。创建好之后,推入栈中就可以了。

自此所有的准备工作,已经准备完毕。

if (!pwalletMain->CreateTransaction(vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet,

                                        strError, NULL, true, fUsePrivateSend ? ONLY_DENOMINATED : ALL_COINS, fUseInstantSend)) {

        if (!fSubtractFeeFromAmount && nValue + nFeeRequired > pwalletMain->GetBalance())

            strError = strprintf("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!", FormatMoney(nFeeRequired));

        throw JSONRPCError(RPC_WALLET_ERROR, strError);

    }

    if (!pwalletMain->CommitTransaction(wtxNew, reservekey, fUseInstantSend ? NetMsgType::TXLOCKREQUEST : NetMsgType::TX))

        throw JSONRPCError(RPC_WALLET_ERROR, "Error: The transaction was rejected! This might happen if some of the coins in

不好意思啊,这个屏幕真的是,报错信息我就不粘全了,大家自己去看下,也不是太重要。

最核心的函数就来。CreateTransaction(vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet,strError, NULL, true, fUsePrivateSend ? ONLY_DENOMINATED : ALL_COINS, fUseInstantSend))创建事务的也就是交易的函数。这里对参数作用简要介绍下。上文介绍过的,就不在介绍了 。

vecSend:用于存储接收方的信息的向量对象。

wtxNew:这次本次创建交易的对象,存储交易的信息

nChangePosRet:一个位置默认是-1

NULL:                    币的控制。原型 const CCoinControl *coinControl = NULL。

true                            是否签名。原型 bool sign = true。

报错信息很好理解,再次就不解释了。

CommitTransaction(wtxNew, reservekey, fUseInstantSend ? NetMsgType::TXLOCKREQUEST : NetMsgType::TX)

这个也算是核心函数对创建的交易记性提交。对交易创建函数解析完毕之后。咱对它进行解析。

好了,今天就到此吧。


以上是关于交易是如何被创建和打包的2的主要内容,如果未能解决你的问题,请参考以下文章

交易是如何被创建和打包的1

交易是如何被创建和打包的7

交易是如何被创建和打包的3

交易是如何被创建和打包的4

交易是如何被创建和打包的6

以太坊上交易异常Pending的处理方法