這邊簡介存儲電路(Storage Circuit)應如何在特定的情況下工作。
在這裡,有一些重要的術語和概念:
在 Storage Circuit,我們按照帳戶地址進行分組,並進一步根據存儲位置進行分組。每個子組中(每個帳戶的每個位置)的記錄都按照全局計數器的升序排列。存儲電路的目標是管理和驗證對存儲的訪問和修改。
記錄在訪問記錄中添加了一個額外的 val_prev,用於寫入存儲時使用。還有一個在總線映射中的額外值 is_first_touch,用於標記存儲位置在一個EOA呼叫中第一次被訪問時的狀態。
一個標準的總線映射查詢可以這樣進行:
bus_mapping_lookup(
    gc,
    Storage,
    key,
    val,
    rw,
    val_prev,
    is_first_touch,
)
def check_storage(row: Row, row_prev: Row, row_next: Row, tables: Tables):
    # 4.0. Unused keys are 0
    assert row.field_tag() == 0
    # 4.1. MPT lookup for last access to (address, storage_key)
    # value = 0 means that the leaf doesn't exist. And this is needed by the non-existing proof.
    is_non_exist = FQ(row.value == Word(0)) * FQ(row.initial_value == Word(0))
    if not all_keys_eq(row, row_next):
        tables.mpt_lookup(
            row.address(),
            is_non_exist * FQ(MPTProofType.NonExistingAccountProof)
            + (1 - is_non_exist) * FQ(MPTProofType.StorageMod),
            row.storage_key(),
            row.value,
            row.initial_value,
            row.root,
            row_prev.root,
        )
    else:
        assert row.root == row_prev.root