尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

EIP-7701 完整交易流程(Complete Transaction Flow)深度解析:原生账户抽象的验证与执行调用链全解

EIP-7701 完整交易流程(Complete Transaction Flow)深度解析:原生账户抽象的验证与执行调用链全解 EIP-7701 完整交易流程Complete Transaction Flow深度解析原生账户抽象的验证与执行调用链全解【免费下载链接】EIPsThe Ethereum Improvement Proposal repository项目地址: https://gitcode.com/GitHub_Trending/ei/EIPsEIP-7701Native Account Abstraction原生账户抽象通过引入新交易类型与操作码族将一笔交易拆分为验证Validation与执行Execution两个阶段并允许 Paymaster 代付 gas、Deployer 按需部署 Sender 合约。本文以仓库中 assets/eip-7701/complete_flow.md 的完整时序图为骨架结合 EIP-7701 规范文档 与配套 README 说明文档逐帧拆解从用户提交 AA 交易到 Paymaster 后操作结束的完整调用链。读完本文你将掌握 EIP-7701 五大角色帧0xA0~0xA4的职责划分、ACCEPT_ROLE/TXPARAM*等核心机制以及如何阅读状态转换函数伪代码验证整个流程。EIP-7701 是什么从单帧交易到多帧交易传统以太坊交易只有一个隐式验证阶段检查余额、nonce、签名和一个隐式执行阶段单个顶层执行帧。EIP-7701 的核心提案是将交易作用域拆分为多个步骤验证validation、执行execution与后操作post-operation交易有效性由验证步骤的结果决定见 EIP 规范 Abstract。它进一步将授权验证与gas 支付分离允许一个合约Paymaster为另一个合约Sender发起的交易支付 gas。需要说明的事实背景该提案当前状态为Withdrawn已撤回撤回原因是被 EIP-8141 取代但其中验证/执行分离 角色帧 操作码族的设计思路对理解原生账户抽象的演进仍有完整价值见 EIP 元信息。规范中关键常量如下见 Constants 表名称值说明AA_TX_TYPETBD新增 EIP-2718 交易类型AA_ENTRY_POINTaddress(0x7701)协议级入口地址AA_BASE_GAS_COST15000基础 gas 成本Sender 地址预热的成本来源ROLE_SENDER_DEPLOYMENT0xA0Sender 部署帧角色ROLE_SENDER_VALIDATION0xA1Sender 验证帧角色ROLE_PAYMASTER_VALIDATION0xA2Paymaster 验证帧角色ROLE_SENDER_EXECUTION0xA3Sender 执行帧角色ROLE_PAYMASTER_POST_OP0xA4Paymaster 后操作帧角色完整流程的参与者与术语定义complete_flow.md的时序图定义了七类参与者。为准确理解流程先结合 README 术语表 澄清各实体的职责Smart Contract Account智能合约账户作为用户账户与链上身份的以太坊智能合约负责持有资产、验证用户请求并代表用户执行操作。Sender发送当前 AA 交易的智能合约账户即执行主体。Paymaster应请求为当前 AA 交易代付 gas 的智能合约。Deployer在需要时为当前 AA 交易中的新 Sender 合约执行部署的智能合约。Entity实体对上述任一合约在 AA 交易上下文中的统称一个实体可承担一个或多个帧角色Frames Role。EIP-7701 Call Frame一次 EVM 代码执行的原子单元由对特定地址的单个顶层调用及给定数据构成帧可能成功或回滚。EIP-7701 Transaction Phase交易阶段构成 AA 交易流程中单个步骤的一组调用帧分为验证阶段与执行阶段。验证阶段定义交易有效性执行阶段则执行 Sender 与 Paymaster 对用户输入的解释动作不定义交易有效性。时序图中的参与者映射如下对应 complete_flow.md 中的 participant 声明时序图参与者角色定位User发起 AA 交易的终端用户Ethereum执行 AA 交易状态转换的协议层AA_ENTRY_POINT协议入口调度各阶段帧调用Deployer Contract可选负责按deployerData部署 SenderSender Contract智能合约账户验证与执行的主体Paymaster Contract可选负责 gas 代付与后操作Target ContractSender 执行阶段实际交互的目标合约完整交易流程总览两大阶段、五类帧complete_flow.md用 PlantUML 完整刻画了 AA 交易的执行轨迹原文完整保留如下源文件见 assets/eip-7701/complete_flow.mdtitle EIP-7701 Complete Transaction Flow actor User skinparam participantFontColor automatic participant Ethereum #darkgreen participant AA_ENTRY_POINT #darkgreen participant Deployer Contract as DC #darkslateblue participant Sender Contract as SC #darkorchid participant Paymaster Contract as PC #olivedrab participant Target Contract as TC #darkred User - Ethereum: Submit AA transaction note right of Ethereum: execute\nAA transaction\nstate transition Ethereum - AA_ENTRY_POINT: |||| group Validation Phase |||| opt Sender Deployment AA_ENTRY_POINT-DC: Deploy AA Transaction Sender\ndeployerData note over DC: ACCEPTROLE 0xA0 DC - SC: Deploy Sender Contract\nCREATE2 DC--AA_ENTRY_POINT:deployed: true |||| end |||| AA_ENTRY_POINT-SC: Validate AA Transaction\nsenderValidationData note over SC: ACCEPTROLE 0xA1 return valid: true |||| opt Gas Abstraction AA_ENTRY_POINT-PC: Validate AA Transaction\npaymasterData note over PC: ACCEPTROLE 0xA2 return valid: true |||| end |||| end group Execution Phase |||| AA_ENTRY_POINT-SC: Execute AA Transaction\nsenderExecutionData note over SC: ACCEPTROLE 0xA3 |||| SC-TC: AA Transaction\nExecution Body |||| opt PostOp AA_ENTRY_POINT-PC: Paymaster PostOp Call note over PC: ACCEPTROLE 0xA4 |||| end |||| end该流程在 README 的帧清单 中被形式化为五类帧验证阶段Validation Phasesender部署帧每个账户一次可选——role_sender_deploymentsender验证帧必选——role_sender_validationpaymaster验证帧可选——role_paymaster_validation执行阶段Execution Phasesender执行帧必选——role_sender_executionpaymaster后操作帧可选——role_paymaster_post_op验证阶段的所有帧必须全部成功且不回滚交易才能被视为对区块内某个位置有效而执行阶段的结果不影响交易有效性的判定。验证阶段逐帧解析交易有效性的判定验证阶段是 EIP-7701 交易能否被打包的关键门槛。根据 规范中的有效性定义对role_sender_deployment、role_sender_validation、role_paymaster_validation三个角色必须同时满足顶层调用帧未回滚在未回滚的帧中ACCEPT_ROLE至少被调用一次且角色输入参数等于current_context_role。Sender 部署帧0xA0可选每个账户一次当 Sender 地址尚无代码时AA_ENTRY_POINT调用 Deployer 合约传入deployerData交易负载中的部署数据。Deployer 在0xA0角色下执行内部通过CREATE2部署 Sender 合约随后向入口返回deployed: true。这一点与 状态转换函数 中if get_code(tx.sender) is None:的判定完全一致——只有链上不存在 Sender 代码时才触发部署因此该帧每个账户仅一次。Sender 验证帧0xA1必选入口向 Sender 合约发起Validate AA Transaction调用负载为senderValidationData。Sender 在此帧内运行自定义验证逻辑如签名校验、nonce 管理、授权检查并以ACCEPTROLE 0xA1显式接受角色后返回valid: true。这是整个流程中不可省略的核心帧。Paymaster 验证帧0xA2可选Gas Abstraction当交易指定了 Paymaster即Gas Abstraction场景时入口向 Paymaster 发起验证调用负载为paymasterData角色为0xA2。Paymaster 在此确认自己愿意为这笔交易买单同样以ACCEPTROLE 0xA2结束。未显式接受角色会导致帧回滚——该机制由 README 的current_context_role规则 保证若实体代码执行结束时未用ACCEPT_ROLE明确接受当前上下文角色则调用帧回滚。执行阶段逐帧解析动作的落地验证通过后进入执行阶段。执行帧不参与有效性判定但它们的状态变更与 gas 消耗最终决定交易结果。Sender 执行帧0xA3必选入口向 Sender 发起Execute AA Transaction负载为senderExecutionData注意这也是唯一一个CALLDATA*非空的帧见 受影响操作码表。Sender 在0xA3角色下执行业务逻辑并可进一步向Target Contract发起AA Transaction Execution Body子调用——即时序图中的SC-TC完成用户意图的实际动作如转账、DApp 交互。Paymaster 后操作帧0xA4可选PostOp执行阶段结束后若存在 Paymaster入口发起Paymaster PostOp Call角色为0xA4。此帧的定位在 README 后操作章节 有明确说明为 Paymaster 提供在 Sender 执行结果已知后**完成记账bookkeeping**的机会例如向用户退款、或强制执行后置条件以确认 Sender 完成了 Paymaster 预期的动作execution_status与execution_gas_used两个运行时内省参数仅在此帧内可通过TXPARAMLOAD访问在0xA4之外的帧中读取返回零值后操作帧被视为执行阶段不可分割的一部分若后操作帧回滚Sender 执行产生的状态变更也会一并回滚对应伪代码中的state.revert_snapshot(checkpoint)。简单流程 vs 完整流程何时不需要 Deployer 与 Paymaster完整流程是全副武装形态当 Sender 已部署且无需 gas 代付时交易退化为 simple_flow.md 所示的最小流程验证阶段仅含 Sender 验证帧ACCEPTROLE 0xA1执行阶段仅含 Sender 执行帧ACCEPTROLE 0xA3及其对 Target Contract 的调用。对比两图完整图源 与 简单图源可以看出opt Sender Deployment、opt Gas Abstraction、opt PostOp三个可选块分别对应 Deployer、Paymaster 验证、Paymaster 后操作它们的取舍决定了流程的复杂程度。这也与 状态转换函数 中if tx.paymaster:的条件分支一一对应。从流程图到伪代码状态转换函数如何落地时序图中的每一步都能在规范的state_transition_function伪代码EIPS/eip-7701.md#L135-L174中找到对应实现核心逻辑如下def state_transition_function(tx, block, state): # 空退款、热地址列表、执行状态与 gas 用量新增等 state.transaction_scoped_vars {} max_gas tx.sender_validation_gas tx.paymaster_validation_gas tx.sender_execution_gas tx.paymaster_post_op_gas gas_price min(tx.max_fee_per_gas, block.base_fee_per_gas tx.max_priority_fee_per_gas) payer tx.sender if tx.paymaster is None else tx.paymaster total_max_cost max_gas * gas_price balances[payer] - total_max_cost gas_used 0 if get_code(tx.sender) is None: deployer_result call(tx.deployer, [], tx.sender_validation_gas_limit, ROLE_SENDER_DEPLOYMENT) assert deployer_result.accepted_role ROLE_SENDER_DEPLOYMENT gas_used deployer_result.gas_used sender_result call(tx.sender, [], tx.sender_validation_gas_limit - gas_used, ROLE_SENDER_VALIDATION) assert sender_result.accepted_role ROLE_SENDER_VALIDATION gas_used sender_result.gas_used if tx.paymaster: paymaster_result call(tx.paymaster, [], tx.paymaster_validation_gas, ROLE_PAYMASTER_VALIDATION) assert paymaster_result.accepted_role ROLE_PAYMASTER_VALIDATION gas_used paymaster_result.gas_used checkpoint state.take_snapshot() sender_execution_result call(tx.sender, [], tx.sender_execution_gas, ROLE_SENDER_EXECUTION) gas_used sender_execution_result.gas_used state.transaction_scoped_vars[execution_status] sender_execution_result.output_code state.transaction_scoped_vars[execution_gas_used] gas_used if tx.paymaster: postop_result call(tx.paymaster, [], tx.paymaster_post_op_gas, ROLE_PAYMASTER_POST_OP) gas_used postop_result.gas_used if postop_result.accepted_role ! ROLE_PAYMASTER_POST_OP: state.revert_snapshot(checkpoint) balances[payer] gas_price * (max_gas - gas_used)几个值得注意的实现细节预先扣费、事后退还先按max_gas × gas_price从 payerSender 或 Paymaster扣款结束后退还(max_gas - gas_used)部分每个帧都断言accepted_role时序图中的ACCEPTROLE 0xA0~0xA4对应每个assert任一帧未接受正确角色即视为验证失败快照回滚保护 Paymastertake_snapshot()/revert_snapshot(checkpoint)实现了PostOp 回滚则 Sender 执行也回滚的语义Sender 地址预预热Sender 地址作为AA_BASE_GAS_COST的一部分被预热当 Paymaster 或 Deployer 提供非零且不等于 Sender 的地址时额外收取 EIP-2930 规定的 2400 gasACCESS_LIST_ADDRESS_COST并加入accessed_addresses见 规范对应章节。帧上下文current_context_role与角色接受机制理解时序图中每帧的ACCEPTROLE 0xXX注释需要掌握帧上下文变量的行为见 README 对应章节执行 Sender、Paymaster 或 Deployer 代码时帧上下文变量current_context_role被设为对应角色默认值为ROLE_SENDER_EXECUTION使用DELEGATECALL之外的操作码发起的调用帧都运行在ROLE_SENDER_EXECUTION角色下该变量只对顶层帧、以及通过不间断的DELEGATECALL链发起的内部帧保持有效行为类似msg.sender若代码执行结束时未通过ACCEPT_ROLE显式接受角色则 EIP-7701 调用帧回滚。ACCEPT_ROLE在语义上等价于RETURN复制内存片段、结束执行并粘贴到父级 returndata唯一区别是它额外接受frame_role参数若与current_context_role不符则回滚见 规范对应章节。配合CURRENT_ROLE操作码合约可以随时读取当前帧角色。TXPARAM* 操作码族帧内访问交易参数验证逻辑需要访问完整交易详情才能做出接受/拒绝决策但为每个交易参数创建独立操作码不可行。规范引入TXPARAMDLOAD、TXPARAMSIZE、TXPARAMCOPY三个操作码遵循CALLDATA*/RETURNDATA*家族模式多出一个栈输入txparam_id。关键参数标识符完整表格见 EIPS/eip-7701.md#L90-L113n返回值数据大小默认值0x02sender32—0x03sender_validation_datadynamic—0x04deployer0 或 32address(0)0x06paymaster0 或 32address(0)0x08sender_execution_datadynamic—0x0Fsender_execution_gas32—0x11access_list哈希32—0xf1execution_status32见处理流程中的交易作用域变量0xf2execution_gas_used32见处理流程中的交易作用域变量0xfftx_hash_for_signature32不含签名的交易哈希两条重要限制见 README 限制章节TXPARAM*只在所有角色的顶层帧中生效其他上下文调用返回零值和零长度execution_status与execution_gas_used仅在role_paymaster_post_op帧内可读。这样设计的理由README Rationale是这些值不向交易执行或传统交易类型开放从而避免TXPARAM*成为新的全局可观察状态源、引发未来向后兼容问题。受影响的全局操作码与跨帧执行上下文时序图之外AA 交易还会改变顶层帧中的全局变量语义见 EIPS/eip-7701.md#L116-L123操作码Solidity 等价值CALLERmsg.senderAA_ENTRY_POINT地址ORIGINtx.origin交易sender地址CALLDATA*msg.data除 Sender 执行帧外均为空Sender 执行帧中为sender_execution_data此外README 特别强调Transaction execution context虽然交易被拆成多个帧但以下依赖交易上下文的行为不受帧拆分影响SSTORE (0x55)的 gas 成本EIP-2200冷地址与冷槽的访问成本EIP-2929瞬态存储中的值EIP-1153执行后分配的最大 gas 退款EIP-3529。例如一个帧中通过TSTORE (0x5D)写入的值在下一个帧中仍然可读——各验证帧与执行帧共享同一交易上下文。安全考量ACCEPT_ROLE的授权语义由于ACCEPT_ROLE是代表合约授权任何动作的通用机制其正确、安全的实现至关重要见 Security Considerations。规范对安全工具与审计方提出明确要求确保不打算在 AA 交易中承担角色的合约不要出现意外的ACCEPT_ROLE操作码否则可能构成直接安全威胁同时建议区块浏览器将源码中使用ACCEPT_ROLE的合约标记为用户账户或paymaster便于识别与审计。总结从complete_flow.md的时序图出发EIP-7701 的完整交易流程可以概括为一条清晰的调用链User→Ethereum→AA_ENTRY_POINT依次调度验证阶段可选的 Deployer 部署0xA0、必选的 Sender 验证0xA1、可选的 Paymaster 验证0xA2与执行阶段必选的 Sender 执行0xA3、对 Target Contract 的执行体调用、可选的 Paymaster 后操作0xA4。每一帧都以显式的ACCEPT_ROLE收尾任何一帧未接受角色即回滚PostOp 帧的回滚还会连带撤销 Sender 执行的全部状态变更。这套角色帧 显式接受 快照回滚的机制配合TXPARAM*交易参数访问族与跨帧共享的执行上下文共同构成了原生账户抽象的完整设计蓝图。建议读者继续深入阅读 EIP-7701 规范、配套 README 说明并结合 simple_flow.md 与 complete_flow.md 两份 PlantUML 源文件自行复现与推演整个流程。【免费下载链接】EIPsThe Ethereum Improvement Proposal repository项目地址: https://gitcode.com/GitHub_Trending/ei/EIPs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表