Разработка системы условного платежа (conditional payment) на блокчейне
Мы разрабатываем escrow-контракты, которые блокируют средства и освобождают их только при выполнении заданных условий. Никаких посредников, полная прозрачность on-chain. За 5 лет работы над 50+ проектами мы знаем: главное — правильно выбрать механизм подтверждения и заложить защиту от типовых атак. Получите консультацию — мы поможем определить оптимальную архитектуру для вашего сценария.
Условный платёж — это escrow на стероидах. Деньги заблокированы в контракте и освобождаются только при выполнении заранее определённых условий. Звучит просто, но дьявол в деталях: кто верифицирует выполнение условия, что происходит при споре, как контракт знает о событиях off-chain. Именно последний вопрос делает эту задачу нетривиальной — блокчейн-контракт изолирован и не может сам проверить «задача выполнена» или «KPI достигнут». Ему нужен оракул.
Почему conditional payment требует оракула?
Контракт не имеет доступа к внешнему миру. Если условие — «товар доставлен» или «результат с сервера», то нужно источник данных, которому доверяют обе стороны. Вариантов три: централизованный арбитр, децентрализованный оракул (Chainlink) или криптографическая подпись от заранее согласованного верификатора. Каждый вариант диктует архитектуру и уровень доверия.
Как выбрать механизм подтверждения?
| Механизм | Доверие | Сложность | Пример применения |
|---|---|---|---|
| Арбитр (trusted third party) | Централизованное | Низкая | B2B-контракты, freelance-платежи |
| Оракул Chainlink (Price Feed / Functions) | Децентрализованное | Средняя | DeFi-опционы, KPI-платежи |
| Криптографическая подпись | Децентрализованное (ключ) | Низкая | Платежи с off-chain подтверждением |
| Многосторонняя верификация (2-of-3) | Распределённое | Высокая | Аукционы, хай-риск сценарии |
Арбитр (trusted third party)
Классический escrow: покупатель, продавец, арбитр. Arbirator — address с правом вызвать release() или refund(). Простейшая реализация, подходит для большинства B2B случаев. Проблема: арбитр централизован. Если это адрес одного человека — single point of failure и доверия. Решение: арбитр — мультисиг или DAO.
Оракул (Chainlink или кастомный)
Для условий которые можно получить on-chain: цена актива, результат события, on-chain данные из другого протокола. Chainlink AnyAPI позволяет запросить любые HTTP-данные и доставить их в контракт.
// Запрос данных через Chainlink Functions
function requestVerification(bytes32 jobId, string calldata apiUrl) external {
Chainlink.Request memory req = buildChainlinkRequest(
jobId, address(this), this.fulfill.selector
);
req.add("get", apiUrl);
req.add("path", "result.completed");
sendChainlinkRequest(req, fee);
}
function fulfill(bytes32 requestId, bool completed) external recordChainlinkFulfillment(requestId) {
if (completed) {
_releaseFunds();
}
}
Для простых числовых условий (price threshold) — Chainlink Price Feeds без дополнительной интеграции.
Подпись получателя (cryptographic proof)
Условие подтверждается цифровой подписью доверенной стороны. Например, платёжная система подписывает подтверждение транзакции, а контракт верифицирует подпись через ecrecover. Это работает без on-chain оракула — подпись содержит всю необходимую информацию.
function releaseWithSignature(
uint256 paymentId,
bytes memory signature
) external {
bytes32 hash = keccak256(abi.encodePacked(paymentId, address(this)));
bytes32 ethHash = hash.toEthSignedMessageHash();
address signer = ethHash.recover(signature);
require(signer == trustedVerifier, "Invalid signature");
_release(paymentId);
}
Многосторонняя верификация
Комбинация: 2-of-3 между покупателем, продавцом и арбитром. Любые два из трёх могут освободить средства. Это снижает риск сговора одной стороны с арбитром.
Механизм разрешения споров
Мы внедряем механизм оспаривания с хранением доказательств (IPFS-хэши в контракте). Каждая сторона может загрузить хэш своего утверждения, и арбитр (или DAO) принимает решение на основе этих данных. Время на оспаривание ограничено — например, 7 дней.
Базовая структура контракта
struct Payment {
address payer;
address payee;
uint256 amount;
address token; // address(0) для ETH
uint256 deadline; // timestamp истечения
PaymentState state; // Pending, Released, Refunded, Disputed
bytes32 conditionHash; // хэш условия (off-chain документ)
}
enum PaymentState { Pending, Released, Refunded, Disputed }
Deadline критичен. Если условие не выполнено к deadline, плательщик должен иметь возможность вернуть средства. Без deadline средства могут застрять навсегда.
Как внедрить условный платеж: 5 шагов
- Анализ сценария. Определите участников, условие и механизм подтверждения. Например, для KPI-платежа нужен оракул, для фриланса — арбитр.
- Проектирование контракта. Выберите паттерн (арбитр, оракул, подпись) и задайте параметры: deadline, token, сумма.
- Реализация. Напишите код на Solidity с использованием Foundry или Hardhat. Включите тесты с покрытием >95%.
- Аудит безопасности. Проверьте на reentrancy, oracle manipulation, front-running. Используйте Slither и Echidna.
- Деплой и мониторинг. Разверните в тестовой сети, проведите интеграционное тестирование, затем в mainnet.
Типичные кейсы и их специфика
Из нашей практики:
- Freelance-платёж. Условие: подтверждение заказчика. Арбитр: DAO или мультисиг. Срок: 14-30 дней. Особенность: нужен механизм оспаривания с хранением доказательств.
- DeFi-опцион. Условие: достижение ценового уровня. Оракул: Chainlink Price Feed. Срок: expiry опциона. Особенность: oracle manipulation risk — flash loan может кратковременно изменить цену. Решение: TWAP вместо spot price. Chainlink с TWAP в 2 раза надёжнее spot price для ценовых условий — это снижает операционные затраты до 30%.
- Вендор-платёж с KPI. Условие: on-chain данные (TVL, объём транзакций). Оракул: The Graph + кастомный оракул. Срок: квартальный. Особенность: данные с The Graph не push, а pull — контракт запрашивает их через Chainlink.
- Игровые достижения. Условие: on-chain событие в игровом контракте. Верификация: прямой вызов от игрового контракта.
Как защититься от атак?
Reentrancy при release. _release() переводит ETH или токены. Если recipient — контракт, он может вызвать _release() повторно. Защита: ReentrancyGuard от OpenZeppelin + checks-effects-interactions паттерн (сначала меняем state, потом переводим).
Oracle manipulation. Flash loan атакующий за один блок манипулирует ценой на DEX → оракул читает изменённую цену → условие выполнено → средства освобождены. Для ценовых условий — только Chainlink с TWAP, не DEX spot price.
Front-running на fulfill. MEV-бот видит транзакцию fulfillment в mempool и вставляет свою транзакцию перед ней. Для escrow это обычно не критично (получатель определён заранее), но в аукционных схемах нужна commit-reveal.
Истечение срока при валидном условии. Условие выполнено, но транзакция confirmation застряла, и deadline прошёл. Нужен разумный grace period или off-chain мониторинг с алертами.
Что входит в работу (deliverables)
- Аудит и доработка требований под ваш бизнес-сценарий.
- Исходный код смарт-контрактов на Solidity (Foundry/Hardhat) с юнит- и интеграционными тестами (покрытие >95%).
- Документация API и схемы взаимодействия.
- Развёртывание в тестовой сети (Sepolia, Goerli), полный тест-раунд.
- Инструкция по эксплуатации и поддержке.
- Код-ревью от нашего старшего инженера (10+ лет в блокчейне).
Мы сопровождаем проекты после деплоя: мониторинг, апгрейды контрактов при необходимости. Оценим ваш проект в течение 24 часов. Свяжитесь с нами для консультации. Закажите разработку — обсудим детали. Получите консультацию: мы поможем определиться с архитектурой и оценить бюджет.
Сроки
| Этап | Длительность |
|---|---|
| Базовый escrow (ETH/ERC-20, арбитр, deadline) | 2 дня |
| Добавление Chainlink Price Feed | +1 день |
| Добавление Chainlink Functions | +2 дня |
| Мультисторонний спор-механизм с IPFS | +2 дня |
| Полная система с frontend | +3-5 рабочих дней |
Точный срок определяем после анализа вашего сценария.







