Monitor

监视器允许您全面了解智能合约的风险和行为。您可以检测威胁,获取关于威胁和异常的警报,并自动响应和解决问题。

用例

  • 监控关键事件和授权函数,如所有权转移、暂停或铸币。

  • 对潜在的危险交易或运营问题发出警报。

  • 将通知集成到 Slack、Telegram、Discord、电子邮件、PagerDuty、Opsgenie 或自定义 API。

  • 使用预构建的模板快速轻松地设置监控。

  • 与其他 Defender 模块结合使用,以使用监视器触发器执行链上交易。

监视器

监视器可以从头开始创建,也可以从模板创建,这些模板是为常见用例设计的。模板会自动预填充监视器,因此您可以轻松修改和重新调整它们。

监视器模板

监视器根据其监控的风险类型分为五个类别:

  • Governance

  • Access Control

  • Suspicious Activity

  • Financial

  • Technical

您还可以指定严重程度,您的团队可以使用它按严重程度对监视器进行分组或过滤。

  • High Severity

  • Medium Severity

  • Low Severity

配置监视器

监视器会监视所有链上合约交易,并在交易与参数、过滤器或事件匹配时发出通知。

目前,除了 Fantom 之外,所有 网络都支持监视器。

常规信息

  • Name:分配给监视器的名称。

  • Risk Category:监视器的风险类别,用于过滤或分组。

  • Contracts:要监控的智能合约。监控依赖于底层的 ABI,因此每个监视器可能只有一个 ABI。如果存在多个智能合约,则监视器必须遵守相同的 ABI/Interface。

  • Confirmation Blocks:如果您希望仅在确定交易被接受到一定程度后才收到通知,建议使用更高的确认区块级别,但如果您希望尽快收到通知并容忍重组,则使用较低的确认区块级别更好。在接受安全和最终区块标签的链中,您也可以选择它们作为确认区块级别。

匹配规则

要使交易触发通知,它必须满足*所有*以下条件:

  • 交易*必须*具有与配置的地址匹配的 To、From 或 Address(来自日志)。

  • 如果指定了*交易过滤器*

    • 交易*必须*与*交易过滤器*匹配。

  • 如果选择了*事件*

    • 交易*必须*发出任何选定的事件并匹配*事件条件*(如果有)

  • 如果选择了*函数*

    • 交易*必须*直接调用任何选定的函数(目前未检测到合约调用)并匹配*函数条件*(如果有)

交易过滤器

交易过滤器允许缩小被监控的交易范围。这些作为属性表达式或 JavaScript 代码输入,提供了极大的灵活性。为了适应校验和地址和非校验和地址的比较,比较是不区分大小写的。

要接收涉及所选事件/函数的所有交易,不应指定交易条件。
  • 条件可以使用 ANDORNOT()

  • 条件可以使用 ==<>>= 进行比较

  • 数字值可以用 Hex (0xabc123) 或 Decimal (10000000000) 表示

  • 字符串值只能通过 == 进行比较

  • 包括基本数学运算符:+-*/、^*

如果指定了交易过滤器条件,则交易*必须*满足此条件才能触发通知。

交易条件可以引用以下属性

  • to 是交易的 to 地址

  • from 是交易的 from 地址

  • gasPrice 是交易中发送的 Gas 价格。在 EIP1559 交易中,它等于或低于 maxFeePerGas

  • maxFeePerGas 是交易愿意为交易支付的最高价格。仅存在于 EIP1559 交易中。

  • maxPriorityFeePerGas 是交易愿意为包含支付给矿工的超过 BASE_FEE 的最高 Wei 金额。仅存在于 EIP1559 交易中。

  • gasLimit 是交易中发送的 Gas 限制

  • gasUsed 是交易中使用的 Gas 量

  • value 是交易中发送的值

  • nonce 是特定交易的 nonce

  • status 是一个派生值,可以与 "success""failed" 进行比较

条件示例

已还原的交易

status == "failed"

排除来自 0xd5180d374b6d1961ba24d0a4dbf26d696fda4cad 的交易

from != "0xd5180d374b6d1961ba24d0a4dbf26d696fda4cad"

Gas 价格高于 50 Gwei 并且 GasUsed 高于 20000 的交易

gasPrice > 50000000000 and gasUsed > 20000

自定义过滤器

自定义过滤器支持用于过滤交易的自定义代码。如果指定了自定义过滤器,则将使用给定区块中找到的匹配项列表调用它。这允许监视器使用其他数据源和自定义逻辑来评估交易是否匹配。

只有符合其他条件(事件、函数、交易)的交易才会调用自定义过滤器。
每次调用最多可包含 25 个交易。

请求 Schema

请求正文将包含以下结构。来自 defender-sdk-action-client 包的 MonitorConditionRequest 类型可用于 Typescript 中的自定义过滤器。

{
  "events": [
  {
    "hash": "0xab..123",                          // 交易哈希
    "timestamp": "1699857792",                    // 交易的时间戳 (区块)
    "blockNumber": 18561272,                      // 交易的区块号
    "blockHash": "0xab..123",                     // 看到此交易的区块哈希
    "transaction": {                              // eth_getTransactionReceipt 响应正文
      ...                                         // 参见 https://eips.ethereum.org/EIPS/eip-1474
      "cumulativeGasUsed": "0xc3614",
      "effectiveGasPrice": "0x6e214d78",
      "gasUsed": "0x6075",
      "logs": [
        { ... }
      ],
      "logsBloom": "0x4..0",
      "status": "0x1",
      "from": "0xab..123",
      "to": "0xab..123",
      "transactionHash": "0xab..123",
      "transactionIndex": "0x9",
      "type": "0x2"
    },
    "matchReasons": [                             // 监视器触发的原因
      {
        "type": "event",                          // event, function, or transaction
        "address": "0x123..abc",                  // 发出事件的合约地址
        "signature": "...",                       // 你的事件/函数的签名
        "condition": "value > 5",                 // 条件表达式(如果有)
        "args": ["5"],                            // 按索引的参数(未命名的存在)
        "params": { "value": "5" }                // 按名称的参数(未命名的不存在)
      }
    ],
    "matchedAddresses": ["0xabc..123"],           // 你正在监控的来自此交易的地址
    "matchedChecksumAddresses": ["0xAbC..123"],   // 你正在监控的来自此交易的校验和地址
    "monitor": {
      "id": "44a7d5...31df5",                     // 你的监视器的内部 ID
      "name": "Monitor Name",                     // 你的监视器的名称
      "abi": [...],                               // 你的地址的 abi(或未定义)
      "addresses": ["0x000..000"],                // 你的监视器正在监视的地址
      "confirmBlocks": 0,                         // 监视器等待的区块数(在 PoS 客户端上可以是“safe”或“finalized”)
      "network": "rinkeby"                        // 你的地址的网络
      "chainId": 4                                // 网络的链 Id
    },
    "metadata": "..."                             // 元数据(如果可用)
  }
  ]
}

响应 Schema

自定义过滤器必须返回一个包含所有匹配项的结构。返回一个空对象表示未发生匹配。此对象的类型为 MonitorConditionResponse

错误将被视为不匹配。
{
  "matches": [
    {
      "hash": "0xabc...123",   // 交易哈希
      "metadata": {
        "foo": true            // 要与通知共享的任何对象
      }
    },
    {
      "hash": "0xabc...123"    // 没有指定元数据的示例
    }
  ]
}

自定义过滤器示例

exports.handler = async function(payload) {
  const conditionRequest = payload.request.body;
  const matches = [];
  const events = conditionRequest.events;
  for(const evt of events) {

    // 在此处添加用于匹配的自定义逻辑

    // 元数据可以是任何可进行 JSON 编组的对象(或未定义)
    matches.push({
       hash: evt.hash,
       metadata: {
        "id": "customId",
        "timestamp": new Date().getTime(),
        "numberVal": 5,
        "nested": { "example": { "here": true } }
       }
    });
  }
  return { matches }
}

事件和函数

事件和函数可以选择作为过滤器。选择多个事件充当 OR 子句(为任何选定的事件触发)。函数也是如此。

事件或函数的条件可以进一步缩小监视器的范围。这些可以通过名称(如果参数已命名)或通过索引(例如,$0,$1…​)引用签名中的参数。变量必须与接口中显示的类型匹配。如果留空,则条件将被忽略。

如果未指定任何事件或函数,则到合约或来自合约的所有交易都将在范围内。
监视器无缝支持智能合约在所有网络上发出的事件的通知,无论它们是直接触发还是通过来自第三方合约的内部调用触发。但是,跟踪和提供合约内内部函数调用通知的功能目前仅限于 Ethereum 主网。

条件示例

发出 Transfer(…​) 事件且值在 1 到 100 ETH 之间的交易(以十六进制表示)

// Event Signature: Transfer(address to, address from, uint256 value)
value > 0xde0b6b3a7640000 and value < 0x56bc75e2d63100000

发出 ValsEvent(…​) 事件且具有第一个元素等于 5 的数组的交易

// Event Signature: ValsEvent(uint256[3] vals)
vals[0] == 5

调用具有未命名的字符串“hello”的 greet(…​) 函数的交易

// Function Signature: greet(address, string)
$1 == "hello"

警报

监视器可以使用任何受支持的通知通道进行警报。也可以连接应该与监视器一起运行的 Action 或 Workflow。

为防止来自单个监视器的重复警报并控制通知率,您可以使用“警报阈值”和“连续通知之间的最短时间”字段。

  • 警报阈值:定义在发送通知或触发 Action 之前,监视器必须在每个时间单位内触发的次数。时间单位由“连续通知之间的最短时间”字段定义。

  • 连续通知之间的最短时间:设置发送通知之间的最短等待时间。

配置 Defender 监视器警报

通知

您可以创建附加到监视器警报的*通知*,以便在多个渠道中获得有关链上事件的通知,有关如何创建和配置它们的更多信息,请参见 此部分

自定义通知

您还可以使用通知通道选择器下方的“自定义通知”复选框来修改消息正文内容和格式。

模板
**监视器名称**

{{ monitor.name }}

**网络**

{{ monitor.network }}

**区块哈希**

{{ blockHash }}

**交易哈希**

{{ transaction.transactionHash }}

**交易链接**

[区块浏览器]({{ transaction.link }})

{{ matchReasonsFormatted }}

**值**

{{ value }}

预览

*监视器名称*

Monitor

*网络*

rinkeby

*区块哈希*

0x22407d00e953e5f8dabea57673b9109dad31acfc15d07126b9dc22c33521af52

*交易哈希*

0x1dc91b98249fa9f2c5c37486a2427a3a7825be240c1c84961dfb3063d9c04d50

https://rinkeby.etherscan.io/tx/0x1dc91b98249fa9f2c5c37486a2427a3a7825be240c1c84961dfb3063d9c04d50[区块浏览器]

*匹配原因 1*

_类型:_ 函数

_匹配地址_:_ 0x1bb1b73c4f0bda4f67dca266ce6ef42f520fbb98

_签名:_ greet(name)

_条件:_ name == 'test'

_参数:_

name: test

*匹配原因 2*

_类型:_ 交易

_条件:_ gasPrice > 10

*值*

0x16345785D8A0000
消息语法

自定义通知支持一组有限的 markdown 语法:

  • 粗体 (**this text is bold**)

  • 斜体 (*this text* and _this text_ are italic)

  • 链接 (this is a [link](https://example.com))

部分支持其他 markdown 语法,但渲染行为因平台而异。电子邮件支持完整的 HTML,并且具有最丰富的功能集,但其他消息传递平台存在限制,包括对标准 markdown 功能(如标题、块引用和表格)的支持。受支持功能的组合(例如,粗体和斜体文本)也具有混合支持。如果 markdown 包含任何具有混合平台支持的语法,则警告消息将直接显示在编辑器下方。

监视器事件 Schema

使用自定义通知模板时,您可以访问以下 schema。如果您配置监视器来执行一个 Action,则此 schema 也会传递给该 Action。

{
  "transaction": {                     // eth_getTransactionReceipt 响应正文
    ...                                // 参见 https://eips.ethereum.org/EIPS/eip-1474
    "cumulativeGasUsed": "0xc3614",
    "effectiveGasPrice": "0x6e214d78",
    "gasUsed": "0x6075",
    "logs": [
      { ... }
    ],
    "logsBloom": "0x4..0",
    "status": "0x1",
    "from": "0xab..123",
    "to": "0xab..123",
    "transactionHash": "0xab..123",
    "transactionIndex": "0x9",
    "type": "0x2"
  },
  "blockHash": "0xab..123",            // 看到此交易的区块哈希
  "matchReasons": [                    // 监视器触发的原因
    {
      "type": "event",                 // event, function, or transaction
      "address": "0x123..abc",         // 发出事件的合约地址
      "signature": "...",              // 事件/函数的签名
      "condition": "value > 5",        // 条件表达式(如果有)
      "args": ["5"],                   // 按索引的参数(未命名的存在)
      "params": { "value": "5" }       // 按名称的参数(未命名的不存在)
    }
  ],
  "matchedAddresses":["0x000..000"]    // 从此交易监控的地址
  "monitor": {
    "id": "44a7d5...31df5",            // 监视器的内部 ID
    "name": "Monitor Name",           // 监视器的名称
    "abi": [...],                      // 地址的 abi(或未定义)
    "addresses": ["0x000..000"],       // 监控的地址
    "confirmBlocks": 0,                // 监视器等待的区块数(在 PoS 客户端上可以是“safe”或“finalized”)
    "network": "rinkeby"               // 地址的网络
    "chainId": 4                       // 网络的链 Id
  },
  "value": "0x16345785D8A0000"         // 交易的值
  "metadata": {...}                // 由 Action 条件注入的元数据(如果适用)
}
动态内容

自定义通知模板使用内联模板呈现动态内容。任何由双大括号包围的字符串都将针对事件 Schema 进行解析。可以使用点表示法访问深度嵌套的项目(包括数组中的项目)。

除了标准事件 schema 之外,还注入了以下参数以供在自定义通知消息中使用:

  • transaction.link

  • matchReasonsFormatted

字符限制

如果消息超过平台的字符限制,则会被截断。最佳做法是将消息限制为 1900 个字符。

设置

在设置选项卡中,您可以指定与不同严重程度(高、中或低)关联的默认通知通道。

监视器设置

暂停和删除

在监视器页面中,您可以暂停已创建的处于活动状态的监视器。通过单击卡片上的虚线按钮,您可以删除监视器或将其另存为模板。

将监视器另存为模板会存储其配置和参数,可以通过单击模板库选项卡找到这些配置和参数。

我们提供了一个快速入门教程,用于使用 Defender 监视智能合约。在此处查看