Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in
zkevm-circuits
zkevm-circuits
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 0
    • Issues 0
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
  • Merge Requests 0
    • Merge Requests 0
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
  • Operations
    • Operations
    • Incidents
    • Environments
  • Packages & Registries
    • Packages & Registries
    • Package Registry
  • Analytics
    • Analytics
    • CI / CD
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar

新注册的用户请输入邮箱并保存,随后登录邮箱激活账号。后续可直接使用邮箱登录!

  • zkp
  • zkevm-circuitszkevm-circuits
  • Wiki
    • Zkevm docs
    • 4 core
  • core log

Last edited by 桂忠 Aug 07, 2024
Page history
This is an old version of this page. You can view the most recent version or browse the history.

core log

EVM-LOG指令定义

参考:https://ethervm.io/#LOG0

uint8 Mnemonic Stack Input Stack Output Expression Notes
A0 LOG0 offset,length - LOG0(memory[offset:offset+length]) fires an event
A1 LOG1 offset,length,topic0 - LOG1(memory[offset:offset+length], topic0) fires an event
A2 LOG2 offset,length,topic0,topic1 - LOG2(memory[offset:offset+length], topic0, topic1) fires an event
A3 LOG3 offset,length,topic0,topic1,topic2 - LOG3(memory[offset:offset+length], topic0,topic1,topic2) fires an event
A4 LOG4 offset,length,topic0,topic1,topic2,topic3 - LOG4(memory[offset:offset+length], topic0, topic1,topic2,topic3) fires an event

处理流程

LOG0

flowchart LR
    LogBytes --> MEMORY_GAS --> LOG_GAS --> LogTopicNumAddr

LOG1-LOG4

flowchart LR
   LogBytes --> MEMORY_GAS --> LOG_GAS --> LogTopicNumAddr --> LogTopic:topic0 --> LogTopic:topic1 --> ...
  • LogBytes: 处理Log数据拷贝(Copy Lookup Memory->PublicLog)和数据长度记录(Public Lookup)
  • Memory_gas 计算Log操作需要的memory gas花费;
  • Log_gas: 计算Log操作最终的gas花费;
  • LogTopicNumAddr: 处理Log数据地址(Public Lookup)
  • LogTopic: 处理每一个TopicHash处理(Public Lookup)

主要约束及状态变化

LOG0为例:

指令 状态 State参数 约束 gen witness 状态变化
LOG0 LogBytes state1=offset state_stamp = pre + 2
state2=length log_stamp = pre
next_pc = pc
memory_gas memory_gas = GasCost::MEMORY_EXPANSION_LINEAR_COEFF.expr() * (next_word_size - memory_chunk_prev) * (next_quad_memory_cost - curr_quad_memory_cost)
log_gas gas_cost = memory_gas_cost + GasCost::LOG.expr() + topic_gas + length * GasCost::LOG_DATA_GAS.expr()
LogTopicNumAddr - state_stamp = pre 根据opcode 切换值state.topic_left
log_stamp = pre + (1*topic_left_0) topic_left==0时log_stamp+1
next_pc = pc + (1*topic_left_0)

LOG1为例:

指令 状态 State参数 约束 gen witness 状态变化
LOG1 LogBytes state1=offset state_stamp = pre + 2 log_
state2=length stamp = pre
next_pc = pc
memory_gas memory_gas = GasCost::MEMORY_EXPANSION_LINEAR_COEFF.expr() * (next_word_size - memory_chunk_prev) * (next_quad_memory_cost - curr_quad_memory_cost)
log_gas gas_cost = memory_gas_cost + GasCost::LOG.expr() + topic_gas + length * GasCost::LOG_DATA_GAS.expr()
LogTopicNumAddr - state_stamp = pre 根据opcode切换值state.topic_left
log_stamp = pre + (1*topic_left_0) topic_left==0时log_stamp+1
next_pc = pc
LogTopic state1=cur_topic_hash state_stamp = pre+1 state.topic_left -=1
log_stamp = pre + (1*topic_left_0) topic_left==0时log_stamp+1

具体Gadget设计

LogBytesGadget设计

处理memory[offset:offset+length],数据从Memory拷贝到PulbicLog

主要约束:

  • state_stamp = pre + 2
  • log_stamp = pre
  • next_pc = pc

gen_witness状态变化

  • 无
cnt
2 COPY(9) - - PUBLIC(6)
1 STATE1(8) STATE2(8) - LO_INV(1)
0 DYNA_SELECTOR(20) AUX(7) - -

CoreRow2-COPY(9) vers_0~vers_8,负责Copy Lookup(处理Log数据拷贝)

cnt vers_0 vers_1 vers_2 vers_3 vers_4 vers_5 vers_6 vers_7 vers_8
2 src_type=Memory src_id=self.call_id src_pointer=1 src_stamp=2 dst_type=PublicLog dst_id=self.tx_idx dst_pointer=0(PublicLogIndex) dst_stamp=log_stamp len=length

CoreRow2-PUBlIC(6) vers_24~vers_31,负责Public Lookup(处理Log数据长度)

cnt vers_26 vers_27 vers_28 vers_29 vers_30 vers_31
2 tag=TxLog tx_idx=self.tx_idx log_index=self.log_stamp log_tag=DataSize 0 data_len=length

CoreRow1-STATE1(8) vers_0~vers_7,负责从栈中取出的offset

cnt vers_0 vers_1 vers_2 vers_3 vers_4 vers_5 vers_6 vers_7
1 tag=Stack stamp value_hi=0 value_lo=offset call_id_contract_addr=self.call_id - pointer_lo is_write=0

CoreRow1-STATE2(8) vers_8~vers_15,负责从栈中取出的length

cnt vers_0 vers_1 vers_2 vers_3 vers_4 vers_5 vers_6 vers_7
1 tag=Stack stamp value_hi=0 value_lo=length call_id_contract_addr=self.call_id - pointer_lo is_write=0

CoreRow1-LO_INV(1) vers_24

cnt vers_24
1 len_lo_inv

MEMORY_GAS

cnt
1 MEMORY_EXPANSION(2..6) U64DIV(7..11) U64DIV(12..16) SELECTOR(17..30)
0 DYNAMIC(0..17) AUX(18..24) MEMORY_GAS(26) NEXT_IS_LOG_GAS(29) NEXT_IS_PURE_MEMORY_GAS(30) NEXT_IS_MEMORY_COPIER_GAS(31)

主要约束:

  • memory_gas = GasCost::MEMORY_EXPANSION_LINEAR_COEFF.expr() * (next_word_size - memory_chunk_prev) * (next_quad_memory_cost - curr_quad_memory_cost)
    • next_word_size = (new_memory_size + 31) / 32,new_memory_size是通过stack中的offset+length;
    • next_quad_memory_cost = next_word_size * next_word_size / 512;

cnt = 0行:

  • 预留vers_26为计算出的memory_gas,提供给下一个状态使用,vers_29, vers_30, vers_31 为下一个状态约束需要的条件。

cnt = 1行:

  • MEMORY_EXPANSION为Max(cur_memory_size, memory_size)
  • 第一个U64Div为 cur_memory_size * cur_memory_size / 512 = curr_quad_memory_cost
  • 第二个U64Div为 next_memory_size * next_memory_size / 512 = next_quad_memory_cost
  • SELECTOR为opcode选择器。

LOG_GAS

cnt
1 U64OVERFLOW SELECTOR(7..11)
0 DYNAMIC(0..17) AUX(18..24)

主要约束:

  • gas_cost = memory_gas_cost + GasCost::LOG.expr() + topic_gas + length * GasCost::LOG_DATA_GAS.expr(),其中:
    • topic_gas = n * GasCost::LOG.expr(), n为LOG_n;
    • length 为 stack中的参数;

cnt = 1 行:

  • U64OVERFLOW 为gas_left u64的约束;
  • SELECTOR为LOG0-4的选择器。

LogTopicNumAddrGadget设计

主要约束:

  • state_stamp = pre
  • log_stamp = pre + (1 * topic_left_0)
  • next_pc = pc + (1 * topic_left_0)

gen_witness状态变化

  • 根据opcode初始化state.topic_left
  • state.topic_left==0时 log_stamp += 1
cnt
2 - - - PUBLIC(6)
1 - LOG_LEFT_X(5) - -
0 DYNA_SELECTOR(20) AUX(7) - -

CoreRow2-PUBlIC(6) vers_24~vers_31,负责Public Lookup(处理Topic数目和地址)

cnt vers_26 vers_27 vers_28 vers_29 vers_30 vers_31
2 tag=TxLog tx_idx=self.tx_idx log_index=self.log_stamp topic_log_tag=AddrWithLogX address[..4] address[4..]

CoreRow1-LOG_LEFT_X(5) vers_8~vers_12,选择器LOG_LEFT_4~LOG_LEFT_0

cnt vers_8 vers_9 vers_10 vers_11 vers_12
1 LOG_LEFT_4 LOG_LEFT_3 LOG_LEFT_2 LOG_LEFT_1 LOG_LEFT_0

LogTopicGadget设计

主要约束:

  • state_stamp = pre
  • log_stamp = pre + (1 * topic_left_0)
  • next_pc = pc + (1 * topic_left_0)

gen_witness状态变化

  • state.topic_left -= 1
  • state.topic_left==0时 log_stamp += 1
cnt
2 - - - PUBLIC(6)
1 STATE1(8) LOG_LEFT_X(5) - -
0 DYNA_SELECTOR(20) AUX(7) - -

CoreRow2-PUBlIC(6) vers_24~vers_31,负责Public Lookup(处理Topic哈希数据)

cnt vers_26 vers_27 vers_28 vers_29 vers_30 vers_31
2 tag=TxLog tx_idx=self.tx_idx log_index=self.log_stamp topic_log_tag=TopicX topic hash[..16] topic hash[16..]

CoreRow1-STATE1(8) vers_0~vers_7,负责从栈中取出的topic_hash

cnt vers_0 vers_1 vers_2 vers_3 vers_4 vers_5 vers_6 vers_7
1 tag=Stack stamp=0 value_hi=0 value_lo=topic_hash call_id_contract_addr=self.call_id - pointer_lo=2 is_write=0

CoreRow1-LOG_LEFT_X(5) vers_8~vers_12,选择器LOG_LEFT_4~LOG_LEFT_0

cnt vers_8 vers_9 vers_10 vers_11 vers_12
1 LOG_LEFT_4 LOG_LEFT_3 LOG_LEFT_2 LOG_LEFT_1 LOG_LEFT_0
Clone repository
  • basics
    • evm
    • halo2
  • code notes
    • binary_number_with_real_selector
    • how to use macro
    • simple_lt
    • simple_lt_word
  • Home
  • image
  • zkevm docs
    • 1 introduction
    • 10 public
    • 11 fixed
    • 12 exp
    • 13 keccak
    • 14 comparisons
    • 15 differences
View All Pages

Copyright © 2024 ChainWeaver Org. All Rights Reserved. 版权所有。

京ICP备2023035722号-3

京公网安备 11010802044225号