Встроенные Функции

Полный справочник всех доступных встроенных функций в политиках

В политиках доступны только следующие встроенные функции. Функции, не указанные здесь, отключены по соображениям безопасности. Подробную информацию об отключенных функциях см. в разделе Ограничения.

Строковые Функции

Функции для манипулирования и проверки строковых значений. Необходимы для работы с адресами, именами методов и другими текстовыми полями.

contains

Проверяет, содержит ли строка подстроку. Возвращает true, если найдено, иначе false.

Пример

# Block any method containing "sign"
deny if {
    contains(input.rpc_method, "sign")
}

startswith

Проверяет, начинается ли строка с префикса. Полезно для сопоставления категорий методов или шаблонов адресов.

Пример

# Block debug methods
deny if {
    startswith(input.rpc_method, "debug_")
}
 
# Block addresses starting with many zeros
deny if {
    startswith(input.to_address, "0x00000000")
}

endswith

Проверяет, заканчивается ли строка суффиксом.

Пример

# Block addresses ending with specific pattern
deny if {
    endswith(lower(input.to_address), "dead")
}

lower

Преобразует строку в нижний регистр. Необходимо для сравнения адресов без учета регистра, поскольку адреса могут иметь смешанный регистр.

Пример

# Case-insensitive address check
blocked_addresses := {
    "0x000000000000000000000000000000000000dead"
}
 
deny if {
    lower(input.to_address) in blocked_addresses
}

upper

Преобразует строку в верхний регистр.

Пример

# Normalize method names that might have inconsistent casing
deny if {
    upper(input.rpc_method) == "ETH_SENDTRANSACTION"
    input.usd_value > 10000
}

concat

Объединяет массив строк с разделителем.

Пример

# Join values for logging or comparison
message := concat(", ", ["chain:", input.chain, "method:", input.rpc_method])

split

Разделяет строку на массив с использованием разделителя.

Пример

# Parse a method name
parts := split(input.rpc_method, "_")
 
deny if {
    parts[0] == "debug"
}

replace

Заменяет все вхождения подстроки другой строкой.

Пример

# Normalize address format
normalized := replace(input.to_address, "0X", "0x")

substring

Извлекает часть строки по начальной позиции и длине.

Пример

# Get method prefix (first 4 characters after "eth_")
deny if {
    startswith(input.rpc_method, "eth_")
    method_action := substring(input.rpc_method, 4, 4)
    method_action == "send"
}

sprintf

Форматирует строку с заполнителями. Полезно для создания динамических значений.

PlaceholderType
%sString
%dInteger
%fFloat
%vAny value

Пример

# Create formatted message
threshold := 10000
message := sprintf("Value %d exceeds limit of %d", [input.usd_value, threshold])

trim

Удаляет указанные символы с обоих концов строки.

Пример

# Remove specific characters from both ends
cleaned := trim(input.rpc_method, "_")

trim_space

Удаляет пробелы с обоих концов строки.

Пример

# Clean up input with extra spaces
clean_method := trim_space(input.rpc_method)

trim_prefix

Удаляет префикс из строки, если он присутствует.

Пример

# Remove common prefix to get the action name
method_name := trim_prefix(input.rpc_method, "eth_")
 
deny if {
    method_name == "sendTransaction"
}

trim_suffix

Удаляет суффикс из строки, если он присутствует.

Пример

# Remove suffix for comparison
base_method := trim_suffix(input.rpc_method, "_v2")

indexof

Находит индекс первого вхождения подстроки. Возвращает -1, если не найдено.

Пример

# Check if underscore exists
deny if {
    indexof(input.rpc_method, "_") == -1
}

Функции Регулярных Выражений

Функции для сопоставления шаблонов с использованием регулярных выражений. Более мощные, чем строковые функции для сложных шаблонов.

regex.match

Проверяет, соответствует ли строка шаблону регулярного выражения. Возвращает true или false.

Пример

# Block methods starting with debug_, admin_, or personal_
deny if {
    regex.match("^(debug_|admin_|personal_)", input.rpc_method)
}
 
# Block addresses with many leading zeros
deny if {
    regex.match("^0x0{10,}", input.to_address)
}

regex.replace

Заменяет все совпадения шаблона строкой замены.

Пример

# Remove all non-alphanumeric characters
cleaned := regex.replace(input.rpc_method, "[^a-zA-Z0-9]", "")

regex.split

Разделяет строку по шаблону регулярного выражения.

Пример

# Split by multiple delimiters
parts := regex.split("[_.]", input.rpc_method)

regex.find_n

Находит до n совпадений шаблона в строке.

Пример

# Find all hex sequences
hex_matches := regex.find_n("0x[a-fA-F0-9]+", input.raw_params[0].data, 10)
 
deny if {
    count(hex_matches) > 5
}

Функции Времени

Функции для работы со временем. Все значения времени указаны в наносекундах с эпохи Unix.

time.now_ns

Получает текущее время в наносекундах. Используйте это в качестве основы для политик, основанных на времени.

Пример

# Block high-value transactions during volatile market hours
deny if {
    current := time.now_ns()
    [hour, _, _] := time.clock(current)
    hour >= 14  # After 2 PM UTC (US market open)
    hour < 21   # Before 9 PM UTC (US market close)
    input.usd_value > 50000
}

time.clock

Извлекает час, минуту и секунду из временной метки. Возвращает [hour, minute, second].

Пример

# Block outside business hours (9 AM - 5 PM UTC)
deny if {
    [hour, _, _] := time.clock(time.now_ns())
    hour < 9
}
 
deny if {
    [hour, _, _] := time.clock(time.now_ns())
    hour >= 17
}

time.weekday

Получает день недели из временной метки. Возвращает 0 (воскресенье) до 6 (суббота).

Пример

# Block on weekends
deny if {
    day := time.weekday(time.now_ns())
    day == 0  # Sunday
}
 
deny if {
    day := time.weekday(time.now_ns())
    day == 6  # Saturday
}

time.date

Извлекает год, месяц и день из временной метки. Возвращает [year, month, day].

Пример

# Block on specific dates
deny if {
    [year, month, day] := time.date(time.now_ns())
    month == 12
    day == 25  # Christmas
}

time.parse_rfc3339_ns

Разбирает строку временной метки в формате RFC3339 в наносекунды.

Пример

# Compare against a specific date
cutoff := time.parse_rfc3339_ns("2024-12-31T23:59:59Z")
 
deny if {
    time.now_ns() > cutoff
}

time.add_date

Добавляет годы, месяцы и дни к временной метке.

Пример

# Block transactions if we're within 7 days of year end
deny if {
    year_end := time.parse_rfc3339_ns("2024-12-31T23:59:59Z")
    week_before := time.add_date(year_end, 0, 0, -7)
    time.now_ns() > week_before
    input.usd_value > 10000
}

time.diff

Вычисляет разницу между двумя временными метками. Возвращает [years, months, days, hours, minutes, seconds].

Пример

# Check if more than 1 hour has passed
start := time.parse_rfc3339_ns("2024-01-01T00:00:00Z")
[_, _, _, hours, _, _] := time.diff(time.now_ns(), start)
 
deny if {
    hours > 1
}

Агрегатные Функции

Функции для работы с коллекциями значений.

count

Подсчитывает количество элементов в массиве, множестве или объекте.

Пример

# Limit number of contracts in a request
deny if {
    count(input.contract_addresses) > 5
}
 
# Ensure at least one address
deny if {
    count(input.contract_addresses) == 0
}

sum

Вычисляет сумму чисел в массиве.

Пример

# Block if total gas across params exceeds limit
deny if {
    gas_values := [to_number(p.gas) | some p in input.raw_params; p.gas != null]
    sum(gas_values) > 5000000
}

max

Находит максимальное значение в массиве.

Пример

# Check against maximum in a set of thresholds
thresholds := [1000, 5000, 10000]
 
deny if {
    input.usd_value > max(thresholds)
}

min

Находит минимальное значение в массиве.

Пример

# Ensure value meets minimum threshold
thresholds := [100, 500, 1000]
 
deny if {
    input.usd_value < min(thresholds)
}

sort

Сортирует массив в порядке возрастания.

Пример

# Check if smallest contract address looks suspicious (many leading zeros)
deny if {
    count(input.contract_addresses) > 0
    sorted_addrs := sort(input.contract_addresses)
    startswith(sorted_addrs[0], "0x00000000")
}

product

Вычисляет произведение чисел в массиве.

Пример

# Calculate combined risk score from multiple factors
deny if {
    risk_factors := [2, 3]  # High-value = 2x, Unknown sender = 3x
    combined_risk := product(risk_factors)
    combined_risk > 5
}

Функции Типов

Функции для проверки и работы с типами данных. Полезны для безопасной обработки полей, допускающих значение null.

is_null

Проверяет, является ли значение null. Необходимо для обработки необязательных полей ввода.

Пример

# Safely check nullable field
deny if {
    not is_null(input.usd_value)
    input.usd_value > 10000
}

is_number

Проверяет, является ли значение числом.

Пример

# Validate before numeric comparison
deny if {
    is_number(input.usd_value)
    input.usd_value > 10000
}

is_string

Проверяет, является ли значение строкой.

Пример

# Validate input type
deny if {
    is_string(input.to_address)
    startswith(input.to_address, "0x0000")
}

is_array

Проверяет, является ли значение массивом.

Пример

# Check before iterating
deny if {
    is_array(input.contract_addresses)
    count(input.contract_addresses) > 10
}

is_boolean

Проверяет, является ли значение булевым (true или false).

Пример

# Verify a flag is actually a boolean before using it
deny if {
    is_boolean(input.raw_params[0].enabled)
    input.raw_params[0].enabled == false
}

is_set

Проверяет, является ли значение множеством.

Пример

# Validate collection type
deny if {
    is_set(input.raw_params[0].addresses)
    count(input.raw_params[0].addresses) > 100
}

is_object

Проверяет, является ли значение объектом (карта ключ-значение).

Пример

# Ensure params is an object before accessing fields
deny if {
    is_object(input.raw_params[0])
    object.get(input.raw_params[0], "dangerous", false) == true
}

type_name

Получает имя типа значения в виде строки.

Пример

# Block if usd_value is not a number (unexpected type)
deny if {
    input.usd_value != null
    type_name(input.usd_value) != "number"
}

Числовые Функции

Функции для числовых операций.

abs

Получает абсолютное значение числа.

Пример

# Check magnitude regardless of sign
deny if {
    abs(input.usd_value) > 10000
}

round

Округляет число до ближайшего целого.

Пример

# Round for comparison
deny if {
    round(input.usd_value) > 10000
}

ceil

Округляет число вверх до следующего целого.

Пример

# Round up for conservative limit checking
deny if {
    ceil(input.usd_value) > 10000
}

floor

Округляет число вниз до предыдущего целого.

Пример

# Block transactions over $10,000 (ignoring cents)
deny if {
    floor(input.usd_value) >= 10000
}

to_number

Преобразует строку в число. Полезно для шестнадцатеричных строковых значений.

Пример

# Convert hex gas values
deny if {
    input.gas_limit != null
    to_number(input.gas_limit) > 1000000
}

numbers.range

Генерирует массив чисел от начала до конца (включительно).

Пример

# Allow transactions only during business hours (9 AM - 5 PM)
deny if {
    [hour, _, _] := time.clock(time.now_ns())
    business_hours := numbers.range(9, 17)
    not hour in business_hours
}

Функции Объектов

Функции для работы с объектами (карты ключ-значение).

object.get

Безопасно получает значение из объекта со значением по умолчанию, если ключ не существует.

Пример

# Safely access nested data
deny if {
    params := input.raw_params[0]
    data := object.get(params, "data", "0x")
    startswith(data, "0xa9059cbb")  # ERC-20 transfer
}

object.keys

Получает все ключи из объекта в виде массива.

Пример

# Check which fields are present
params := input.raw_params[0]
keys := object.keys(params)
 
deny if {
    "data" in keys
    "value" in keys
}

object.remove

Создает новый объект с удаленными указанными ключами.

Пример

# Block if params contain unexpected fields after removing known safe ones
deny if {
    safe_fields := ["to", "from", "value", "gas", "data"]
    remaining := object.remove(input.raw_params[0], safe_fields)
    count(object.keys(remaining)) > 0
}

object.union

Объединяет два объекта. Значения из второго объекта переопределяют первый.

Пример

# Apply safe defaults and check resulting gas limit
deny if {
    defaults := {"gas": "0x5208"}
    params := object.union(defaults, input.raw_params[0])
    to_number(params.gas) > 1000000
}

Функции Массивов

Функции для манипулирования массивами.

array.concat

Объединяет два массива в один.

Пример

# Combine address lists
all_addresses := array.concat(
    input.contract_addresses,
    [input.to_address]
)

array.slice

Извлекает часть массива по начальному и конечному индексу.

Пример

# Only check first 5 contract addresses for blocked list
deny if {
    first_five := array.slice(input.contract_addresses, 0, 5)
    some addr in first_five
    addr in {"0xbanned1...", "0xbanned2..."}
}

array.reverse

Переворачивает порядок элементов в массиве.

Пример

# Check last contract address (most recent) for suspicious patterns
deny if {
    count(input.contract_addresses) > 0
    reversed := array.reverse(input.contract_addresses)
    startswith(reversed[0], "0x00000000")
}

Функции Множеств

Функции для операций над множествами.

intersection

Получает элементы, которые существуют в обоих множествах.

Пример

# Check for any blocked address
blocked := {"0xdead...", "0xbad..."}
request_addrs := {lower(input.to_address)}
 
deny if {
    count(intersection(blocked, request_addrs)) > 0
}

union

Объединяет два множества в одно со всеми уникальными элементами.

Пример

# Combine multiple blocklists
blocked_countries := union(
    {"KP", "IR", "CU"},
    {"SY", "RU"}
)
 
deny if {
    input.source_country in blocked_countries
}

Функции Кодирования

Функции для кодирования и декодирования данных.

base64.encode

Кодирует строку в формат Base64.

Пример

# Check if method matches an encoded pattern
deny if {
    encoded_method := base64.encode(input.rpc_method)
    encoded_method == "ZXRoX3NlbmRUcmFuc2FjdGlvbg=="  # eth_sendTransaction
}

base64.decode

Декодирует строку Base64 обратно в обычный текст.

Пример

# Decode base64 data from request
decoded := base64.decode("aGVsbG8=")  # "hello"
 
deny if {
    contains(decoded, "dangerous")
}

base64url.encode

Кодирует строку в формат Base64, безопасный для URL. Использует - и _ вместо + и /.

Пример

# Create URL-safe identifier from address for comparison
deny if {
    encoded_addr := base64url.encode(input.to_address)
    encoded_addr in {"MHhkZWFk...", "MHhiYWQ..."}
}

base64url.decode

Декодирует строку Base64, безопасную для URL, обратно в обычный текст.

Пример

# Decode and check URL-safe encoded data in params
deny if {
    encoded_data := object.get(input.raw_params[0], "encoded", "")
    decoded := base64url.decode(encoded_data)
    contains(decoded, "malicious")
}

hex.encode

Кодирует строку в шестнадцатеричный формат.

Пример

# Encode method name to hex for pattern matching
deny if {
    method_hex := hex.encode(input.rpc_method)
    startswith(method_hex, "657468")  # "eth" in hex
}

hex.decode

Декодирует шестнадцатеричную строку обратно в обычный текст.

Пример

# Decode hex-encoded data field and check contents
deny if {
    data := object.get(input.raw_params[0], "data", "")
    startswith(data, "0x")
    decoded := hex.decode(substring(data, 2, 8))
    contains(decoded, "admin")
}
Встроенные Функции | 256 Blocks