Skip to content

智能合约 Event 恢复

其实数据库被误删这种事情不是 Dapp 专属的一种事故,而应该在所有具有数据库应用的防范列表中。这一次只是结合智能合约的数据库的一种特例和它特殊的「修复」方式。

成本核算

  • 显性成本:50USD + 275USD (Infura Team Plan + Archive Node Access Permission)
  • 隐形成本:用户信任度降低,项目的打击
  • 健康成本:团队所有人两天精神紧绷

Dapp 架构

sequenceDiagram autonumber par 用户注册流程 用户->>前端: 钱包签名 前端->>智能合约: 调用只能合约注册账户 智能合约->>后端: 通过 Event(emit Register(用户ID, 用户以太坊地址)) 数据同步 end par 登录到后端 用户->>前端: 钱包签名 前端->>后端: 签名信息传递给后端 后端->>前端: 验签取到用户以太坊地址,返回用户ID end

在本案例中 Dapp 的架构如上所示,有三个端,前端用户界面,业务全在智能合约中,后端收集一些信息做统计、分析的工作。

在这个架构下,event 的 subscribe 和 持久化显得十分重要,所有的数据都是由 event 生成。

发生原因

工程师在重置已使用的测试环境时,误删了线上环境数据库,由于用户的所有信息都是从 API 读取的,数据库删除后所有用户进入前端都是空空一片,只能保证基本的业务流程的使用,所有的统计信息都没了。

团队成员马上进入战斗状态,

  1. 首先询问删除了什么表:delete from table 的方式删除了用户表、event 原始数据表
  2. 其次判断恢复方式
    1. MySQL 层面:备份文件、binlog,这两个都没有!
    2. Event 层面:重新拉取一下从项目开始到现在只能合约发到后端的 event,重新组织数据。

因为并没有做备份,没有开 binlog,没有使用云服务,现在从 MySQL 层面无法下手。因为后端只是收到 event 然后转换为结构化数据,持久化到数据库中,所以决定使用从头处理一遍 Event 的方式去恢复被删除的数据。

然后经过实际试用后选择了 Infura 这家的 Archive 节点的服务,当时我们找到了三种方式:

  1. 自建以太坊全节点,以太坊轻节点我们搭建过一次,但是有足足 10 个区块的延迟,是无法接受的,现在需要搭建全节点来拉取 event 的话,从同步需要的时间和前期积累的经验来看,不考虑这种方式
  2. QuikNode 的服务,他们的 rpc 节点我们试用过,Dashboard 做的十分简陋,节点使用起来速度也比较慢,并且区块同步有延迟,不考虑
  3. Infura 的服务,Infura 的服务是非常不错的,已经经过了 MetaMask 及各种钱包的验证。经过我们本次事故恢复的体验来说,Infura 做的以太坊服务是非常值得推荐的(除了他们的 billing 系统,操作的时候一定要慎重,订单、优惠券管理一塌糊涂,重复扣费蒙眼扣费)。

然后我们从 Infura Archive 节点拉取了从合约部署到当前区块的所有 event 重新持久化后替换了线上数据库,完成事件处理。

吃一堑长一智

  • MySQL(持久化数据) 一定要定期备份、开启 binlog

Comments

Commenting as a guest. A nickname is required; email is optional. Only new comments posted after verifying your email and signing in will appear on your profile. Existing guest comments will not be linked automatically.

Share article

智能合约 Event 恢复

Email X

View original ↗