跳转到主要内容
本指南介绍如何使用 Tenderly 的 API 设置简单和复杂的告警规则。我们将逐一探讨每种表达式类型,然后将它们组合成复杂的监控方案。

Alerting API 参考

简介

Tenderly 的 Alert API 允许您创建简单和复杂的 Alerts。 简单告警由一条规则组成,例如 method_call 会在事务调用您的 public 或 external 方法时触发。复杂告警可包含多个条件,只有当所有条件都满足时才会触发。例如,同时包含 method_callstate_change 的告警,会在事务调用指定方法并更新指定存储槽时触发。 使用 API 定义 Alert 时,您需要指定以下内容:
  • 投递渠道(delivery channels):当告警规则触发时,会通知这些渠道。详见 Delivery Channels
  • 表达式(expressions)数组:当数组中每个表达式所代表的所有条件都被满足时,告警将被触发。
您只能通过 Dashboard 创建投递渠道,但可以使用 API 获取它们。

身份验证

在创建告警之前,您需要设置身份验证并标识您的项目:
const TENDERLY_API_KEY = 'your_api_key';
const PROJECT_SLUG = 'your_project_slug';
const ACCOUNT_ID = 'me';  // Use 'me' or your specific account ID

// Base configuration for axios
const baseConfig = {
  baseURL: 'https://api.tenderly.co/api/v1',
  headers: {
    'X-Access-Key': TENDERLY_API_KEY,
    'Content-Type': 'application/json'
  }
};

表达式类型

您可以使用不同的表达式类型来指定 Alerts 的触发规则。
表达式类型监控对象主要用途必填参数可选参数
method_call合约中特定函数的调用(适用于直接或内部事务)跟踪重要函数何时被调用- line_number:函数定义所在行;call_position:调用位置(“first”、“last”、“any”)
whitelisted_caller_addresses来自特定地址的调用基于白名单的访问控制- addresses:Ethereum 地址数组
blacklisted_caller_addresses来自被拉黑地址的调用基于黑名单的访问控制- addresses:Ethereum 地址数组
contract_address特定合约的交互跟踪与某合约的所有交互- address:合约地址- transaction_type:“direct”、“source” 或 “internal”
network特定网络上的事件多链监控- network_id:网络/链 ID
tag具有特定标签的合约基于分组的监控- tag:标签字符串- transaction_type:“direct”、“source” 或 “internal”
tx_status事务成功/失败跟踪失败的事务- transaction_success:布尔值
function_params函数参数值跟踪特定函数的输入- address:合约地址;function_line_number:函数定义行;parameter_conditions:条件数组- 参数特定的选项
tx_value事务金额跟踪大额转账- transaction_value:金额(wei);operator:比较运算符
emitted_log合约事件跟踪特定事件- address:合约地址;event_name:事件名称;event_id:事件签名- match_any:布尔值;decode_events:布尔值;parameter_conditions:条件数组
state_change合约状态变化跟踪存储变更- address:合约地址;parameter_conditions:条件数组- 比较选项(阈值、百分比)
view_function只读函数结果跟踪计算得到的值- address:合约地址;input:ABI 编码的函数数据;network_id:网络 ID- parameter_condition:值比较
eth_balanceETH 余额变化跟踪余额阈值- address:合约地址;threshold:余额(wei);operator:比较运算符
erc20_transfer_matcherERC20 转账一致性校验转账机制- address:代币地址;log_name:事件名称;balances:状态变量名
tx_error事务错误跟踪意外失败- addresses_to_ignore:地址数组
tx_internal_error内部事务错误跟踪内部调用失败- addresses_to_match:地址数组
no_action无活动跟踪合约休眠- check_after_seconds:时间阈值- no_log:日志条件;no_transaction:事务条件
sandwich_transaction三明治攻击跟踪 MEV 活动- address:合约地址- transaction_type:“direct”、“source” 或 “internal”

说明

  • 比较运算符(operator)的有效取值:>>=<<===!=containsnotContains
  • 参数类型(parameter_type)包括:uintintbooladdressstringbyte
  • 所有地址必须是有效的 Ethereum 地址(以 0x 开头,40 个十六进制字符)
  • Wei 值应作为字符串传入以处理大数
  • 网络 ID 应与目标区块链一致(例如 Ethereum 主网为 “1”)
更多详情请参阅 Alerting API 参考

简单表达式示例

以下示例展示如何设置简单表达式规则。

1. 方法调用监控

使用场景:监控智能合约中的特定函数调用。
const methodCallAlert = {
  name: "Critical Function Call Alert",
  description: "Monitors calls to critical functions",
  enabled: true,
  expressions: [{
    type: "method_call",
    expression: {
      line_number: 123, // Line where function is defined
      call_position: "any" // "first", "last", or "any"
    }
  },
  {
      "type": "contract_address",
      "expression": {
          "address": "0xe592427a0aece92de3edee1f18e0157c05861564"
      }
  }
  ],
  delivery_channels: [{
    id: "your_channel_id",
    enabled: true
  }]
};

await axios.post(
  `/account/${ACCOUNT_ID}/project/${PROJECT_SLUG}/alert`,
  methodCallAlert,
  baseConfig
);

2. 状态变化监控

使用场景:监控合约状态变量的变化,特别适用于跟踪关键参数,例如暂停状态或余额阈值。
const stateChangeAlert = {
  name: "Critical State Change Alert",
  description: "Monitors important state changes",
  enabled: true,
  expressions: [{
    type: "state_change",
    expression: {
      address: "0x1234....",
      parameter_conditions: [
        {
          parameter_name: "pause",
          parameter_type: "bool",
          compare_change: true
        },
        {
          parameter_name: "totalSupply",
          parameter_type: "uint",
          compare_percentage: true,
          comparison_value: "5",
          operator: ">="
        }
      ]
    }
  }],
  delivery_channels: [{
    id: "your_channel_id",
    enabled: true
  }]
};

await axios.post(
  `/account/${ACCOUNT_ID}/project/${PROJECT_SLUG}/alert`,
  stateChangeAlert,
  baseConfig
);

3. 事件监控

使用场景:监控您的合约发出的特定事件,并支持参数过滤。
const eventAlert = {
  name: "Large Transfer Event Alert",
  description: "Monitors large transfer events",
  enabled: true,
  expressions: [{
    type: "emitted_log",
    expression: {
      address: "0x1234....",
      event_name: "Transfer",
      event_id: "0x241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80",
      parameter_conditions: [
        {
          parameter_name: "amount",
          parameter_type: "uint",
          operator: ">=",
          comparison_value: "1000000000000000000" // 1 ETH
        }
      ],
      decode_events: true
    }
  }],
  delivery_channels: [{
    id: "your_channel_id",
    enabled: true
  }]
};

await axios.post(
  `/account/${ACCOUNT_ID}/project/${PROJECT_SLUG}/alert`,
  eventAlert,
  baseConfig
);

4. 原生 ETH 余额监控

使用场景:当某个地址的原生 ETH 余额低于阈值时告警,例如必须保持有充足资金的中继器或运营钱包。将告警范围限定到某个网络和地址,然后将原生余额与阈值(以 wei 表示)进行比较。
const balanceAlert = {
  name: "Low ETH balance alert",
  description: "Alerts when the native ETH balance falls below 0.1 ETH",
  enabled: true,
  expressions: [
    // Scope to a specific network
    {
      type: "network",
      expression: {
        network_id: "1" // Ethereum mainnet
      }
    },
    // Scope to the watched address
    {
      type: "contract_address",
      expression: {
        address: "0x3b8c2f1a9d7e4605c8a1b2d3e4f5061728394a5b"
      }
    },
    // Trigger when the native balance drops below the threshold
    {
      type: "eth_balance",
      expression: {
        address: "0x3b8c2f1a9d7e4605c8a1b2d3e4f5061728394a5b",
        threshold: "100000000000000000", // 0.1 ETH in wei
        operator: "<"
      }
    }
  ],
  delivery_channels: [{
    id: "your_channel_id",
    enabled: true
  }]
};

await axios.post(
  `/account/${ACCOUNT_ID}/project/${PROJECT_SLUG}/alert`,
  balanceAlert,
  baseConfig
);

复杂告警示例

以下示例展示复杂的表达式规则。只有当 expressions 数组中的每个表达式都被满足时,告警才会触发。

1. 安全监控系统

使用场景:结合多个条件的全面安全监控:
  • 监控管理员函数调用
  • 跟踪大额转账
  • 监视黑名单地址
  • 对关键参数的状态变化进行告警
const securityAlert = {
  name: "Security Monitoring System",
  description: "Comprehensive security monitoring for contract",
  enabled: true,
  expressions: [
    {
      "type": "contract_address",
      "expression": {
          "address": "0xe592427a0aece92de3edee1f18e0157c05861564"
      }
    },
    // Admin function monitoring
    {
      type: "method_call",
      expression: {
        line_number: 123,
        call_position: "any"
      }
    },
    // Blacklist checking
    {
      type: "blacklisted_caller_addresses",
      expression: {
        addresses: [
          "0xblacklisted1...",
          "0xblacklisted2..."
        ]
      }
    },
    // Large value transfers
    {
      type: "tx_value",
      expression: {
        transaction_value: "100000000000000000000", // 100 ETH
        operator: ">"
      }
    },
    // Critical state changes
    {
      type: "state_change",
      expression: {
        address: "0x1234....",
        parameter_conditions: [
          {
            parameter_name: "pause",
            parameter_type: "bool",
            compare_change: true
          },
          {
            parameter_name: "owner",
            parameter_type: "address",
            compare_change: true
          }
        ]
      }
    }
  ],
  delivery_channels: [{
    id: "your_channel_id",
    enabled: true
  }]
};

await axios.post(
  `/account/${ACCOUNT_ID}/project/${PROJECT_SLUG}/alert`,
  securityAlert,
  baseConfig
);

2. DeFi 协议监控

使用场景:监控 DeFi 协议的以下情况:
  • 大额交易/兑换
  • 显著的价格影响
  • 流动性变化
  • 失败的事务
  • 三明治攻击
const defiMonitor = {
  name: "DeFi Protocol Monitor",
  description: "Comprehensive DeFi protocol monitoring system",
  enabled: true,
  expressions: [
    // Monitor large swaps via events
    {
      type: "emitted_log",
      expression: {
        address: "0xpool_address",
        event_name: "Swap",
        event_id: "0x...", // Swap event signature
        parameter_conditions: [
          {
            parameter_name: "amountOut",
            parameter_type: "uint",
            operator: ">=",
            comparison_value: "1000000000000000000000" // 1000 tokens
          }
        ],
        decode_events: true
      }
    },
    // Monitor liquidity changes
    {
      type: "state_change",
      expression: {
        address: "0xpool_address",
        parameter_conditions: [
          {
            parameter_name: "reserve0",
            parameter_type: "uint",
            compare_percentage: true,
            comparison_value: "10",
            operator: ">="
          },
          {
            parameter_name: "reserve1",
            parameter_type: "uint",
            compare_percentage: true,
            comparison_value: "10",
            operator: ">="
          }
        ]
      }
    },
    // Monitor for sandwich attacks
    {
      type: "sandwich_transaction",
      expression: {
        address: "0xpool_address",
        transaction_type: "direct"
      }
    },
    // Monitor failed transactions
    {
      type: "tx_error",
      expression: {
        addresses_to_ignore: [] // Monitor all addresses
      }
    }
  ],
  delivery_channels: [{
    id: "your_channel_id",
    enabled: true
  }]
};

await axios.post(
  `/account/${ACCOUNT_ID}/project/${PROJECT_SLUG}/alert`,
  defiMonitor,
  baseConfig
);

3. 带非活动告警的 ERC20 代币监控

使用场景:全面的代币监控,包括:
  • 转账监控
  • 余额检查
  • 状态一致性检查
  • 非活动监控
const tokenMonitor = {
  name: "ERC20 Token Monitor",
  description: "Comprehensive ERC20 token monitoring with inactivity alerts",
  enabled: true,
  expressions: [
    // Monitor Transfer event consistency
    {
      type: "erc20_transfer_matcher",
      expression: {
        address: "0xtoken_address",
        log_name: "Transfer",
        balances: "balances"
      }
    },
    // Monitor large transfers
    {
      type: "emitted_log",
      expression: {
        address: "0xtoken_address",
        event_name: "Transfer",
        event_id: "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
        parameter_conditions: [
          {
            parameter_name: "value",
            parameter_type: "uint",
            operator: ">=",
            comparison_value: "1000000000000000000000" // 1000 tokens
          }
        ]
      }
    },
    // Monitor total supply changes
    {
      type: "state_change",
      expression: {
        address: "0xtoken_address",
        parameter_conditions: [
          {
            parameter_name: "totalSupply",
            parameter_type: "uint",
            compare_percentage: true,
            comparison_value: "1",
            operator: ">="
          }
        ]
      }
    },
    // Monitor for inactivity
    {
      type: "no_action",
      expression: {
        no_log: {
          address: "0xtoken_address",
          event_name: "Transfer",
          event_id: "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
        },
        check_after_seconds: 86400 // 24 hours
      }
    }
  ],
  delivery_channels: [{
    id: "your_channel_id",
    enabled: true
  }]
};

await axios.post(
  `/account/${ACCOUNT_ID}/project/${PROJECT_SLUG}/alert`,
  tokenMonitor,
  baseConfig
);