交易是區塊鏈中最基本也是最核心的乙個概念,在以太坊中,交易更是重中之重,因為以太坊是乙個智慧型合約平台,以太坊上的應用都是通過智慧型合約與區塊鏈進行互動,而智慧型合約的執行是由交易觸發的,沒有交易,智慧型合約就是一段死的**,可以說在以太坊中,一切都源於交易。下面就來看看在以太坊中交易是什麼樣的,交易裡面都有什麼。
在core/types/transaction.go
中定義了交易的資料結構:
type transaction struct
在這個結構體裡面只有乙個data
字段,它是txdata
型別的,其他的三個字段hash
size
from
是快取字段,txdata
也是乙個結構體,它裡面定義了交易的具體的字段:
type txdata struct
各字段的含義如下:
注意:這裡並沒有乙個欄位來指明交易的傳送者,因為交易的傳送者位址可以從簽名中得到。
在transaction.go
中還定義了乙個jsontransaction
結構體,這個結構體用於將交易進行json序列化和反序列化,具體的序列化和反序列化可以參照marshaljson
和unmarshaljson
函式。以太坊節點會向外部提供json rpc服務,供外部呼叫,rpc服務通過json格式傳輸資料,節點收到json資料後,會轉換成內部的資料結構來使用。jsontransaction
結構體使用go語言的struct tag
特性指定了內部資料結構與json資料各字段的對應關係,例如內部的accountnonce
對應json的nonce
,amount
對應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...