量子鏈賬戶抽象層分析

我們知道比特幣的余額模型是UTXO模型,以太坊是個賬戶余額模型。這點可以從各自的交易結(jié)構(gòu)里體現(xiàn)出來

而量子鏈打通了這兩個交易,實現(xiàn)了從UTXO模型到Balance模型的轉(zhuǎn)換。這個轉(zhuǎn)換過程稱為:賬戶抽象層(Account Abstract Layer, AAL)。

以太坊和比特幣交易結(jié)構(gòu)

這里我們說下從UTXO到Balance的轉(zhuǎn)換原理:

1.UTXO交易新增的腳本操作碼:Qtum 針對UTXO交易腳本新增了三個操作碼OP_CREATE,OP_CALL和OP_SPEND,目的是用于為UTXO和EVM賬戶模型之間的轉(zhuǎn)換提供操作支持。這些操作碼定義在opcodetype枚舉類型中(同比特幣在script.h中)。

2.量子鏈實現(xiàn)了一個自己的交易結(jié)構(gòu)QtumTransaction,并且繼承了以太坊的交易,同時擴展出用于生成UTXO結(jié)構(gòu)的nVout和version兩個字段 。(QtumTransaction.h)

3.實現(xiàn)QtumTxConverter類,也就是用于轉(zhuǎn)換的類及賬戶抽象層。(在validation.h中)

4.實現(xiàn)EthTransactionParams 結(jié)構(gòu)體,用于轉(zhuǎn)換過程中參數(shù)的存儲和傳遞。(在validation.h中)


新增opcode

OP_CREATE:用于智能合約的創(chuàng)建;OP_CALL用于合約的執(zhí)行;OP_SPEND用于合約余額的花費;

這些 OpCode的執(zhí)行同比特幣一樣也是在EvalScript()中判斷執(zhí)行的(在interpreter.cpp中)。相當于比特幣的虛擬機。

在EvalScript中的處理

從代碼中可以看到,對OP_CREATE,OP_CALL的處理就是將剩余代碼壓棧。為了識別這幾個操作符,Qtum擴展了在比特幣交易類(CTransaction)中增加了HasCreateOrCall()和HasOpSpend()函數(shù),用于新區(qū)塊中對mempool中的交易處理。

通過以上源碼可以看到OP_CREATE,OP_CALL對應的交易輸出,OP_SPEND對應的交易輸入也就是用于余額的花費。

現(xiàn)在我們就開始從源碼看下具體的轉(zhuǎn)換過程,代碼從validation.cpp中驗證函數(shù)(AcceptToMemoryPoolWorker)開始,從源碼可以看出,qtum就是在比特幣的源碼基礎上增加了HashCreateOrCall()的判斷。并進行了處理。

調(diào)用AAL層進行轉(zhuǎn)換

CheckSenderScript()是先檢查了解鎖腳本是否合法。核心轉(zhuǎn)換代碼在QtumTxConverter中的extractionQtumTransactions 函數(shù)中。

extractionQtumTransactions

可以看到這個函數(shù)是遍歷了交易輸出的鎖定腳本也就是智能合約代碼。

1。判斷是否有OP_CREATE和OP_CALL,通過receiveStack將腳本傳入堆棧,并判斷執(zhí)行結(jié)果

2。通過parseEthTXParams提取轉(zhuǎn)換到以太坊交易所需的參數(shù)。

3。通過createEthTX將參數(shù)轉(zhuǎn)入,并且轉(zhuǎn)換成QtumTransaction,我們知道QtumTransaction就是繼承自以太坊交易的。所以和EVM執(zhí)行相關的操作QtumTransaction類都支持。

以上三步的三個函數(shù)都在QtumTxConverter類中。具體文件是validation.cpp。

將腳本存入stack棧

上面代碼將傳進來的合約腳本通過EvalScript存入stack中。并進行了有效性判斷。下面是從stack中取參數(shù)。

提取轉(zhuǎn)換參數(shù)

以上代碼首先判斷如果opcode 為OP_CALL,則說明地址為vecAddr的合約已經(jīng)創(chuàng)建,因此直接轉(zhuǎn)換成EVM格式的地址receiveAddress,否則為OP_CREATE,對應合約的創(chuàng)建,沒有該字段,所以不做提取。接下來依次完成了data、gasPrice、gasLimit、VM version的提取,提取操作就是順序?qū)tack中的數(shù)據(jù)出棧就可以了。這些都是EVM執(zhí)行bytecode時必不可少的參數(shù)。


利用參數(shù)生成QtumTransaction

首先代碼etp.receiveAddress == dev::Address()判斷該合約是EVM狀態(tài)中沒有而需要新創(chuàng)建的還是EVM狀態(tài)已經(jīng)包含的合約,差別只在于合約地址。然后,QtumTransaction()構(gòu)造函數(shù)完成了部分的交易參數(shù)構(gòu)造,接下來的語句提取交易的發(fā)送者(sender),之后設置交易HASH。一個UTXO交易支持多個輸入和輸出,Qtum的AAL設計考慮到了這種情況,因此AAL支持一個交易輸出包含UTXO賬號和合約賬號,通過最后設置的nOut指示該交易的nOut輸出是發(fā)送到智能合約的(對應交易輸入所引用的utxo順序號COutPoint的n),所以該輸出將觸發(fā)合約執(zhí)行。這樣就按照EVM的賬號模型完成了交易的轉(zhuǎn)換。

好了,以上也是將原理和實現(xiàn)從源碼上分析了下,至于從Balance到UTXO的轉(zhuǎn)換,代碼還要細細分析。




作者:區(qū)塊鏈研習社比特幣源碼研讀班,black

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容