개발자를 위한 문서 / JSON-RPC

Ethereum과 다른 점

Pickle은 Ethereum의 형태를 하고 있을 뿐 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.

사유가 필요하다면 반환 데이터는 메시지 텍스트 안에 있으므로 직접 디코딩할 수 있습니다.

javascript
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 정산이며, 이 태그들로는 전혀 보이지 않습니다.

루트와 블룸이 0입니다

블록과 영수증 양쪽에서 stateRoot, transactionsRoot, receiptsRoot는 0이고, logsBloom은 0이 512개입니다.

결과는 두 가지입니다. 루트를 검증하는 클라이언트는 여기서 아무것도 검증할 수 없습니다. 그리고 로그를 가져오기 전에 블룸으로 미리 거르는 클라이언트는 아무것도 맞히지 못합니다 - 실제 인덱스를 읽는 eth_getLogs로 거르십시오.

그 밖에 헤더는 제대로 Cancun 형태이며, mixHash, withdrawalsRoot, blobGasUsed, excessBlobGas, parentBeaconBlockRoot를 포함합니다. mixHash는 장식이 아니라 하중을 받습니다. 그것이 없으면 forge script를 포함한 모든 revm 기반 클라이언트가 시뮬레이션 전에 prevrandao not set으로 헤더를 거부합니다.

영수증과 트랜잭션 필드

  • 실제로 어떤 엔벨로프를 보냈든 type은 항상 "0x0"이고, 트랜잭션은 평평한 gasPrice 하나만 보고합니다 - maxFeePerGas, maxPriorityFeePerGas, accessList는 돌아오지 않습니다. 타입이 붙은 트랜잭션은 들어올 때 받아들여집니다. 응답 형태가 그 타입을 반영하지 않을 뿐입니다.
  • cumulativeGasUsed는 블록의 누계가 아니라 그 트랜잭션 자신의 gasUsed입니다. 블록 전체에 걸쳐 더해도 중복 계산되는 것은 없지만 알려 주는 것도 없습니다.
  • blockHash와 blockNumber는 실행과 EVM 봉인 사이에서 null입니다. 그 구간에도 영수증은 존재하므로 "영수증이 null이 아니다"는 "블록에 포함되었다"와 같은 검사가 아닙니다.
  • 트랜잭션에는 표준이 아닌 추가 필드가 붙습니다 - raw, miniBlockNumber, miniBlockHash - 영수증에는 뒤의 둘이 붙습니다. 유용하지만 이식성이 없습니다.
  • fullTransactions: true를 준 eth_getBlockByNumber는 섞인 배열을 돌려줄 수 있습니다. 영수증이 아직 인덱싱되어 있는 트랜잭션은 객체로, 이미 축출된 것은 해시 문자열로 나옵니다.
  • eth_getBlockReceipts는 축출된 영수증을 조용히 빠뜨리므로, 배열이 블록의 트랜잭션 목록보다 짧아질 수 있습니다.

logIndex는 트랜잭션 단위입니다

logIndex는 블록이 아니라 자기 영수증의 로그들에 대해 매겨집니다. 한 블록 안의 두 로그가 둘 다 logIndex 0을 가질 수 있습니다.

이벤트 저장소를 (blockNumber, logIndex)로 키잉하면 - 인덱서에서 흔한 복합 기본 키입니다 - 충돌하게 됩니다. transactionHash를 포함하십시오.

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는 0이며, 네 개의 엉클 메서드는 파라미터를 검증하지 않고 0이나 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을 쓰십시오.