- Функции: пользовательский код на JavaScript или TypeScript, который вы хотите выполнить при возникновении внешнего события. Это ядро вашей автоматизации.
- Триггеры: предопределённые внешние события, которые ваш Web3 Action настроен отслеживать. Когда событие происходит, триггер указывает Tenderly выполнить ваш пользовательский код (функцию).
- События (типы триггеров): предопределённые внешние события, которые вы можете отслеживать, установив триггер. Когда событие происходит, триггер вызовет ваш пользовательский код (функции).
Типы выполнения
Web3 Actions в Tenderly могут выполняться в двух режимах: Sequential (последовательный) и Parallel (параллельный).
Последовательное выполнение (Sequential)
При последовательном выполнении actions запускаются один за другим в том порядке, в котором они были вызваны. Это режим по умолчанию. В этом режиме каждый action ждёт, пока предыдущий завершит выполнение, прежде чем начать своё. Вот пример конфигурации action для последовательного выполнения:example
Параллельное выполнение (Parallel)
При параллельном выполнении actions запускаются параллельно, что приводит к более высокой пропускной способности. В этом режиме порядок выполнения не гарантируется и возможны состояния гонки при работе с action storage. Вот пример конфигурации action для параллельного выполнения:example
Функции action
Функции Web3 Action — это пользовательский код, написанный как обычные функции JavaScript или TypeScript, но они должны соответствовать некоторым правилам.- Функции должны быть асинхронными и возвращать
Promise<void> - Функции принимают два параметра:
contextиevent - Функция должна быть именованным экспортом из файла
- Функции можно размещать в любом файле в каталоге корня actions (actions root)
- Параметр
context, дающий доступ к Storage и Secrets. - Параметр
event— объект с информацией, отвечающей на вопрос «что только что произошло?». Этот параметр содержит данные, специфичные для типа триггера, на который подписана функция Web3 Action. Раздел Задание триггеров для внешних событий подробно рассматривает внешние события.
Выполнение функций Web3 Action ограничено 30 секундами. Если ваша функция выполняется дольше
30 секунд, она будет прервана.
event может быть любым из поддерживаемых типов триггеров (событий).
example.ts
Доступные библиотеки для actions на базе dashboard
Runtime Tenderly поставляется с несколькими предустановленными JavaScript-библиотеками, которые вы можете импортировать при создании Web3 Actions через Tenderly Dashboard. Доступные библиотеки: Чтобы импортировать любую из этих библиотек, используйте функциюrequire() так же, как в стандартном npm-проекте (без ES6).
Пример импорта Axios выглядит так:
example.jsx
Использование npm-библиотек для Web3 Actions на базе CLI
Проект, создаваемый Tenderly CLI, по сути является npm-модулем. Вы можете установить любой npm-пакет в каталоге корня actions.Внешние события и типы триггеров
Когда происходит внешнее событие, оно запускает выполнение вашего пользовательского кода (функций). Вы можете выбрать одно из четырёх внешних событий для отслеживания:- Block event: блок заминирован в выбранной сети.
- Periodic event: этот триггер срабатывает при прохождении определённых интервалов времени или на основе CRON-выражений.
- Webhook event: HTTP-запрос отправлен на URL webhook (Web3 Action предоставляет webhook)
- Transaction event: транзакция, соответствующая заданным критериям фильтра, выполняется в выбранной сети.
Вы должны писать отдельные функции для каждого типа триггера. Использовать одну функцию для разных
типов триггеров не рекомендуется.
Подписка функций Web3 Action на события
Помимо определения функции action на JavaScript, вам также нужно предоставить конфигурацию триггера, которая сообщает Tenderly, что его запускает — внешнее событие, на которое подписана ваша функция. При создании Web3 Actions через Tenderly Dashboard процесс создания в UI позаботится об этом за вас. Прочитайте руководство Быстрый старт через Dashboard. При работе с Web3 Actions на основе кода функции и их триггеры должны быть определены в файлеtenderly.yaml, генерируемом Tenderly CLI. Прочитайте руководство Быстрый старт через CLI.
Пример
В примере ниже мы объявляем Web3 Action под именем bestActionEver и ссылаемся на функцию awesomeActionFunction, экспортированную из файла actions/myCoolTsFile.ts. Это функция, которую Tenderly вызовет при срабатывании Web3 Action. Выполнение контролируется через execution_type, в этом случае оно установлено в parallel.
tenderly.yaml
Задание триггеров для внешних событий
В этом разделе мы рассмотрим объявлениеtrigger. Для получения дополнительной информации о написании файла tenderly.yaml обратитесь к этому руководству.
Тип триггера и соответствующая конфигурация задаются в файле tenderly.yaml. Сначала нужно определить объект trigger, у которого есть два обязательных свойства:
- Свойство
type, указывающее тип триггера, который может быть:periodic | webhook | block | transaction - Объект с конфигурацией, специфичной для выбранного типа триггера
Periodic event
Periodic event используется, когда вы хотите, чтобы ваш Web3 Action срабатывал через определённые интервалы времени. Оно несёт в себе time: время вызова.example.ts
periodic. Оно может быть основано на интервале или на cron:
trigger.yaml
interval может принимать любое из следующих значений: 5m | 10m | 15m | 30m | 1h | 3h | 6h | 12h | 1d
Используйте периодический триггер на основе CRON, если вам нужен более гранулярный контроль над тем, когда выполняется ваш Web3 Action:
trigger.yaml
cron может быть любой валидной CRON-строкой.
Webhook event
Web3 Actions на основе webhook предоставляют пользовательский URL webhook, что позволяет запускать их из внешних систем с помощью простого HTTP POST запроса. Соответствующий тип триггера содержит два свойства: time вызова и любую payload (JSON-объект). Tenderly не выполняет никаких проверок или инспекций вашей полезной нагрузки.example.ts
webhook-trigger.yaml
authenticated установлено в true, вы должны включить Tenderly Access Token в свой запрос как значение x-access-key, чтобы иметь возможность запустить Web3 Action. cURL для предоставленного webhook можно найти в обзоре Web3 Action в Tenderly Dashboard.
example
Block event
Block event используется, когда вы хотите отслеживать майнинг блоков в одной или нескольких сетях. Вы можете сделать ваш Web3 Action «блочно-периодическим», указав количество заминированных блоков между двумя последовательными вызовами.example.ts
network: одно значение или список ID сетей, которые вас интересуютblocks: количество заминированных блоков между двумя последовательными выполнениями Web3 Action. Например, выполнять Web3 Action на каждом 100-м заминированном блоке.
block-trigger.yaml
Transaction event
Тип триггера transaction позволяет отслеживать конкретные транзакции по мере их выполнения в цепочке.Чтобы отслеживать транзакции со смарт-контракта, смарт-контракт должен быть верифицирован и добавлен в
ваш проект в Tenderly Dashboard. CLI выдаст предупреждение, если это не так.
event.
example.ts
- Статус майнинга транзакции:
mined(транзакция заминирована) илиconfirmed10(подтверждено 10 блоков после блока, содержащего транзакцию) - Фильтры: список условий, включающих полезную нагрузку транзакции, с использованием списка
filters. Только транзакции, соответствующие фильтрам, запустят выполнение вашего кода.
Фильтрация транзакций
Списокfilters позволяет задавать критерии срабатывания с использованием свойств транзакции для сопоставления конкретных транзакций.
Каждый фильтр в списке — это объект, где все поля объединены логикой AND. Каждое условие фильтра должно быть истинным, чтобы он совпал. Сам список filters объединён логикой OR: транзакция совпадает, если удовлетворяет любому одному фильтру из списка.
| Фильтр | Описание |
|---|---|
*обязательный / **должен присутствовать хотя бы один из этих | |
| network* | ID сети, из которой отправлена транзакция |
| status | Статус транзакции: fail или success |
| from** | Адрес отправителя транзакции |
| to** | Адрес получателя транзакции |
| eventEmitted** | Событие определённого типа, сгенерированное конкретным контрактом |
| logEmitted** | Логи, сгенерированные конкретным контрактом, по совпадению префикса сырой записи лога |
| function** | Прямой вызов заданной функции. Не применяется к внутренним вызовам между контрактами |
| ethBalance** | Аккаунт или контракт, чей ETH-баланс удовлетворяет числовому условию в момент транзакции |
| stateChanged** | Контракт, у которого переменная состояния on-chain изменилась во время транзакции, с опциональными условиями по значению/проценту |
| value | Значение, передаваемое в транзакции, в wei |
| gasUsed | Количество газа, использованного транзакцией, в wei |
| gasLimit | Лимит газа, установленный для транзакции, в wei |
| fee | Комиссия транзакции в wei |
| contract | Смарт-контракт, участвующий в транзакции (см. фильтр contract) |
0x236..fd62.
transaction-trigger.yaml
- Фильтр 1: network 1 (Ethereum) AND status fail AND to
0x2364...fd62 - Фильтр 2: network 8453 (Base) AND status fail AND to
0x2364...fd62
Фильтрация транзакций по полям транзакции
Среди общих полей транзакции вы можете фильтровать по следующим свойствам с конкретными значениями.from— фильтрация по конкретному отправителю. Может быть одиночный адрес или список адресов (OR). Опционально.to— фильтрация по конкретному получателю. Может быть одиночный адрес или список адресов (OR). Опционально.status— фильтрация по статусу транзакции:successилиfail. Может быть одиночное значение или список (OR). Опционально.network— фильтрация по сети. Может быть одиночный chain ID или список chain ID (OR). Обязательно.contract.address— фильтрация только транзакций, участие в которых принимает контракт с этим конкретным адресом. Опционально.
0xf63c48626f874bf5604D3Ba9f4A85d5cE58f8019).
list-fields.yaml
valuegasUsedgasLimitfee
eq, gte, gt, lt, lte. Также можно использовать булев флаг not для инвертирования сравнения.
| Оператор | Значение |
|---|---|
eq | Равно |
gt | Больше чем |
gte | Больше или равно |
lt | Меньше чем |
lte | Меньше или равно |
not | Булев. Установите в true, чтобы инвертировать сравнение (например, совпадать, когда значение не в диапазоне) |
numeric-filters.yaml
not для инвертирования сравнения:
negated-comparison.yaml
Фильтрация транзакций с использованием сгенерированных событий EVM
Настройка Web3 Actions на отслеживание EVM-событий, генерируемых выполнением транзакции, позволяет реагировать на значимые изменения, регистрируемые этими событиями. Этого можно достичь с помощью оператораeventEmitted, поддерживающего следующие вложенные свойства:
contract(обязательный): для указания источника события.contract.address: адрес контракта, сгенерировавшего событие.contract.invocation: контролирует, как контракт был вызван:direct,internalилиany(по умолчанию). См. фильтр contract для деталей.
name: имя события (требует верифицированного контракта).id: topic-хеш сигнатуры события (альтернативаname). Полезно для неверифицированных контрактов, где ABI недоступен. Например, событиеTransfer(address,address,uint256)имеет topic-хеш0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef.not: булев. Установите вtrueдля инвертирования всего совпадения события, включая параметры (срабатывает, когда событие не сгенерировано с указанными параметрами).parameters: список условий на декодированные значения аргументов события. Все условия объединены AND: каждое условие должно совпадать. Каждая запись поддерживает:name(обязательный): имя аргумента события.string: сравнение строк. Принимает обычную строку для точного совпадения либо объект с полямиexactиnot. См. StringComparison для деталей.int: целочисленное сравнение. Поддерживает те же операторы, что и числовые фильтры (eq,gt,gte,lt,lte). Все операторы в одном блокеintобъединены AND. Используйте флагnotдля инвертирования комбинированного условия. См. IntComparison для деталей.
В пределах одной записи
eventEmitted в parameters нет OR. Все условия объединены AND.
Для OR-логики на одном параметре используйте несколько записей eventEmitted (которые объединены OR во внешнем списке).Чтобы использовать фильтр
eventEmitted с name или parameters, контракт должен быть верифицирован и добавлен в проект в
Tenderly Dashboard. Используйте id (topic-хеш) для неверифицированных контрактов.TxSubmission или TxConfirmation при выполнении смарт-контракта по адресу 0x418d..9d45 в Sepolia.
event-emitted-filter.yaml
event-parameters.yaml
negated-parameter.yaml
eventEmitted:
event-parameter-or.yaml
not на самом событии для инвертирования всего совпадения:
negated-event.yaml
Фильтрация транзакций по сгенерированным логам
Ещё один способ отслеживать EVM-события — запрашивать их по topic лога. ФильтрlogEmitted может быть одиночным объектом или списком (записи объединены OR). Он поддерживает следующие свойства:
startsWith(обязательный): список значений topic для сопоставления с topic’ами логов транзакции. Каждая запись сравнивается по точному равенству (без учёта регистра) с соответствующим topic. На практике это полные 32-байтные topic-хеши (с префиксом 0x, 64 hex-символа), но поле принимает любую валидную hex-строку.contract.address(опционально): источник логов. Когда указан, сопоставляются только логи из этого контракта.matchAny: булев. Приtrueдостаточно совпадения любого одного topic изstartsWith. Приfalse(по умолчанию) должны совпасть все topic.not: булев. Установите вtrueдля инвертирования всего совпадения лога (срабатывает, когда лог не сгенерирован).
Использование
logEmitted позволяет использовать префикс topic события в сыром виде для фильтрации событий.
Это полезно, если вы настраиваете Web3 Action на неверифицированном контракте.log-emitted-filter.yaml
Фильтрация транзакций, включающих конкретный контракт
Для фильтрации транзакций, вызывающих конкретный контракт во время своего выполнения, вы можете использовать необязательный фильтрcontract.
Фильтр contract поддерживает следующие свойства:
address: адрес контракта.invocation: контролирует, как контракт был вызван. Возможные значения:direct: контракт был вызван напрямую отправителем транзакции (EOA). Используйте, когда вас интересуют только вызовы верхнего уровня к контракту.internal: контракт был вызван внутренне другим контрактом во время выполнения (например, через опкодыCALL,DELEGATECALLилиSTATICCALL). Используйте, чтобы обнаружить, когда ваш контракт вызывается как часть многоконтрактного взаимодействия.any: совпадает и для прямых, и для внутренних вызовов. Значение по умолчанию.
invocation доступно везде, где используется объект contract, включая фильтры eventEmitted. Например, вы можете использовать invocation: internal для контракта в eventEmitted, чтобы совпадать только с событиями, генерируемыми во время внутренних вызовов. См. Contract для схемы.
В примере ниже первый фильтр совпадает с любой успешной транзакцией, отправленной на 0x2364...fd62 в Sepolia. Второй фильтр более ограничивающий: только транзакции, которые также включают внутренний вызов контракта 0xad88...80d6, запустят Web3 Action.
contract-filter.yaml
Фильтрация транзакций по вызову функции
Для фильтрации транзакций, напрямую вызывающих конкретную функцию, можно использовать необязательный фильтрfunction. Он требует адрес контракта contract.address и либо name, либо signature функции.
Фильтр function поддерживает следующие свойства:
contract(обязательный): для указания целевого контракта.contract.address: адрес вызываемого контракта.contract.invocation: контролирует, как функция должна быть вызвана:any(по умолчанию, и прямые, и внутренние),direct(только инициированные EOA) илиinternal(только вложенные вызовы). См. фильтр contract для деталей.
name: имя функции (требует верифицированного контракта).signature: 4-байтовый селектор функции (например,0xa9059cbb). Полезно для неверифицированных контрактов, где ABI недоступен.not: булев. Установите вtrueдля инвертирования всего совпадения функции, включая параметры (срабатывает, когда функция не вызвана с указанными параметрами).parameters: список условий на декодированные значения входных аргументов функции. Все условия объединены AND: каждое условие должно совпадать. Каждая запись поддерживает:name(обязательный): имя аргумента функции.string: сравнение строк. Принимает обычную строку для точного совпадения либо объект с полямиexactиnot. См. StringComparison для деталей.int: целочисленное сравнение. Поддерживает те же операторы, что и числовые фильтры (eq,gt,gte,lt,lte). Все операторы в одном блокеintобъединены AND. Используйте флагnotдля инвертирования комбинированного условия. См. IntComparison для деталей.
В пределах одной записи
function в parameters нет OR. Все условия объединены AND.
Для OR-логики по одному и тому же параметру используйте несколько записей function (которые объединены OR во внешнем списке).Чтобы использовать фильтр
function с name или parameters, контракт должен быть верифицирован и добавлен в проект в
Tenderly Dashboard. Используйте signature (4-байтовый селектор) для неверифицированных контрактов.function как одиночный объект или как список. Когда предоставлен список, записи объединяются OR. Фильтр совпадает, если вызвана любая функция из списка. Полное описание полей см. в FunctionFilter.
Ниже приведён пример триггера Web3 Action, реагирующего на любой вызов (прямой или внутренний) функции verySpecialFunction контракта, развёрнутого по адресу 0xad88...80d6.
function-filter.yaml
function-selector.yaml
function-parameters.yaml
function-negated-string.yaml
function-negated-parameter.yaml
function:
function-parameter-or.yaml
transfer, вызванным маршрутизатором или провайдером flash-loan, а не напрямую пользователем, установите invocation: internal. Этот пример срабатывает только когда другой контракт внутренне вызывает transfer для USDC на сумму не менее 1000 USDC:
function-internal-with-params.yaml
Фильтрация транзакций по балансу ETH
ФильтрethBalance запускает ваш Web3 Action, когда ETH-баланс аккаунта или контракта удовлетворяет числовому условию во время транзакции. Это полезно для отслеживания крупных перемещений «китов», пороговых значений казны протокола или событий пополнения кошелька.
Фильтр поддерживает следующие свойства:
address(обязательный): адрес аккаунта или контракта для отслеживания.balanceCmp(обязательный): числовое сравнение с балансом на момент транзакции. Использует операторыBigIntComparison(eq,gt,gte,lt,lte). Значения в wei и могут быть предоставлены как десятичные строки (например,"1000000000000000000") или как hex с префиксом0x(например,"0xde0b6b3a7640000").not(опционально): установите вtrueдля инвертирования всего совпадения.
ethBalance или список — записи объединены OR.
Полное описание полей см. в EthBalanceFilter.
Пример: срабатывает, когда баланс кошелька достигает не менее 1 ETH:
eth-balance-filter.yaml
eth-balance-multi.yaml
eth-balance-range.yaml
eth-balance-not.yaml
Фильтрация транзакций по изменениям состояния контракта
ФильтрstateChanged запускает ваш Web3 Action, когда переменная состояния контракта меняется во время транзакции. Вы можете сопоставлять по любой комбинации: изменилась ли переменная вообще, конкретное новое значение, процентное изменение или сырой ключ слота хранилища.
Фильтр поддерживает следующие свойства:
address(обязательный, если неmatchAny: true): адрес контракта для отслеживания.matchAny(опционально): приtrueсовпадает с изменениями состояния любого контракта в транзакции,addressможно опустить. Полезно для мониторинга на уровне протокола.params(опционально): список условий на переменные состояния. Все записи объединены AND. Когда опущен, фильтр совпадает с любым изменением состояния указанного адреса.not(опционально): установите вtrueдля инвертирования всего совпадения.
params требует:
name(обязательный): имя переменной состояния.- Хотя бы одно условие:
change: true: совпадает, когда значение переменной изменилось.valueCmp(BigIntComparison) — совпадает, когда новое значение удовлетворяет числовому условию.percentageCmp(BigIntComparison) — совпадает по знаковому процентному изменению, вычисленному как(newValue - oldValue) * 100 / oldValue. Положительные значения означают увеличение, отрицательные — уменьшение. Например,gte: "10"срабатывает при увеличении на 10%+;lte: "-10"срабатывает при уменьшении на 10%+. Примечание: когдаoldValueравно 0, процент всегда 0, используйтеchange: trueилиvalueCmp.storageSlotKey: совпадает по сырому ключу слота хранилища (полезно для неверифицированных контрактов).
StateChangedFilter.
Чтобы использовать сопоставление переменных состояния по
name, контракт должен быть верифицирован и добавлен в ваш проект
в Tenderly Dashboard.totalSupply:
state-changed-basic.yaml
totalSupply достигает порогового значения:
state-changed-value.yaml
totalSupply увеличивается на 50% или более:
state-changed-percentage-increase.yaml
totalSupply уменьшается на 10% или более:
state-changed-percentage-decrease.yaml
totalSupply изменилось И новое значение выше порога):
state-changed-multi-params.yaml
balances[bob], с использованием сырого ключа слота хранилища:
Для отображений нет именованной переменной на запись — используйте storageSlotKey со слотом, полученным через keccak256, для интересующего ключа. Слот для mapping(address => uint256) balances в слоте хранилища N и ключе addr — keccak256(abi.encode(addr, N)).
state-changed-slot.yaml
storageSlotKey работает для неверифицированных контрактов и любой схемы хранилища — он не требует, чтобы контракт был верифицирован или добавлен в ваш проект Tenderly.
Пример: matchAny для отслеживания любого контракта в транзакции:
state-changed-match-any.yaml
stateChanged и ethBalance могут комбинироваться с любым другим фильтром в одном и том же объекте фильтра — все поля объединены AND. Приведённые ниже примеры показывают распространённые реальные комбинации.
Пример: mint() был вызван И totalSupply изменилось (подтверждение того, что вызов имел эффект в блокчейне):
state-changed-with-function.yaml
Transfer И изменилось состояние paused (переключён флаг владения или паузы во время перевода):
state-changed-with-event.yaml
eth-balance-with-to.yaml
togglePause() был вызван, но balances не изменились (то есть транзакция затронула только флаг паузы):
state-changed-not.yaml
Полная справка по триггеру transaction
Следующий аннотированный YAML-блок показывает в одном месте каждое доступное поле для триггеров transaction. Используйте его как быструю справку при построении вашей конфигурации триггера. Определения типов см. в разделе Справочник схемы YAML-триггеров ниже.complete-reference.yaml
Справочник схемы YAML-триггеров
Приведённая ниже схема описывает структуру и типы каждого поля, принимаемого конфигурацией триггера. Используйте её вместе с аннотированным примером выше при построении вашегоtenderly.yaml.
Нотация: ? = опционально, | = одно из, [] = список. Поля, помеченные как «одиночный или список», принимают либо скалярное значение, либо YAML-список.
Все типы триггеров
schema.yaml
TransactionFilter
schema.yaml
Поле
contract верхнего уровня действует как общее значение по умолчанию для фильтра. Оно автоматически применяется к любой записи function или eventEmitted, которая не указывает свой собственный контракт, что позволяет не повторять один и тот же адрес. Оно не применяется к logEmitted.Общие типы
schema.yaml
FunctionFilter
schema.yaml
EventFilter (eventEmitted)
schema.yaml
LogFilter (logEmitted)
schema.yaml
EthBalanceFilter (ethBalance)
schema.yaml
StateChangedFilter (stateChanged)
schema.yaml