Користувач встановив застосунок, отримав NFT або токени, хоче щось зробити — і натикається на «потрібен ETH для газу». На цьому кроці втрачається від 30 до 60% нових користувачів залежно від аудиторії. За нашими оцінками, впровадження meta-транзакцій збільшує конверсію в цільову дію на 40–70%, а вартість інтеграції окупається протягом кількох місяців завдяки зростанню користувацької бази. Ми вирішуємо цю проблему за допомогою стандарту EIP-2771: користувач підписує намір, а застосунок оплачує газ — це називається безгазові транзакції. За нашими даними, meta-транзакції збільшують конверсію в 2-3 рази порівняно зі стандартними транзакціями, де користувач сам оплачує газ.
EIP-2771 стандартизував архітектуру: trusted forwarder — контракт, якому цільовий контракт довіряє пересилати виклики зі збереженням оригінального msg.sender. За роки роботи ми впровадили такі системи для 15+ DeFi-проєктів, обробивши понад 500 ETH комісій. Ви можете заощадити до 60% на газових зборах для ваших користувачів, переклавши витрати на свій бюджет.
Як EIP-2771 усуває бар'єр газу?
Без meta-транзакцій: user → (напряму) → Contract. msg.sender у контракті — це адреса користувача. З meta-транзакціями: user → (підписаний запит) → Relayer → Forwarder → Contract. msg.sender у контракті — це адреса Forwarder. Контракт не знає справжнього відправника.
Рішення — контракт перевіряє, що msg.sender є довіреним forwarder'ом, і тоді читає справжню адресу з останніх 20 байт calldata:
// OpenZeppelin ERC2771Context
function _msgSender() internal view virtual override returns (address) {
if (isTrustedForwarder(msg.sender) && msg.data.length >= 20) {
return address(bytes20(msg.data[msg.data.length - 20:]));
}
return super._msgSender();
}
Усі msg.sender у бізнес-логіці контракту потрібно замінити на _msgSender(). Це єдина зміна в існуючому контракті — якщо він успадковує ERC2771Context від OpenZeppelin.
Що входить у роботу
- Аудит існуючого смарт-контракту
- Інтеграція ERC2771Context та модифікація логіки
- Деплой кастомного Forwarder
- Налаштування централізованого релейера на Node.js
- Інтеграція у фронтенд (wagmi + signTypedData)
- Написання E2E-тестів
- Документація та передача доступів
- Підтримка протягом 2 тижнів після деплою
Компоненти системи
Trusted Forwarder
Валідує підписи користувачів (EIP-712 typed data), перевіряє nonce (захист від replay), пересилає виклик у цільовий контракт, додаючи адресу користувача в кінець calldata.
OpenZeppelin MinimalForwarder — проста реалізація, підходить для початку. Для production рекомендуємо OpenGSN Forwarder або власний з додатковими перевірками: deadline, domain separator, address whitelisting.
struct ForwardRequest {
address from; // користувач
address to; // цільовий контракт
uint256 value; // ETH (зазвичай 0)
uint256 gas; // ліміт газу
uint256 nonce; // захист від replay
bytes data; // calldata
}
Підпис EIP-712
Користувач підписує структуровані дані, а не сирий хеш. Це дозволяє MetaMask та іншим гаманцям показувати людиночитаний вміст запиту перед підписанням.
// Клієнт: підготовка підпису
const domain = {
name: "MyForwarder",
version: "1",
chainId: await signer.getChainId(),
verifyingContract: forwarderAddress,
};
const signature = await signer.signTypedData(domain, types, request);
Relayer
Приймає підписаний запит, перевіряє його валідність, відправляє транзакцію за користувача, оплачуючи газ. Варіанти:
| Тип | Приклад | Коли вибрати |
|---|---|---|
| Централізований | Власний backend | Прототип, мале навантаження (<10 TPS) |
| Децентралізована мережа | OpenGSN | Висока надійність, scale |
| Managed-сервіс | Biconomy / Gelato | Швидкий старт, аналітика |
Для більшості проєктів на старті — централізований relayer на власному backend. Це простіше, швидше та дешевше, поки TPS невеликий. Децентралізація потрібна, коли централізований relayer стає точкою відмови з реальними наслідками.
Для централізованого релейера знадобиться: сервер з Node.js, база даних для зберігання nonce (Redis або PostgreSQL), RPC-ендпоінт (Infura/Alchemy). Архітектура: API endpoint приймає підписаний ForwardRequest, валідує підпис, перевіряє nonce, відправляє транзакцію через ethers.js, оновлює nonce. Для managed-сервісів (Biconomy) налаштування зводиться до реєстрації контракту та вказівки токена для оплати газу.
Які вразливості потрібно враховувати?
Replay attack. Підписаний запит без nonce або з передбачуваним nonce може бути виконаний кілька разів. Forwarder повинен зберігати nonce per-user та інкрементувати після кожного успішного виклику.
Gas griefing. Користувач вказує мінімальний gas у запиті, relayer відправляє транзакцію з цим лімітом — контракт падає з out-of-gas, але газ витрачено. Рішення: relayer перевіряє, чи має він достатньо газу для виконання + overhead на forwarder logic.
Forwarder spoofing. Якщо контракт приймає будь-який forwarder як довірений — атакуючий може підробити msg.sender. Список довірених forwarder'ів має бути фіксованим або змінюваним тільки через multisig.
_msgSender() vs msg.sender. Найпоширеніша помилка при інтеграції EIP-2771 — використання msg.sender там, де має бути _msgSender(). Статичний аналіз через Slither ловить частину таких випадків, але не всі.
Що робити, якщо контракт уже розгорнутий?
Якщо контракт уже в production без підтримки EIP-2771 — його не можна змінити (без upgrade proxy). Є обхідний шлях: meta-транзакції через EIP-1271 (contract signatures), де користувач деплоїть власний акаунт-контракт. Але це складніше та дорожче для користувача. Висновок: якщо meta-транзакції потрібні, закладати підтримку ERC2771Context потрібно на етапі початкової розробки, не після.
Інтеграція по кроках
- Аналіз контракту — визначаємо, чи потрібно мігрувати або чи можна використовувати upgradeable proxy.
- Інтеграція ERC2771Context — замінюємо msg.sender на _msgSender(), додаємо успадкування.
- Деплой Forwarder — розгортаємо MinimalForwarder або кастомний, налаштовуємо довірені адреси.
- Backend релейера — реалізуємо на Node.js + ethers.js, додаємо ендпоінт для прийому підписаних запитів.
- Frontend інтеграція — підключаємо wagmi, готуємо EIP-712 домен і типи, викликаємо signTypedData.
- Тестування — E2E-тести з реальними гаманцями, перевірка nonce, газу, replay.
Терміни та вартість
Обсяг робіт і терміни
| Етап | Тривалість |
|---|---|
| Аналіз контракту та підготовка | 0.5 дня |
| Інтеграція ERC2771Context + тести | 1 день |
| Деплой forwarder і конфігурація | 0.5 дня |
| Backend relayer (Node.js + ethers.js) | 1–2 дні |
| Frontend інтеграція (wagmi + signTypedData) | 1 день |
| E2E-тести та фінальний деплой | 1 день |
Разом: від 3 до 5 робочих днів. З Biconomy або OpenGSN — 2–3 дні. Вартість робіт починається від $5,000, включаючи всі етапи.
Наша команда має 5+ років досвіду в Web3 та 15+ реалізованих проєктів з meta-транзакціями. Зв'яжіться з нами для попередньої оцінки вартості та термінів — проконсультуємо по стеку та сценарію. Замовте консультацію прямо зараз, щоб обговорити деталі вашого проєкту. Ми працюємо під ключ: від консультації до підтримки. Оцінимо ваш проєкт безкоштовно.







