Разработка системы gasless cross-chain транзакций

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1 услугВсе 1306 услуг
Разработка системы gasless cross-chain транзакций
Сложная
~1-2 недели
Часто задаваемые вопросы
Направления блокчейн-разработки
Этапы блокчейн-разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1221
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1163
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    855
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1058
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    828

Разработка системы gasless cross-chain транзакций

Gasless транзакции решают один из главных барьеров Web3: пользователю нужны нативные токены на каждой цепи чтобы платить газ. Хочешь использовать Arbitrum — нужен ETH на Arbitrum. Хочешь перейти на Base — нужен ETH на Base. Это плохой UX. Gasless cross-chain идёт дальше: пользователь не только не думает о газе, но и не думает о том, на какой цепи он находится.

Компоненты системы

Gasless cross-chain — не один продукт, а стек из нескольких слоёв:

Layer 1: Meta-transactions / ERC-4337. Кто платит газ на исходной цепи.

Layer 2: Paymaster. Спонсор, который покрывает стоимость газа (или принимает оплату в ERC-20).

Layer 3: Cross-chain relayer. Кто передаёт сообщение и платит газ на целевой цепи.

Layer 4: Solver/intent executor. Кто находит оптимальный маршрут исполнения.

ERC-4337 как фундамент

Без ERC-4337 каждая gasless схема — кастомный костыль. С ERC-4337 — стандартизированный framework:

// UserOperation — стандартная единица gasless транзакции
interface UserOperation {
  sender: string;           // smart account адрес
  nonce: bigint;
  initCode: string;         // для деплоя аккаунта если не существует
  callData: string;         // что выполнить
  callGasLimit: bigint;
  verificationGasLimit: bigint;
  preVerificationGas: bigint;
  maxFeePerGas: bigint;
  maxPriorityFeePerGas: bigint;
  paymasterAndData: string; // paymaster адрес + данные
  signature: string;
}

Bundler собирает UserOperations, упаковывает в транзакцию и отправляет on-chain. Он платит газ и возмещает его из paymaster или из аккаунта пользователя.

Paymaster реализация

Paymaster — смарт-контракт, который решает «кто платит газ»:

contract ERC20Paymaster is BasePaymaster {
    address public acceptedToken;     // например USDC
    AggregatorV3Interface public priceFeed; // Chainlink price feed
    
    function _validatePaymasterUserOp(
        UserOperation calldata userOp,
        bytes32 userOpHash,
        uint256 maxCost    // максимальный газ в ETH
    ) internal override returns (bytes memory context, uint256 validationData) {
        
        // Рассчитываем сколько USDC нужно за maxCost газа
        uint256 tokenAmount = _calculateTokenAmount(maxCost);
        
        // Добавляем 10% буфер на случай роста gas price
        tokenAmount = tokenAmount * 110 / 100;
        
        // Проверяем что пользователь одобрил достаточно токенов
        require(
            IERC20(acceptedToken).allowance(userOp.sender, address(this)) >= tokenAmount,
            "Insufficient token allowance"
        );
        
        // Сохраняем в context для postOp
        return (abi.encode(userOp.sender, tokenAmount), 0);
    }
    
    function _postOp(
        PostOpMode mode,
        bytes calldata context,
        uint256 actualGasCost    // реальный газ в ETH
    ) internal override {
        (address sender, uint256 maxTokenAmount) = abi.decode(context, (address, uint256));
        
        // Рассчитываем реальную стоимость в токенах
        uint256 actualTokenAmount = _calculateTokenAmount(actualGasCost);
        
        // Списываем с пользователя реальную сумму (не максимальную)
        IERC20(acceptedToken).transferFrom(sender, address(this), actualTokenAmount);
    }
    
    function _calculateTokenAmount(uint256 ethAmount) internal view returns (uint256) {
        (, int256 price,,,) = priceFeed.latestRoundData(); // ETH/USDC price
        return (ethAmount * uint256(price)) / 1e18;
    }
}

Cross-chain gas relay

Gasless на исходной цепи — это первая половина. Вторая: кто платит газ на целевой цепи для исполнения cross-chain сообщения?

Несколько подходов:

Axelar Gas Service

При отправке сообщения через Axelar — оплачиваем газ для целевой цепи заранее, в нативном токене исходной цепи:

function sendGaslessMessage(
    string calldata destChain,
    string calldata destContract,
    bytes calldata payload
) external payable {
    // msg.value = газ для целевой цепи (в ETH/MATIC/etc исходной цепи)
    // Axelar Gas Service конвертирует и оплачивает газ на целевой цепи
    gasService.payNativeGasForContractCall{value: msg.value}(
        address(this), destChain, destContract, payload, msg.sender
    );
    
    gateway.callContract(destChain, destContract, payload);
}

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

LayerZero с нативным gas drop

LayerZero позволяет «дропнуть» нативный газ на адрес получателя на целевой цепи:

function sendWithGasDrop(
    uint16 dstChainId,
    bytes calldata payload,
    address payable refundAddress,
    address zroPaymentAddress,
    uint256 dstNativeAmount,   // сколько нативного токена получит адрес на dst
    address dstNativeAddress   // кто получит нативные токены
) external payable {
    bytes memory adapterParams = abi.encodePacked(
        uint16(2),             // version 2 = с airdrop
        uint256(200000),       // gas limit на dst
        dstNativeAmount,
        dstNativeAddress
    );
    
    lzEndpoint.send{value: msg.value}(
        dstChainId,
        abi.encode(destContract),
        payload,
        refundAddress,
        zroPaymentAddress,
        adapterParams
    );
}

Это позволяет «снабдить» новый адрес на целевой цепи небольшим количеством ETH для первых транзакций.

Relayer сеть с собственными нодами

Для полностью кастомной системы — собственная сеть relayer нод, каждая из которых держит баланс нативных токенов на всех поддерживаемых цепях:

class CrossChainRelayer {
  // Балансы на всех цепях
  private chainWallets: Map<number, Wallet> = new Map();
  
  async relayMessage(
    sourceChain: number,
    destChain: number,
    contractAddress: string,
    calldata: string,
    userSignature: string
  ): Promise<string> {
    // Верифицируем подпись пользователя
    const isValid = await this.verifyUserSignature(userSignature, calldata);
    if (!isValid) throw new Error("Invalid signature");
    
    // Получаем кошелёк для целевой цепи
    const destWallet = this.chainWallets.get(destChain);
    if (!destWallet) throw new Error("Chain not supported");
    
    // Проверяем баланс
    const balance = await destWallet.provider!.getBalance(destWallet.address);
    const gasEstimate = await destWallet.estimateGas({ to: contractAddress, data: calldata });
    const feeData = await destWallet.provider!.getFeeData();
    const gasCost = gasEstimate * feeData.maxFeePerGas!;
    
    if (balance < gasCost * 2n) {
      // Нужна пополнение баланса relayer
      await this.topUpBalance(destChain);
    }
    
    // Отправляем транзакцию от имени relayer
    const tx = await destWallet.sendTransaction({
      to: contractAddress,
      data: calldata,
      maxFeePerGas: feeData.maxFeePerGas,
      maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
    });
    
    // Списываем с пользователя в нашей системе (или через Paymaster)
    await this.chargeUser(userSignature, gasCost);
    
    return tx.hash;
  }
}

Intent-based gasless архитектура

Самый продвинутый вариант: пользователь подписывает intent, solver находит оптимальный маршрут и исполняет его, оплачивая всё с прибыли от арбитража:

interface GaslessIntent {
  user: string;
  sourceChain: number;
  destChain: number;
  action: string;          // "swap", "stake", "transfer"
  inputToken: string;
  inputAmount: string;
  minOutputAmount: string; // solver должен обеспечить minimum output
  deadline: number;
  signature: string;
}

// Solver берёт intent и исполняет его
// Прибыль: разница между реальным output и minOutputAmount
// Из этой прибыли оплачивается газ на обеих цепях
class IntentSolver {
  async solve(intent: GaslessIntent): Promise<void> {
    // Расчёт профитабельности
    const route = await this.findOptimalRoute(intent);
    const expectedOutput = await this.simulate(route, intent);
    const gasCosts = await this.estimateTotalGasCosts(route);
    
    const profit = expectedOutput - BigInt(intent.minOutputAmount) - gasCosts;
    
    if (profit < this.minProfitThreshold) {
      return; // Нерентабельно
    }
    
    // Исполняем
    await this.executeRoute(route, intent);
  }
}

Permit2 для gasless approvals

Традиционный approve требует отдельную транзакцию (gas). С Permit2 (Uniswap):

// Пользователь подписывает разрешение off-chain (zero gas)
const permit = {
  permitted: { token: USDC_ADDRESS, amount: parseUnits("100", 6) },
  spender: RELAYER_ADDRESS,
  nonce: await getPermitNonce(userAddress),
  deadline: Math.floor(Date.now() / 1000) + 3600,
};

const signature = await signer._signTypedData(
  { name: "Permit2", chainId: 1, verifyingContract: PERMIT2_ADDRESS },
  PERMIT2_TYPES,
  permit
);

// Relayer использует подпись для transferFrom без отдельного approve
await permit2Contract.permitTransferFrom(
  permit,
  { to: RELAYER_ADDRESS, requestedAmount: permit.permitted.amount },
  userAddress,
  signature
);

Экономика системы

Кто платит за газ в итоге? Варианты:

Модель Кто платит Когда подходит
Sponsored (freemium) Приложение Onboarding, gaming, loyalty
ERC-20 paymaster Пользователь в stablecoin DeFi, trading
Solver extracts surplus Solver из арбитража Intent-based протоколы
Fee token swap Система конвертирует fee token Общий случай

Стек

Smart contracts: Solidity + ERC-4337 + Permit2 + Foundry Bundler: Pimlico, StackUp, Alchemy (hosted) или Alto (self-hosted) Paymaster: кастомный ERC20Paymaster + Pimlico sponsored Cross-chain: Axelar Gas Service или LayerZero с adapterParams Relayer: Node.js + TypeScript + viem Frontend: wagmi v2 + permissionless.js

Сроки

  • Gasless на одной цепи (ERC-4337 + ERC-20 Paymaster): 3-4 недели
  • Cross-chain gas relay (Axelar/LayerZero интеграция): +3-4 недели
  • Intent solver (profitable solving + routing): +4-6 недель
  • Production + мониторинг + security audit: +4-6 недель
  • Итого полная система: 3-4 месяца