MetaNode社区
找工作面试题库领SepoliaETH

© 2025 MetaNode社区. All rights reserved.

Powered by MetaNode

VIP

尊享永久会员

解锁所有面试题解,一次性买断

当前等级普通用户
限时优惠
¥129¥399

/永久

✓解锁全部企业高频面试题及高质量题解
✓参与模拟面试,获取百套模拟面试视频
✓加入永久会员交流群,专属答疑

点击按钮联系客服获取兑换码

扫码添加老师微信

获取兑换码 · 干货不错过

微信二维码
Logo

关注我们

B站抖音小红书
在合约开发过程中,你遇到了哪些具体的安全挑战?当比特币交易卡住时,如何加速交易过程?你参与的NFT交易市场和借贷聚合平台项目是什么时候做的?如果用户在未支付的情况下调用matchOrder会发生什么?你目前主要接触的是EVM吗?能否讲一下比特币和以太坊的区别?以太坊如何通过nonce值解决交易重复的问题?在NFT交易市场项目中,合约团队的规模及整体项目架构是怎样的?NFT交易市场的交易你是如何设计事件监听器的?如何保证事件不丢失?能否详细描述一下作为买家和卖家,在合约中是如何处理资金流的?NFT交易市场中的版税功能如何在合约层面实现的?为何选择通过资金池合约进行所有交先自我介绍一下。你负责的这个岗位主要负责什么工作?在订单匹配过程中,为什么选择将所有资金通过你们的合约进行处理,而不是直接从用户相较于其他NFT平台,你们的模式有哪些优势?你们是否参考了OpenSea方案,并且在安全方面,特别是撤单时如何防范重入攻击等安
返回题库

你是如何设计事件监听器的?如何保证事件不丢失?

简单
00

在NFT交易平台和DeFi借贷聚合平台中,链上数据同步是至关重要的一环。我设计了一套高可靠的事件监听系统, 核心目标就是"不丢、不重、低延迟"。 整体架构设计: 我没有使用简单的ethers.js的contract.on监听,因为这种方式在网络波动或服务重启时容易丢失事件。 我采用的是"拉模式"(Pull)为主,"推模式"(Push)为辅的架构。 核心组件是一个基于Actor模型的Supervisor-Worker系统(我们使用Go语言实现)。Supervisor负责维护区块高 度,Worker负责具体的区块抓取和解析。 如何保证事件不丢失: 第一:基于区块高度的持久化游标(Persistent Cursor) 我们在数据库中记录了每个合约当前已处理到的区块高度(last_processed_block)。 Worker启动时,从数据库读取这个高度,从下一个区块开始抓取。 每处理完一个区块的事件并成功写入数据库后,原子性地更新last_processed_block。 这样即使服务崩溃重启,也能从上次中断的地方继续抓取,绝对不会漏掉中间的区块。 第二:区块确认与重组处理(Reorg Handling) 区块链(特别是Polygon)偶尔会发生区块重组(Chain Reorganization),即链的末端发生了分叉,之前被认为 有效的区块变成了孤块。 如果我们在区块刚产生就抓取并处理,一旦发生重组,数据库里的数据就是错误的。 解决方案是"延迟确认"机制。我们设置了一个安全确认数(Confirmation Blocks),比如Polygon是128个区 块,以太坊是12个区块。 Worker只抓取"当前高度 - 安全确认数"之前的区块。对于这些区块,发生重组的概率极低。 对于需要实时反馈的前端(比如用户刚买了NFT想马上看到),我们有一个独立的"实时流"服务,它订阅最新的事 件推送到前端,但这些数据标记为"未确认"。前端显示"处理中",直到"确认流"服务处理到了这个区块,状态才变 为"已完成"。 第三:多RPC节点故障转移(RPC Failover) RPC节点是不稳定的,经常会出现超时、限流或者数据落后。 我们维护了一个RPC节点池(包括Infura、Alchemy、QuickNode和自建节点)。 Worker在请求RPC时,如果失败,会自动切换到下一个健康的节点重试。 我们还有一个监控协程,定期检测所有RPC节点的健康状态和区块高度,剔除落后太多的节点。 第四:幂等性设计(Idempotency) 为了防止重复处理(比如服务重启时重复抓取了最后一个区块),我们的数据库操作都是幂等的。 每个事件都有一个唯一ID:transaction_hash + log_index。 在写入数据库时,使用INSERT IGNORE或ON CONFLICT DO NOTHING。 这样即使同一个事件被处理两次,数据库里也只会有一条记录,保证了数据的准确性。 具体的处理流程: Supervisor定期(每秒)查询链上的最新区块高度。 如果发现新区块(比如从100涨到了105),它会生成5个任务(101, 102, 103, 104, 105)。 将这些任务发送给Worker池。 Worker领取任务,调用eth_getLogs获取该区块内的所有相关事件。 解析事件数据,转换为业务对象。 开启数据库事务: 插入事件记录 更新业务状态(比如NFT所有权转移) 更新last_processed_block 提交事务。 性能优化: 为了追赶历史数据或处理突发流量,我们实现了并发抓取。Supervisor可以同时分发多个区块的任务给多个 Worker并行处理。 但这里要注意顺序问题。对于某些依赖顺序的业务(比如先转入再转出),并行处理可能会出错。 我们的策略是: 事件入库是并行的(只要保证唯一性)。 业务逻辑处理是串行的。我们有一个消费者服务,按区块高度和log index的顺序读取已入库的事件,依次执行业务 逻辑。 这套系统经过了实战检验,在Polygon网络拥堵期间也能稳定工作,没有发生过一起事件丢失事故。