Neutrinoで働くブロックチェーンエンジニアのブログ

渋谷の専門特化コワークNeutrinoに入居してブロックチェーンエンジニアとして働いています。元丸の内。(Neutrino運営企業とは直接関係ありません)

EthereumのStateについて - Yellow Paper4章より

f:id:naomasabit:20181208202434j:plain

EthereumのStateについて、EthereumのYellow Papergo-ethereumのコードを参照しつつ書いた記事になります。

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の残高も更新されます。

f:id:naomasabit:20181208194612p:plain

図にするとこんな感じです。

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を指定して取得できるものになります。

Ethereum Trie Architecture
Ethereum Trie Architecture

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に定義されています。

storage root definition

RLPエンコーディングについて詳しく知りたい方は以下をご参考ください。

www.blockchainengineer.tokyo

codeHash

EVMコードのハッシュ。スマートコントラクトコードがない場合、空白文字のKECCAK256ハッシュ値がはいります。

go-ethereum(geth)におけるAccount Stateの実装

go-ethereumにおける実装箇所を見てみましょう以下はgo-ethereumのstate packageコードのリンクになります。

github.com

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で追ってみると取り出したり計算したりしている箇所が見つけられて理解が深まります。

関連記事

www.blockchainengineer.tokyo

www.blockchainengineer.tokyo

www.blockchainengineer.tokyo

www.blockchainengineer.tokyo

Yellow Paperについて大まかに解説した資料