Для разработчиков / JSON-RPC
Отличия от Ethereum
Pickle сделан в форме Ethereum, но не эквивалентен ему. Это полный список мест, где стандартный клиент получит ответ, которого не ждал, в порядке того, сколько времени стоит выяснить каждое трудным путём.
Причины revert не декодируются
error.data никогда не заполняется
A revert arrives as message text - "execution reverted: 0x<returndata>" - and error.data is absent.
Libraries decode custom errors and revert strings out of error.data, so on this chain they cannot. ethers and viem will both surface the raw message instead of a decoded error. If you need the reason, parse the hex out of the message yourself and decode it against your own ABI.
Если вам нужна причина, возвращённые данные лежат в тексте сообщения, и вы можете декодировать их сами:
try {
await client.readContract({ /* … */ });
} catch (err) {
// "execution reverted: 0x08c379a0…"
const hex = String(err.message).match(/0x[0-9a-fA-F]+/)?.[0];
// Decode that hex against your own ABI's errors, or against Error(string).
}Исторического состояния нет
eth_getBalance, eth_getTransactionCount, eth_getCode и eth_getStorageAt разбирают адрес и затем читают последний опубликованный снимок. Параметр блока принимается и молча игнорируется - запрос баланса на блоке 100 не выдаёт ошибку, он отвечает балансом на сейчас.
eth_call и eth_estimateGas делают то же самое и вдобавок игнорируют переданные им gas, gasPrice и nonce: симуляция всегда идёт при лимите газа блока 30 000 000 против последнего состояния.
Это отказывает молча, потому оно и на втором месте
Любой архивный шаблон - чтение исторического баланса, повторение состояния на прошлом блоке, вычисление снимка - возвращает здесь уверенные, правдоподобные, неверные ответы, а не ошибку. Для всего исторического читайте обозреватель.
Теги блоков схлопываются
latest, pending, safe и finalized разрешаются в одно и то же: в сохранённую вершину. А earliest разрешается в самый ранний сохранённый блок, а не в блок 0, - так что он движется вперёд, пока окно скользит.
Объекты EIP-1898 принимаются: { blockNumber } или { blockHash }, причём хеш разрешается через индекс и отвечает null, когда блок больше не хранится. Всё остальное - -32602 "block tag".
Клиент, различающий safe и finalized, чтобы решить, когда доверять результату, не получает от этой сети никакого сигнала. Финальность здесь - это расчёт на L1, и через эти теги она не видна вовсе.
Корни и фильтры нулевые
И у блоков, и у квитанций stateRoot, transactionsRoot и receiptsRoot нулевые, а logsBloom - это 512 нулевых символов.
Два следствия. Клиент, который проверяет корни, не сможет здесь проверить ничего. И клиент, который предварительно фильтрует по bloom, прежде чем забирать логи, не найдёт совпадений - фильтруйте через eth_getLogs, который читает настоящий индекс.
В остальном заголовки правильной формы Cancun, включая mixHash, withdrawalsRoot, blobGasUsed, excessBlobGas и parentBeaconBlockRoot. mixHash здесь несущий, а не декоративный: без него любой клиент на revm, включая forge script, отвергает заголовок с prevrandao not set ещё до симуляции.
Поля квитанции и транзакции
typeвсегда"0x0", какой бы конверт вы на самом деле ни отправили, и транзакция сообщает единственный плоскийgasPrice- ниmaxFeePerGas, ниmaxPriorityFeePerGas, ниaccessListобратно не приходят. Типизированные транзакции принимаются на входе; просто форма ответа тип не отражает.cumulativeGasUsed- это собственныйgasUsedтой же транзакции, а не нарастающий итог по блоку. Суммирование его по блоку ничего не задваивает, но и ничего вам не говорит.blockHashиblockNumberравныnullмежду исполнением и запечатыванием EVM-блока. В этом окне квитанция уже существует, так что проверка "квитанция не null" - не то же самое, что "включено в блок".- Транзакция несёт нестандартные добавки -
raw,miniBlockNumber,miniBlockHash, - а квитанция несёт две последние. Они полезны, и они непереносимы. eth_getBlockByNumberсfullTransactions: trueможет вернуть смешанный массив: объекты для транзакций, чьи квитанции ещё проиндексированы, и голые строки хешей для уже вытесненных.eth_getBlockReceiptsмолча пропускает вытесненные квитанции, так что массив может быть короче списка транзакций блока.
logIndex нумеруется в пределах транзакции
logIndex нумеруется по логам собственной квитанции, а не по блоку. У двух логов в одном блоке logIndex может быть 0 у обоих.
Если вы ключуете хранилище событий парой (blockNumber, logIndex) - обычный составной первичный ключ индексатора, - вы получите коллизию. Добавляйте transactionHash.
Pending - это не мемпул
Нет публичного мемпула, в котором можно было бы находиться в состоянии pending. Хеш доходит до eth_newPendingTransactionFilter и до подписки newPendingTransactions только после того, как транзакция исполнена и проиндексирована.
То есть это поток уже исполненных транзакций под вводящим в заблуждение именем. Следить за входящими транзакциями до того, как они приземлятся, нельзя, и опережать через этот интерфейс нечего.
Методы, отвечающие константами
Два метода выглядят работающими и возвращают значения, которые не являются измерениями. Оба помечены в справочнике, и оба опаснее метода, который выдаёт ошибку:
eth_feeHistoryчитает толькоblockCount, полностью игнорируетnewestBlockиrewardPercentilesи возвращаетbaseFeePerGasкак повторённое0x1иgasUsedRatioкак повторённое0.0.eth_createAccessListвозвращает{ accessList: [], gasUsed: "0x0" }, не глядя ни на параметры, ни на состояние.
Третья группа отвечает честно, но пусто, потому что понятия неприменимы: eth_accounts всегда пуст, eth_mining - false, eth_hashrate - ноль, а четыре метода про дядей возвращают ноль или null, не проверяя свои параметры.
Пространства имён, которых нет
rpc_modules объявляет eth, net, web3 и pickle. Отсутствуют и не реализованы: debug, trace, txpool и admin. Значит, debug_traceTransaction здесь нет - за трассами вызовов идите в обозреватель, у него они есть.
Методы подписи зарегистрированы и отказывают намеренно: eth_sendTransaction, eth_sign, eth_signTransaction, personal_sign и eth_coinbase отвечают -32601. Узел не хранит пользовательских ключей - подписывайте локально и пользуйтесь eth_sendRawTransaction.