Настройка gasless-транзакций (спонсирование газа)
Onboarding в Web3 ломается в одном месте: пользователь зарегистрировался, прошёл KYC, подключил кошелёк — и увидел, что для первого действия нужен ETH на газ. У него его нет. Конверсия падает. Gasless транзакции решают это, перекладывая оплату газа на протокол или спонсора.
Вариантов реализации три, и выбор между ними не очевидный.
Три архитектуры gasless: когда что использовать
Meta-transactions (EIP-2771)
Пользователь подписывает данные офчейн (без транзакции), relayer берёт эту подпись, оборачивает в транзакцию и платит газ сам. Контракт через ERC2771Context извлекает оригинального отправителя из calldata вместо msg.sender.
import "@openzeppelin/contracts/metatx/ERC2771Context.sol";
contract MyContract is ERC2771Context {
constructor(address trustedForwarder) ERC2771Context(trustedForwarder) {}
function doSomething() external {
address sender = _msgSender(); // реальный пользователь, не relayer
// логика
}
}
Когда подходит: существующий контракт с минимальными изменениями. Простая логика без account abstraction. Минус — relayer централизован, и его нужно либо держать самому, либо платить за сервис (Gelato, Biconomy).
Скрытая проблема: если контракт проверяет msg.sender в нескольких местах и часть кода не адаптирована под _msgSender() — ошибки авторизации при production нагрузке. Видели такое на проекте, где 15% транзакций падали именно из-за этого.
ERC-4337 Account Abstraction + Paymaster
ERC-4337 — стандарт account abstraction без изменений в консенсусе Ethereum. Пользователь работает через smart account (контракт-кошелёк), а не EOA. Paymaster — смарт-контракт, который берёт на себя оплату газа за пользователя по заданным правилам.
Компоненты системы:
| Компонент | Роль |
|---|---|
| UserOperation | «транзакция» от пользователя (не настоящая tx) |
| Bundler | собирает UserOps и отправляет реальную транзакцию |
| EntryPoint | глобальный контракт-координатор (0x5FF1...7780) |
| Paymaster | решает, спонсировать ли газ для конкретного UserOp |
| Smart Account | кошелёк пользователя (Safe, Biconomy, ZeroDev) |
Paymaster может спонсировать газ условно: только для первых N транзакций, только для держателей токена, только для whitelist адресов.
contract MyPaymaster is BasePaymaster {
mapping(address => bool) public whitelist;
function _validatePaymasterUserOp(
UserOperation calldata userOp,
bytes32 userOpHash,
uint256 maxCost
) internal override returns (bytes memory context, uint256 validationData) {
require(whitelist[userOp.sender], "Not whitelisted");
return ("", 0); // 0 = success
}
}
Когда подходит: новые dApp с нуля, где нужен полный UX контроль. Социальная авторизация (email login через WebAuthn + smart account). Батчинг транзакций (несколько операций в одном UserOp). Восстановление кошелька без seed phrase.
Сложность: экосистема ERC-4337 молодая. Bundler нужно либо держать самому, либо использовать Alchemy, Pimlico, Stackup. Staking Paymaster требует депозита ETH в EntryPoint. Debugging UserOp failures — отдельное искусство.
Собственный Relayer
Простейший вариант: backend-сервис с кошельком, который принимает подписанные запросы от пользователей и отправляет транзакции, оплачивая газ.
Подходит для закрытых приложений (B2B, корпоративные решения), где пользователи известны и проверены. Централизован — relayer-кошелёк становится точкой отказа и мишенью.
Что выбрать
| Критерий | Meta-tx (EIP-2771) | ERC-4337 | Свой Relayer |
|---|---|---|---|
| Сложность интеграции | Средняя | Высокая | Низкая |
| Децентрализация | Средняя | Высокая | Низкая |
| UX возможности | Базовые | Расширенные | Базовые |
| Стоимость разработки | Невысокая | Высокая | Минимальная |
| Существующий контракт | Да (с изменениями) | Нет | Да |
Реализация ERC-4337 с Pimlico
Для нового проекта — рекомендуем Pimlico как bundler + paymaster провайдер. Интеграция через permissionless.js:
import { createSmartAccountClient } from "permissionless";
import { signerToSimpleSmartAccount } from "permissionless/accounts";
import { createPimlicoPaymasterClient } from "permissionless/clients/pimlico";
const paymasterClient = createPimlicoPaymasterClient({
transport: http(`https://api.pimlico.io/v2/${chainId}/rpc?apikey=${PIMLICO_KEY}`),
entryPoint: ENTRYPOINT_ADDRESS_V07,
});
const smartAccount = await signerToSimpleSmartAccount(publicClient, {
signer: walletClient,
factoryAddress: SIMPLE_ACCOUNT_FACTORY,
entryPoint: ENTRYPOINT_ADDRESS_V07,
});
const smartAccountClient = createSmartAccountClient({
account: smartAccount,
entryPoint: ENTRYPOINT_ADDRESS_V07,
chain: mainnet,
bundlerTransport: http(bundlerUrl),
middleware: {
sponsorUserOperation: paymasterClient.sponsorUserOperation,
},
});
// Транзакция без газа для пользователя
const txHash = await smartAccountClient.sendTransaction({
to: contractAddress,
data: encodeFunctionData({ abi, functionName: "doSomething", args: [] }),
});
Мониторинг и лимиты
Gasless — это спонсирование, и без лимитов бюджет улетает быстро. Настраиваем:
- максимальный газ на UserOp
- дневной лимит на адрес
- глобальный дневной лимит
- мониторинг баланса Paymaster + автопополнение
Paymaster, у которого кончился депозит, начинает отклонять все транзакции. Пользователи видят «gasless транзакция недоступна» без объяснения причины — плохой UX. Алерты обязательны.
Срок настройки базовой gasless схемы через meta-transactions — 3-4 дня. Полноценная ERC-4337 интеграция с кастомным Paymaster, фронтендом и мониторингом — 4-5 дней.







