1. 程式人生 > >交易是如何被建立和打包的2

交易是如何被建立和打包的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)

這個也算是核心函式對建立的交易記性提交。對交易建立函式解析完畢之後。咱對它進行解析。

好了,今天就到此吧。