Реализация EIP-1559 механизма комиссий в мобильном кошельке
До EIP-1559 кошельки угадывали gasPrice — часто переплачивали или транзакция зависала. EIP-1559, активированный в Ethereum блоке 12,965,000 (август 2021), ввёл предсказуемую структуру комиссий. Поддерживать его правильно — не просто использовать новые поля, но и объяснять их пользователю.
Структура типа транзакции 2 (EIP-1559)
Транзакция type 2 содержит три ключевых параметра вместо одного gasPrice:
-
baseFee — автоматически рассчитывается протоколом, сжигается (не идёт майнеру). Увеличивается на 12.5% при заполненном блоке, уменьшается при пустом. Получить текущий:
eth_getBlockByNumber("pending", false)→ полеbaseFeePerGas. - maxPriorityFeePerGas (tip) — вознаграждение майнеру/валидатору. Минимальный tip для включения в блок — обычно 0.1–2 Gwei.
-
maxFeePerGas — абсолютный максимум, который готов заплатить пользователь. Фактически списывается:
min(maxFeePerGas, baseFee + maxPriorityFeePerGas). Разница возвращается.
// iOS — web3swift: построение EIP-1559 транзакции
var transaction = CodableTransaction(
type: .eip1559,
to: recipientAddress,
value: amount,
data: Data()
)
transaction.maxFeePerGas = baseFee + maxPriorityFee + buffer
transaction.maxPriorityFeePerGas = maxPriorityFee
transaction.chainID = BigUInt(1) // Ethereum Mainnet
Почему maxFeePerGas важнее gasPrice
Пользователь видит maxFeePerGas = 50 Gwei, но если baseFee в момент майнинга равен 20 Gwei, а tip — 2 Gwei, заплатит 22 Gwei. Оставшиеся 28 Gwei вернутся. Это ключевое отличие от legacy-транзакций, где вся сумма уходила в доход майнера.
В UI лучше показывать не maxFeePerGas, а ожидаемую комиссию (baseFee + tip) и максимально возможную (maxFeePerGas * gasLimit). Это снижает тревогу у пользователей, видящих большой максимум.
Динамические подсказки
Рекомендуемые значения обновлять каждые 12 секунд (время блока Ethereum). Источники:
-
eth_feeHistory— расчёт percentile priority fee самостоятельно -
eth_maxPriorityFeePerGas— MetaMask-метод, поддерживается Infura, Alchemy, QuickNode - Blocknative Gas API — платный, но очень точный для Mainnet
// Android — получить рекомендованный priority fee
val maxPriorityFeeResponse = web3j.send(
Request("eth_maxPriorityFeePerGas", emptyList<Any>(), web3jService, EthMaxPriorityFeePerGas::class.java)
)
val priorityFeeWei = maxPriorityFeeResponse.maxPriorityFeePerGas
Сети без EIP-1559
BNB Chain использует legacy-формат с фиксированным gasPrice (по умолчанию 3 Gwei). Polygon поддерживает EIP-1559 с версии сети 26.x. Arbitrum и Optimism — собственные механизмы поверх EIP-1559.
Приложение должно определять тип сети и выбирать соответствующий формат транзакции автоматически. Отправка type-2 транзакции в сеть без EIP-1559 вернёт ошибку unsupported transaction type.
Сроки: 2–3 дня: определение типа сети, построение type-2 транзакций, динамические подсказки комиссий, отображение ожидаемой и максимальной стоимости, автоматический fallback на legacy для несовместимых сетей.







