以太坊原始碼 交易(一)

2021-08-21 11:39:41 字數 3773 閱讀 5951

交易是區塊鏈中最基本也是最核心的乙個概念,在以太坊中,交易更是重中之重,因為以太坊是乙個智慧型合約平台,以太坊上的應用都是通過智慧型合約與區塊鏈進行互動,而智慧型合約的執行是由交易觸發的,沒有交易,智慧型合約就是一段死的**,可以說在以太坊中,一切都源於交易。下面就來看看在以太坊中交易是什麼樣的,交易裡面都有什麼。

core/types/transaction.go中定義了交易的資料結構:

type transaction struct
在這個結構體裡面只有乙個data字段,它是txdata型別的,其他的三個字段hashsizefrom是快取字段,txdata也是乙個結構體,它裡面定義了交易的具體的字段:

type txdata struct
各字段的含義如下:

注意:這裡並沒有乙個欄位來指明交易的傳送者,因為交易的傳送者位址可以從簽名中得到。

transaction.go中還定義了乙個jsontransaction結構體,這個結構體用於將交易進行json序列化和反序列化,具體的序列化和反序列化可以參照marshaljsonunmarshaljson函式。以太坊節點會向外部提供json rpc服務,供外部呼叫,rpc服務通過json格式傳輸資料,節點收到json資料後,會轉換成內部的資料結構來使用。jsontransaction結構體使用go語言的struct tag特性指定了內部資料結構與json資料各字段的對應關係,例如內部的accountnonce對應json的nonceamount對應json的value。web3.js的eth.gettransaction()eth.sendtransaction()使用的資料就是json格式的,根據這個結構體就可以知道在web3.js中交易的各個欄位與程式內部的各個欄位的對應關係。

type jsontransaction struct
注:payload這個欄位在eth.sendtransaction()中對應的是data字段,在eth.gettransaction()中對應的是input字段。

下面是計算交易hash的函式,它是先從快取tx.hash中取,如果取到,就直接返回,如果快取中沒有,就呼叫rlphash計算hash,然後把hash值加入到快取中。

// hash hashes the rlp encoding of tx.

// it uniquely identifies the transaction.

func (tx *transaction) hash() common.hash

v := rlphash(tx)

tx.hash.store(v)

return v

}

rlphash的**在core/types/block.go中:

func

rlphash(x

inte***ce{}) (h

common

.hash)

rlphash函式可以看出,計算hash的方法是先對交易進行rlp編碼,然後計算rlp編碼資料的hash,具體的hash演算法是keccak256

那麼到底是對交易中的哪些字段計算的hash呢?這就要看rlp.encode對哪些字段進行了編碼。rlp.encode**在rlp/encode.go中,不用看具體的實現,在注釋中有這麼一段:

// if the type implements the encoder inte***ce, encode calls

// encoderlp. this is true even for nil pointers, please see the

// documentation for encoder.

就是說如果乙個型別實現了encoder介面,那麼encode函式就會呼叫那個型別所實現的encoderlp函式。所以我們就要看transaction這個結構體是否實現了encoderlp函式。回到core/types/transaction.go中,可以看到transaction確實實現了encoderlp函式:

// decoderlp implements rlp.encoder

func (tx *transaction) encoderlp(w io.writer) error

從這可以看出交易的hash實際上是對tx.data進行hash計算得到的:txhash=keccak256(rlpencode(tx.data))

在原始碼中交易只有一種資料結構,如果非要給交易分個類的話,我認為交易可以分為三種:轉賬的交易、建立合約的交易、執行合約的交易。web3.js提供了傳送交易的介面:

web3.eth.sendtransaction(transactionobject [, callback])
引數是乙個物件,在傳送交易的時候指定不同的字段,區塊鏈節點就可以識別出對應型別的交易。

轉賬是最簡單的一種交易,這裡轉賬是指從乙個賬戶向另乙個賬戶傳送以太幣。傳送轉賬交易的時候只需要指定交易的傳送者、接收者、轉幣的數量。使用web3.js傳送轉賬交易應該像這樣:

web3.eth.sendtransaction();
value是轉移的以太幣數量,單位是wei,對應的是原始碼中的amount字段。to對應的是原始碼中的recipient

建立合約指的是將合約部署到區塊鏈上,這也是通過傳送交易來實現。在建立合約的交易中,to欄位要留空不填,在data欄位中指定合約的二進位制**,from欄位是交易的傳送者也是合約的建立者。

web3.eth.sendtransaction();
data字段對應的是原始碼中的payload字段。

呼叫合約中的方法,需要將交易的to字段指定為要呼叫的合約的位址,通過data字段指定要呼叫的方法以及向該方法傳遞的引數。

web3.eth.sendtransaction();
data字段需要特殊的編碼規則,具體細節可以參考ethereum contract abi。自己拼接欄位既不方便又容易出錯,所以一般都使用封裝好的sdk(比如web3.js)來呼叫合約。

以太坊原始碼分析 交易的執行

以太坊是乙個執行智慧型合約的平台,被稱作可程式設計的區塊鏈,允許使用者將編寫的智慧型合約部署在區塊鏈上執行。而執行合約的主體便是以太坊虛擬機器 evm 區塊 交易 合約 區塊鏈由區塊 block 組成,而區塊中打包一定數量的交易 transaction 交易可能是乙個單純的轉賬操作,也可能是呼叫乙個...

64 原始碼 以太坊交易簽名解析原始碼解讀

上篇文章 以太坊交易簽名過程原始碼解析 從原始碼角度分析了乙個合約呼叫的的簽名過程,簽名後的交易傳送到以太坊節點後,節點需要從簽名交易中還原出公鑰 從公鑰中單向計算出賬號位址 進而將交易放入交易池中。本文從 go ethereum 原始碼的出發,看看如何從簽名交易中還原出公鑰。我們使用上文中最後得到...

以太坊ETH原始碼分析(2) 交易執行過程

交易的發起一般通過呼叫rpc介面實現,eth原始碼本身提供了相關api,位於原始碼的ethereum go ethereum的internal包中 sendtransaction creates a transaction for the given argument,sign it and sub...