# 智能合约 Event 恢复

Original: <https://lifelonglearn.ing/dapp-pir-database-deleted-by-mistake>

Author: [奶爸](https://lifelonglearn.ing/users/3b04650c-8231-499b-8ef0-381fc4d7efb0)

Published: 2020-07-23T11:09:00Z

Updated: 2026-09-27T06:57:43Z

Version: 1

其实数据库被误删这种事情不是 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
