EthereumのStateについて、EthereumのYellow Paperとgo-ethereumのコードを参照しつつ書いた記事になります。
- Ethereumはトランザクションによって更新される状態(state)を保持するマシン
- stateとはethereum世界における状態のこと
- world state
- acccount stateが持つ4項目
- go-ethereum(geth)におけるAccount Stateの実装
- 関連記事
Ethereumはトランザクションによって更新される状態(state)を保持するマシン
This system can be said to be a very specialised version of a cryptographically secure, transaction-based state machine.
Yellow Paperの第1章 Introductionには上記のように「暗号学的に安全なトランザクションベースの状態(state)マシン」と述べられています。
ここから2つのことが読み取れます。
1つは状態(state)マシンであるということ。stateについては後から詳しく述べますが、アカウントはそれぞれstateを持ち、Ethereumはそのstateを保持するマシンと捉えられます。
もう1つはトランザクションベースであるということ。これはトランザクションによってstateが更新されるという事です。アカウントの持つ代表的なstateは残高ですが、トランザクションが発生して資金が移動するとstateの残高も更新されます。
図にするとこんな感じです。
stateとはethereum世界における状態のこと
Ethereumのstateは「world state」と「account state」があります。
world stateはEthereum世界全体の状態であるとともに、account stateの集合です。
They fall into those of world-state, which are denoted σ (3. Conventions より)
The account state, σ[a] (4.1 World State より)
上記のように定義され、Yellow Paperではworld stateはσという記号で表され、account stateはσ[a]で表されています。
world state
4.1. World State. The world state (state), is a mapping between addresses (160-bit identifiers) and account states (a data structure serialised as RLP, see Appendix B).
「world state」(ワールドステート)は、「address」と「account state」(アカウントステート)のマッピング情報です。
Though not stored on the blockchain, it is assumed that the implementation will maintain this mapping in modifed Merkle Patricia tree (trie, see Appendix D).
この情報はブロックチェーンには書き込まれないと書かれています。ブロックに全ての情報が書き込まれるわけではなく、AccountとStateの紐付けを記録したStateTrieのRootHash値のみが書き込まれます。
こちらの図に掲載されていますが、world stateはpatricia trieのデータ構造になっています。account stateはkeyを指定して取得できるものになります。
blockchain - Ethereum block architecture - Ethereum Stack Exchangeより
acccount stateが持つ4項目
「account state」はnonce、balance、storageRoot、codeHashの4項目をもちます。
Nonce
アドレスの作ったトランザクション数。マイニングに関わるnonceとは別です。
A scalar value equal to the number of transactions sent from this address or, in the case of accounts with associated code, the number of contract-creations made by this account.
原文にはこのように書かれています。
Balance
Ether残高(単位はWei)です。
storageRoot
アカウントが持っているstorageのMerkle Patricia Trieのルートノードハッシュ(デフォルトは空)です。Storage Trieという別のコンテンツが格納されているデータ構造があり、そのルートHash値です。
storageRootのkey,valueペア式については、keyをKECCAK256ハッシュ値で、valueをRLPエンコーディングを行なってstorageRootを作っていくとYellow Paperに定義されています。
RLPエンコーディングについて詳しく知りたい方は以下をご参考ください。
codeHash
EVMコードのハッシュ。スマートコントラクトコードがない場合、空白文字のKECCAK256ハッシュ値がはいります。
go-ethereum(geth)におけるAccount Stateの実装
go-ethereumにおける実装箇所を見てみましょう以下はgo-ethereumのstate packageコードのリンクになります。
go-ethereumにおいてAccount Stateの実際の構造体が書かれているのが以下です。先に挙げた4項目が定義されていますね。
// Account is the Ethereum consensus representation of accounts. // These objects are stored in the main account trie. type Account struct { Nonce uint64 Balance *big.Int Root common.Hash // merkle root of the storage trie CodeHash []byte }
上記AccountはstateObjectという構造体の中に含まれ、dataという項目名で定義されています。更にstateDBという構造体が絡んで利用されたりします。
var emptyCodeHash = crypto.Keccak256(nil) // stateObject represents an Ethereum account which is being modified. // // The usage pattern is as follows: // First you need to obtain a state object. // Account values can be accessed and modified through the object. // Finally, call CommitTrie to write the modified storage trie into a database. type stateObject struct { address common.Address addrHash common.Hash // hash of ethereum address of the account data Account db *StateDB // DB error. // State objects are used by the consensus core and VM which are // unable to deal with database-level errors. Any error that occurs // during a database read is memoized here and will eventually be returned // by StateDB.Commit. dbErr error // Write caches. trie Trie // storage trie, which becomes non-nil on first access code Code // contract bytecode, which gets set when code is loaded originStorage Storage // Storage cache of original entries to dedup rewrites dirtyStorage Storage // Storage entries that need to be flushed to disk // Cache flags. // When an object is marked suicided it will be delete from the trie // during the "update" phase of the state transition. dirtyCode bool // true if the code was updated suicided bool deleted bool }
実装についてはきりがなくなるので定義部分以外は深く追いません。ただ、state packageとその利用されている箇所をgo-ethereumで追ってみると取り出したり計算したりしている箇所が見つけられて理解が深まります。
関連記事
Yellow Paperについて大まかに解説した資料