English version: /en/doc/introduction.html
What is Kasane
TL;DR
Kasane は、ICP canister 上で EVM実行を提供するプロジェクトです。
公開導線は「canister Candid API」と「Gateway JSON-RPC」です。
JSON-RPCは Ethereum完全互換ではなく、開発用途の制限付き互換です。
互換ターゲットは Ethereum JSON-RPC + EVM実行意味論で、OP/Superchain互換は非目標です。
できること
- Ethereum風 JSON-RPC で基本的な参照/送信を行う
- canister query/update で直接EVM機能を呼ぶ
- indexer で
export_blocksを pull し、Postgresへ保持する
主な制約(現行実装)
- Ethereum JSON-RPC 互換は制限付き(未対応メソッドは互換仕様ページを参照)
- node運用向けワークフローの提供(本書対象外)
互換の立ち位置
- 明示対象: Ethereum JSON-RPC 互換(制限付き)
- 非目標: OP-stack / Superchain 互換
- 注意:
eth_sendRawTransactionの成功は submit成功のみ。実行成功は receiptstatus=0x1で判定
読者対象
- EVM dApp開発者
- スマートコントラクト開発者
- バックエンド統合開発者
- indexer開発者
根拠
README.md(運用サマリ、互換方針)tools/rpc-gateway/README.md(Gatewayの互換表)crates/ic-evm-wrapper/evm_canister.did(公開I/F)
互換仕様の正本
- JSON-RPC互換ポリシーの正本:
./rpc/overview.md - メソッド差分の詳細:
./compatibility/json-rpc-deviations.md
English version: /en/doc/quickstart.html
Quickstart (Gateway + Candid)
TL;DR
- 既定ネットワークは public testnet(
chain_id=4801360、RPC:https://rpc-testnet.kasane.network)。 - 導線は2つ: Path A(Gateway JSON-RPC)/ Path B(canister Candid直呼び)。
- 送信成功判定は submit結果ではなく
eth_getTransactionReceipt.status。 tx_idとeth_tx_hashは別物。- deploy/call は署名済み raw tx を用いた送信手順に統一する。
できること / できないこと
できること
- 接続確認(chain id / block number)
- ネイティブ送金(署名済みraw tx投入)
- receipt監視(成功/失敗判定)
- query系の状態参照(balance/code/storage/call/estimate)
できないこと(現行)
- Ethereum標準の pending/mempool API 前提のフロー(
eth_pendingTransactionsなど) - (補足)canister直呼びでは
get_pending(tx_id)による個別追跡は可能 - WebSocket購読(
eth_subscribe) eth_getLogsの完全互換(filter制約あり)
互換ポリシー詳細は ./rpc/overview.md と ./compatibility/json-rpc-deviations.md を参照。
前提条件
- 公開RPC:
https://rpc-testnet.kasane.network - chain id:
4801360 - canister id(testnet運用値):
4c52m-aiaaa-aaaam-agwwa-cai dfx(canister query/updateを使う場合)- Gateway経由で送信する場合は署名済み raw tx を用意
Path A: Gateway JSON-RPC
1) 接続確認
RPC_URL="https://rpc-testnet.kasane.network"
curl -s -X POST "$RPC_URL" -H 'content-type: application/json' \
--data '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'
curl -s -X POST "$RPC_URL" -H 'content-type: application/json' \
--data '{"jsonrpc":"2.0","id":2,"method":"eth_blockNumber","params":[]}'
期待結果:
eth_chainIdが0x4944d0(10進4801360)eth_blockNumberが0x...形式
2) 送金(署名済み raw tx)
RAW_TX="0x<signed_raw_tx_hex>"
curl -s -X POST "$RPC_URL" -H 'content-type: application/json' \
--data "{\"jsonrpc\":\"2.0\",\"id\":3,\"method\":\"eth_sendRawTransaction\",\"params\":[\"$RAW_TX\"]}"
期待結果:
resultに0x...tx hash が返る(Gatewayがtx_idからeth_tx_hashを解決)
3) receipt監視(成功判定)
TX_HASH="0x<tx_hash_from_send>"
curl -s -X POST "$RPC_URL" -H 'content-type: application/json' \
--data "{\"jsonrpc\":\"2.0\",\"id\":4,\"method\":\"eth_getTransactionReceipt\",\"params\":[\"$TX_HASH\"]}"
判定:
status == 0x1: 実行成功status == 0x0: 実行失敗(submit成功でも失敗しうる)result == null: まだ採掘反映前
代表エラー
-32602 invalid params: 引数形式不正-32001 resource not found: prune境界または対象なし-32000 state unavailable: migration/corrupt等の状態
落とし穴
eth_sendRawTransaction成功だけで完了扱いにするtx_idとeth_tx_hashを混同する
Path B: canister Candid直呼び
1) 接続確認(query)
CANISTER_ID="4c52m-aiaaa-aaaam-agwwa-cai"
NETWORK="ic"
dfx canister call --network "$NETWORK" --query "$CANISTER_ID" rpc_eth_chain_id '( )'
dfx canister call --network "$NETWORK" --query "$CANISTER_ID" rpc_eth_block_number '( )'
2) submit_ic_tx(IcSynthetic)
submit_ic_tx は record を受け取る:
to: opt vec nat8(Some時は20 bytes、Noneはcreate)value: natgas_limit: nat64nonce: nat64max_fee_per_gas: natmax_priority_fee_per_gas: natdata: vec nat8
IcSynthetic では from をpayloadに含めません。
wrapper が msg_caller() と canister_self() を付与して core の TxIn::IcSynthetic に渡し、sender を決定します。
# 例: to=0x...01 / value=0 / gas_limit=500000 / data=""
# 注: fee は現行の最小受理条件(min_gas_price/min_priority_fee)以上に設定する。
TO_BYTES="$(python - <<'PY'
to = bytes.fromhex('0000000000000000000000000000000000000001')
print('; '.join(str(b) for b in to))
PY
)"
dfx canister call --network "$NETWORK" "$CANISTER_ID" submit_ic_tx "(record {
to = opt vec { $TO_BYTES };
value = 0 : nat;
gas_limit = 500000 : nat64;
nonce = 0 : nat64;
max_fee_per_gas = 500000000000 : nat;
max_priority_fee_per_gas = 250000000000 : nat;
data = vec { };
})"
2.0) submit_ic_tx 送信手順
運用は次の順で固定すると事故を減らせます。
- 送信前に chain/network を確認する
rpc_eth_chain_idが4801360であること
- 送信元nonceを確認する
expected_nonce_by_address(20 bytes)を呼び、現在nonceを取得
- fee/gasを決める
rpc_eth_gas_price/rpc_eth_max_priority_fee_per_gasを参照し、下限以上を設定
submit_ic_tx(record)を1回送る- 返り値
tx_idを保存
- 返り値
- 実行結果を追跡する
get_pending(tx_id)で状態確認get_receipt(tx_id)が取得できたらstatusで成功/失敗判定
注意:
submit_ic_txの成功は「受付成功」です。実行成功はreceipt.statusで判定してください。tx_idは内部キーであり、eth_tx_hashとは別です。
2.1) submit_ic_tx 検証フロー(重要)
- pre-submit guard
- anonymous拒否(
auth.anonymous_forbidden) - migration/cycle状態で write拒否(
ops.write.*)
- anonymous拒否(
- decode/検証
- payloadサイズ/形式
- sender導出失敗は
arg.principal_to_evm_derivation_failed - fee条件不一致は
submit.invalid_fee - nonce不一致は
submit.nonce_too_low/submit.nonce_gap/submit.nonce_conflict
- 正常時は
tx_idを返し、採掘は非同期(auto-production)
3) nonce取得
ADDR_BLOB='"\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00"'
dfx canister call --network "$NETWORK" --query "$CANISTER_ID" expected_nonce_by_address "(blob $ADDR_BLOB)"
注意:
expected_nonce_by_addressは 20 bytes address のみ受理- 32 bytes(bytes32エンコードprincipalの誤投入)には明示エラーを返す
4) raw tx投入(EthSigned)
既存ヘルパー eth_raw_tx を使って raw tx bytes を作る:
CHAIN_ID=4801360
PRIVKEY="<YOUR_PRIVKEY_HEX>"
RAW_TX_BYTES=$(cargo run -q -p ic-evm-core --features local-signer-bin --bin eth_raw_tx -- \
--mode raw \
--privkey "$PRIVKEY" \
--to "0000000000000000000000000000000000000001" \
--value "0" \
--gas-price "500000000000" \
--gas-limit "21000" \
--nonce "0" \
--chain-id "$CHAIN_ID")
dfx canister call --network "$NETWORK" "$CANISTER_ID" rpc_eth_send_raw_transaction "(vec { $RAW_TX_BYTES })"
5) tx_id 追跡(IcSynthetic)
submit_ic_tx の戻り値は eth_tx_hash ではなく内部キー tx_id です。
追跡は以下を使います。
get_pending(tx_id)(Queued/Included/Dropped/Unknown)get_receipt(tx_id)(実行結果)
6) eth_sendRawTransaction の返却注意(Gateway)
- 通常は
eth_tx_hashが返る。 - ただし内部で
tx_id -> eth_tx_hash解決に失敗した場合、-32000(submit succeeded but eth hash is unavailable)を返す。
落とし穴
- queryメソッドを update呼び出しして失敗する
- address 20bytes要件を満たさない(
expected_nonce_by_address) submit_ic_txのtx_idをeth_tx_hashと混同するsubmit_ic_tx成功だけで実行成功とみなす
Deploy & Call(運用手順)
前提
- bytecode 生成済みであること(
dataフィールドに deploy bytecode を設定) - 署名環境(private key / chain id一致)が準備済みであること
- nonce と fee を事前に取得・設定すること
実行フロー
eth_estimateGasで deploy tx の gas を見積もる。- deploy用 raw tx を生成し、
eth_sendRawTransactionで送信する。 - 返却された
eth_tx_hashをeth_getTransactionReceiptで追跡する。 receipt.contractAddressにデプロイ先アドレスが入ることを確認する。
根拠
README.mdtools/rpc-gateway/README.mddocs/api/rpc_eth_send_raw_transaction_payload.mdcrates/evm-core/src/test_bin/eth_raw_tx.rscrates/ic-evm-wrapper/evm_canister.didtools/rpc-gateway/src/handlers.tscrates/ic-evm-wrapper/src/lib.rs(submit_ic_tx,expected_nonce_by_address)crates/evm-core/src/chain.rs(TxIn::IcSynthetic, submit検証)
English version: /en/doc/concepts/accounts-keys.html
Accounts & Keys
TL;DR
- senderは
EthSignedとIcSyntheticで導出経路が異なる。 expected_nonce_by_addressは20 bytes address前提。IcSyntheticはfromをpayloadで受け取らず、caller情報から決定される。
できること
- Eth signed txの署名senderを使う
- Principal由来sender(IcSynthetic)を使う
制約
- bytes32風の値を20 bytes addressとして扱う
EthSigned と IcSynthetic の違い
EthSigned- 署名済みraw txから sender を復元
- chain id検証を伴う
IcSynthetic- wrapperが
msg_caller()とcanister_self()を付与してTxIn::IcSyntheticとして投入 - payloadに
fromを持たない - sender導出失敗は
AddressDerivationFailed系エラーになる
- wrapperが
IcSynthetic で必ず押さえる点
submit_ic_txの入力は Candidrecord(to/value/gas_limit/nonce/max_fee_per_gas/max_priority_fee_per_gas/data)- 内部保存時の canonical bytes は
to_flag(0/1)形式 - nonce参照は
expected_nonce_by_addressを使う - 戻り値は
eth_tx_hashではなくtx_id - 実行確定は submit時点ではなく、後続blockで receipt 参照して判断する
安全な使い方
- callerに対応する20 bytesアドレスを確定する
expected_nonce_by_addressで nonce を取るsubmit_ic_txを送るget_pending(tx_id)/get_receipt(tx_id)で追跡する
pending/mempool運用ポリシーの正本は ../rpc/overview.md を参照。
落とし穴
- Principalエンコード値をそのままaddressとして投入する
expected_nonce_by_addressに20 bytes以外を渡すtx_idをeth_tx_hashと同一視する- submit成功を実行成功と誤認する
根拠
crates/ic-evm-wrapper/src/lib.rs(expected_nonce_by_address)crates/evm-core/src/tx_decode.rs(IcSynthetic/EthSigned)crates/evm-core/src/chain.rs(TxIn::IcSynthetic)README.md
English version: /en/doc/concepts/transactions-fees.html
Transactions & Fees
TL;DR
- 対応tx typeは Legacy/2930/1559、4844/7702は非対応。
- feeは base fee + priority fee モデル(制限付き)。
手数料モデル
compute_next_base_feeで次ブロックbase fee更新compute_effective_gas_priceで実効価格を計算
落とし穴
- chain id不一致txを送る
- priority/max feeの整合条件を満たさない
根拠
crates/evm-core/src/tx_decode.rscrates/evm-core/src/base_fee.rscrates/evm-core/src/revm_exec.rs
English version: /en/doc/concepts/blocks-receipts-logs.html
Blocks, Receipts, Logs
TL;DR
- block/receipt/log は Candid型として公開される。
- receipt には
status,gas_used,effective_gas_price,contract_address,logsを含む。
ポイント
logs[].logIndexはブロック内通番- receipt lookup は
Found/NotFound/PossiblyPruned/Pruned
落とし穴
- pruned履歴を永続参照できる前提で設計する
tx_idとeth_tx_hashの照会経路を混在させる
根拠
crates/ic-evm-wrapper/evm_canister.didcrates/ic-evm-rpc/src/lib.rstools/rpc-gateway/src/handlers.ts
English version: /en/doc/concepts/finality-reorg.html
Finality & Reorg
TL;DR
- 本実装は単一ブロックプロデューサ(sequencer)前提で、reorgを前提とする運用モデルは想定しない。
- submitとexecuteは分離されるため、receipt監視が必要。
見え方
eth_sendRawTransactionは投入- 実行確定は後続blockで反映
注意点
- submit成功時点で状態確定したとみなす
- Ethereum L1のfork前提ロジックをそのまま持ち込む
根拠
README.mdtools/rpc-gateway/README.mdcrates/ic-evm-wrapper/src/lib.rs
English version: /en/doc/compatibility/ethereum-differences.html
Ethereum Differences
TL;DR
- 互換対象は Ethereum JSON-RPC + EVM実行意味論(完全互換ではない)。
- tx type は Legacy/EIP-2930/EIP-1559 を受理、EIP-4844/EIP-7702 は現状未受理。
- opcode は Kasane 独自の追加/改変を行わず、採用中 spec(現状PRAGUE)の範囲に従う。
- pending/mempool 系APIは一部未実装(
eth_pendingTransactionsなど)。 - canister Candid では
get_pending(tx_id)による個別追跡を提供する。 - 単一ブロックプロデューサ(sequencer)前提で、reorgを前提とする運用モデルは想定しない。
注: pending/mempoolの運用ポリシーの正本は ../rpc/overview.md。
対応範囲
できること
- Eth signed tx の投入・実行・receipt参照
eth_call/eth_estimateGas(制限付き)- ブロック/tx/receipt/log の参照
制約がある領域
- 4844 blob tx / 7702 authorization tx は現状未受理
- mempoolやfilter/WebSocket購読は制限付き(互換差分あり)
トランザクション互換
- Supported
- Legacy (RLP)
- EIP-2930 (
tx_type=1) - EIP-1559 (
tx_type=2)
- 現在未受理
- EIP-4844 (
type=0x03) - EIP-7702 (
type=0x04)
- EIP-4844 (
opcode差分
- Kasane 独自の opcode 追加/挙動改変は行わない。
- 実際の有効範囲は
revmの採用specに依存し、現行デフォルトはPRAGUE。
feeモデル差分
base_feeは保持され、compute_next_base_feeで更新される。effective_gas_priceはmax_fee,max_priority_fee,base_feeから計算。eth_gasPriceはmax(base_fee + max(推定priority,min_priority), min_gas_price)を返す。
finality/reorg差分
- 単一ブロックプロデューサ(sequencer)前提
auto-production後ブロックは final 扱い(reorg前提では扱わない)latest/pending/safe/finalizedの一部は head扱いの制約あり
代表エラー
DecodeError::UnsupportedType(4844/7702)DecodeError::WrongChainIdDecodeError::LegacyChainIdMissing
落とし穴
- Ethereum L1と同じ pending/finalityモデルを前提にする
- 4844/7702 tx を送って互換がある前提で実装する
根拠
crates/evm-core/src/tx_decode.rscrates/evm-core/tests/phase1_eth_decode.rscrates/evm-core/src/base_fee.rscrates/evm-core/src/revm_exec.rsvendor/revm/crates/handler/src/mainnet_builder.rsvendor/revm/crates/primitives/src/hardfork.rstools/rpc-gateway/README.mdREADME.md
English version: /en/doc/compatibility/json-rpc-deviations.html
JSON-RPC Deviations
TL;DR
- 実装済みメソッドは限定される。
eth_getLogsは制約が強いが、blockHashは条件付き対応、topics[0]の OR配列は対応済み。- blockTagはメソッドごとに制約があり、
latest系に加えてearliest/QUANTITYを受理するが historical は多くが非対応。 eth_sendRawTransactionは submit API委譲で、実行成功は receipt で確認する。eth_feeHistoryは対応済み(blockCountは number/QUANTITY/10進文字列を受理)。eth_gasPriceはbase_fee単体ではなく、受理条件に寄せた推定値を返す。
適用範囲: 本ページはJSON-RPC差分の詳細。全体ポリシーは ../rpc/overview.md を正本とする。
メソッド別差分(要点)
eth_getBalancelatest/pending/safe/finalized/earliest/QUANTITYを受理- 実質 historical は
exec.state.unavailableまたはinvalid.block_range.out_of_window
eth_getTransactionCountlatest/pending/safe/finalized/earliest/QUANTITYを受理pendingは pending nonceearliestや過去block nonceは非対応(historical nonce未提供)
eth_getCodelatest/pending/safe/finalized/earliest/QUANTITYを受理- 実質 historical は
exec.state.unavailableまたはinvalid.block_range.out_of_window
eth_getStorageAtlatest/pending/safe/finalized/earliest/QUANTITYを受理- slotは QUANTITY/DATA(32 bytes) 受理
- 実質 historical は
exec.state.unavailableまたはinvalid.block_range.out_of_window
eth_call,eth_estimateGaslatest/pending/safe/finalized/earliest/QUANTITYを受理- historical execution は非対応(
exec.state.unavailable/invalid.block_range.out_of_window) - 未対応フィールドは
-32602
eth_getLogsblockHashは条件付き対応(fromBlock/toBlock併用不可、直近Nブロック走査で解決)address単一のみtopics[0]OR配列は対応(最大16件)topics[1+]条件は非対応- 範囲超過は
-32005
eth_feeHistoryblockCountはnumber/QUANTITY/ 10進文字列を受理blockCount <= 256pendingは現状latest同義
eth_maxPriorityFeePerGas- 観測データ不足時は
-32000(state unavailable)
- 観測データ不足時は
eth_gasPricemax(base_fee + max(推定priority,min_priority), min_gas_price)を返す
未対応メソッド
eth_getBlockByHasheth_newFilter/eth_getFilterChanges/eth_uninstallFiltereth_subscribe/eth_unsubscribeeth_pendingTransactions
エラー設計
-32602: invalid params-32000: state unavailable / execution failed-32001: resource not found(pruned含む)-32005: limit exceeded(logs)- (補足)submit内部エラーは
-32603が返る経路あり
落とし穴
- 標準ノード前提の
eth_getLogsfilter(address[]やtopics[1+])をそのまま投げる eth_sendRawTransactionだけで成功確定扱いにするeth_getLogsのblockHashが常に解決できる前提で使う(走査上限あり)
根拠
tools/rpc-gateway/src/handlers.tstools/rpc-gateway/README.mdcrates/ic-evm-rpc/src/lib.rs
English version: /en/doc/compatibility/precompiles-system-contracts.html
Precompiles & System Contracts
TL;DR
- precompile 失敗は
exec.halt.precompile_errorとして分類される。 - Kasane は
revmの mainnet precompile set を利用し、独自のアドレス上書きはしていない。 - 現行実装は
SpecId::default = PRAGUEのため、OSAKA追加の0x0100 (P256VERIFY)はデフォルトでは有効化されない。 - opcode差分の解説はこのページの責務外(
ethereum-differences.mdを参照)。
運用方針
- precompile失敗の分類は
exec.halt.precompile_errorを一次判定に使う。 - precompile依存機能は mainnet 投入前に対象パスをスモークして動作を固定化する。
対応precompile(現行デフォルト: PRAGUE)
| Address | Name | 導入段階 | 備考 |
|---|---|---|---|
0x01 | ECREC | Homestead | secp256k1 ecrecover |
0x02 | SHA256 | Homestead | |
0x03 | RIPEMD160 | Homestead | |
0x04 | ID | Homestead | identity |
0x05 | MODEXP | Byzantium | Prague では Berlin gas式が適用 |
0x06 | BN254_ADD | Byzantium | Istanbul 以降はガス更新版 |
0x07 | BN254_MUL | Byzantium | Istanbul 以降はガス更新版 |
0x08 | BN254_PAIRING | Byzantium | Istanbul 以降はガス更新版 |
0x09 | BLAKE2F | Istanbul | |
0x0a | KZG_POINT_EVALUATION | Cancun | 現行ビルドで有効(検証バックエンドは c-kzg / blst / arkworks) |
0x0b | BLS12_G1ADD | Prague | EIP-2537 |
0x0c | BLS12_G1MSM | Prague | EIP-2537 |
0x0d | BLS12_G2ADD | Prague | EIP-2537 |
0x0e | BLS12_G2MSM | Prague | EIP-2537 |
0x0f | BLS12_PAIRING_CHECK | Prague | EIP-2537 |
0x10 | BLS12_MAP_FP_TO_G1 | Prague | EIP-2537 |
0x11 | BLS12_MAP_FP2_TO_G2 | Prague | EIP-2537 |
OSAKAで追加されるが、現行デフォルトでは未有効
0x0100(P256VERIFY, RIP-7212)
実装上の前提
evm-coreはContext::mainnet().build_mainnet_with_inspector(...)でrevmの mainnet builder をそのまま使う。- mainnet builder 側で
EthPrecompiles::new(spec)を使って precompile set が決まる。 SpecId::default()はPRAGUE。
観測可能な事実
- 実行系エラー分類に
PrecompileErrorが存在 - wrapper側で
exec.halt.precompile_errorにマップされる
安全な使い方
- precompile依存機能では、
exec.halt.precompile_errorを監視/分類してリトライ判定を分離する - precompile前提のdAppでは、mainnet投入前に当該pathをスモークする
落とし穴
- ingress検証とruntime precompile責務を混同する
0x0100 (P256VERIFY)を常に有効と誤認する0x0a (KZG)の検証バックエンド差分(c-kzg/blst/arkworks)を考慮しない
関連ページ
ethereum-differences.md(opcode/tx type/finality差分)
根拠
crates/ic-evm-wrapper/src/lib.rs(exec.halt.precompile_error)crates/evm-core/src/revm_exec.rscrates/evm-core/Cargo.toml(revmfeature)vendor/revm/crates/handler/src/mainnet_builder.rsvendor/revm/crates/primitives/src/hardfork.rsvendor/revm/crates/precompile/src/lib.rsvendor/revm/crates/precompile/src/id.rsvendor/revm/crates/precompile/src/bls12_381_const.rsvendor/revm/crates/precompile/src/secp256r1.rs
English version: /en/doc/rpc/overview.html
RPC Overview
TL;DR
- Gateway は canister Candid API を JSON-RPC 2.0 に変換する層です。
- 互換は制限付きで、未実装メソッドがあります。
- 入力不正は主に
-32602、状態不整合は-32000/-32001。
対応範囲
web3_*,net_*,eth_*の一部- 実装メソッドは
handleRpcの switch が正本
主なユースケースと制約
- 基本参照、
call、estimate、raw tx投入に対応 - filter/ws/pending は互換差分あり(詳細は各ページ参照)
Pending/Mempoolポリシー
- Ethereum互換APIとしての pending/mempool(例:
eth_pendingTransactions,eth_subscribe)は現状未実装。 - ただし canister Candid には
get_pending(tx_id)があり、送信済み tx を個別追跡できる。 - 送信成功判定は submit戻り値ではなく receipt ベース(
status)で行う。 - 詳細は以下を参照:
../quickstart.md../compatibility/json-rpc-deviations.md../compatibility/ethereum-differences.md../concepts/accounts-keys.md../_generated/interfaces.md
根拠
tools/rpc-gateway/src/handlers.ts(handleRpc)tools/rpc-gateway/README.mdcrates/ic-evm-wrapper/src/lib.rs(get_pending)
English version: /en/doc/rpc/chain-and-block.html
Chain & Block Methods
TL;DR
eth_chainId,net_version,eth_blockNumber,eth_getBlockByNumberを提供。eth_getBlockByNumberは prune範囲で-32001。
メソッド
eth_chainId-> canisterrpc_eth_chain_idnet_version->rpc_eth_chain_idを10進文字列化eth_blockNumber-> canisterrpc_eth_block_numbereth_getBlockByNumber-> canisterrpc_eth_get_block_by_number_with_status
blockTag制約
latest/pending/safe/finalizedは head扱い- prune済みは
resource not found
根拠
tools/rpc-gateway/src/handlers.tscrates/ic-evm-rpc/src/lib.rs
詳細な制約差分は ../compatibility/json-rpc-deviations.md を参照。
English version: /en/doc/rpc/transactions-and-receipts.html
Transaction & Receipt Methods
TL;DR
- tx参照は
eth_tx_hash基準。 - receiptは
PossiblyPruned/Prunedを明示的に返しうる。
メソッド
eth_getTransactionByHash->rpc_eth_get_transaction_by_eth_hasheth_getTransactionReceipt->rpc_eth_get_transaction_receipt_with_status_by_eth_hash
注意
tx_idは内部キー、外部連携はeth_tx_hashを使う。- 内部運用で tx_id を直接引く場合は
rpc_eth_get_transaction_receipt_with_status_by_tx_idを使う。 - migration/corrupt時は
state unavailableエラー。
根拠
tools/rpc-gateway/src/handlers.tscrates/ic-evm-rpc/src/lib.rs
English version: /en/doc/rpc/state.html
State Methods
TL;DR
eth_getBalance,eth_getTransactionCount,eth_getCode,eth_getStorageAtを提供。- blockTag は
latest/pending/safe/finalized/earliest/QUANTITYを受理するが、historical は多くが制約付き。
メソッド
eth_getBalance->rpc_eth_get_balanceeth_getTransactionCount->rpc_eth_get_transaction_count_ateth_getCode->rpc_eth_get_codeeth_getStorageAt->rpc_eth_get_storage_at
主な制約
- balance/code/storage:
QUANTITY==head以外の historical はstate unavailable/ out-of-window になり得る - tx count:
pendingは pending nonce を返す。earliest/ 過去nonce は現状未提供
詳細は ../compatibility/json-rpc-deviations.md と ./overview.md を参照。
根拠
tools/rpc-gateway/src/handlers.tscrates/ic-evm-rpc/src/lib.rstools/rpc-gateway/README.md
English version: /en/doc/rpc/call-estimate-send.html
Call, Estimate, Send
TL;DR
eth_call/eth_estimateGasは callObject制約あり。eth_estimateGasはgas_usedではなく、成功する最小gasを返す。eth_sendRawTransactionは canister submit API委譲。
メソッド
eth_call->rpc_eth_call_objecteth_estimateGas->rpc_eth_estimate_gas_objecteth_sendRawTransaction->rpc_eth_send_raw_transaction
callObject制約
- 対応キー:
to/from/gas/gasPrice/value/data/nonce/maxFeePerGas/maxPriorityFeePerGas/chainId/type/accessList type=0x0/0x2のみ- feeパラメータ併用ルールあり
送信時の運用
- submit成功後に receipt
statusを必ず監視
根拠
tools/rpc-gateway/README.mdtools/rpc-gateway/src/handlers.tscrates/ic-evm-rpc/src/lib.rs
English version: /en/doc/rpc/logs.html
Logs
TL;DR
eth_getLogsはrpc_eth_get_logs_pagedベースの制限付き実装。- 範囲・filter制約を超えると
-32005。
対応パターン
- 単一address +
topic0中心のログ取得 topics[0]の OR配列(最大16件)blockHash指定(fromBlock/toBlock併用なし、走査上限内)
制約
topics[1+]条件は現状未対応- 複数address同時指定は未対応
代表エラー
logs.range_too_largelogs.too_many_resultsUnsupportedFilter
根拠
crates/ic-evm-rpc/src/lib.rs(rpc_eth_get_logs_paged)tools/rpc-gateway/src/handlers.ts
English version: /en/doc/rpc/errors-and-limits.html
Errors & Limits
TL;DR
- HTTP側制限(body/batch/depth)とRPC側制限(blockTag/filter/range)の二層で制御。
- エラーコードは
-32602/-32000/-32001/-32005が中心。
Gateway HTTP制限
RPC_GATEWAY_MAX_HTTP_BODY_SIZERPC_GATEWAY_MAX_BATCH_LENRPC_GATEWAY_MAX_JSON_DEPTH
RPCエラー
-32602 invalid params-32000 state unavailable / execution failed-32001 resource not found-32005 limit exceeded
根拠
tools/rpc-gateway/src/server.tstools/rpc-gateway/src/handlers.tstools/rpc-gateway/src/config.ts
English version: /en/doc/contracts/solidity-vyper-compatibility.html
Solidity/Vyper Compatibility
TL;DR
- EVM実行系の基本導線として
eth_call/eth_estimateGas/eth_sendRawTransactionを利用できる。 - 互換の詳細は Gateway の実装・互換表を正本として扱う。
利用可能な主要メソッド
eth_calleth_estimateGaseth_sendRawTransaction
参照先
tools/rpc-gateway/README.mdcrates/evm-core/src/tx_decode.rs
English version: /en/doc/contracts/tooling.html
Tooling (Hardhat/Foundry/ethers/viem)
TL;DR
- ethers/viem/foundry のスモークがリポジトリ内にある。
- まず read系 + call/estimate + receipt監視を最小セットにする。
手順(最小)
- viem:
tools/rpc-gateway/smoke/viem_smoke.ts - ethers:
tools/rpc-gateway/smoke/ethers_smoke.ts - foundry:
tools/rpc-gateway/smoke/foundry_smoke.sh
落とし穴
- revert dataを捨てて原因調査不能になる
- tx hash保存なしで監視不能になる
根拠
tools/rpc-gateway/smoke/viem_smoke.tstools/rpc-gateway/smoke/ethers_smoke.tstools/rpc-gateway/smoke/foundry_smoke.sh
English version: /en/doc/contracts/verification.html
Verification
TL;DR
- Verify 機能は Explorer 側で提供される。
- 事前チェック・鍵ローテーション・監視運用は
docs/ops/verify_runbook.mdを正本として運用する。
運用手順(概要)
EXPLORER_VERIFY_ENABLED=1と許可コンパイラの環境変数を設定する。tools/explorerでnpm run verify:preflightを実行し、許可バージョンのsolc可用性を確認する。POST /api/verify/submitで検証ジョブを投入し、GET /api/verify/statusで状態を確認する。
根拠
tools/explorer/README.mddocs/ops/verify_runbook.md
English version: /en/doc/integration/sdks.html
SDKs
TL;DR
- 専用SDKより、JSON-RPCクライアント(ethers/viem/foundry)利用が主。
- canister直呼びは Candid 経由で可能。
根拠
tools/rpc-gateway/package.jsoncrates/ic-evm-wrapper/evm_canister.did
English version: /en/doc/integration/signing-nonce-retries.html
Signing, Nonce, Retries
TL;DR
- nonceは送信前に必ず取得する。
- chain idは
4801360を一致させる。 - submit成功後は receipt poll で結果判定する。
推奨手順
- sender addressを確定
eth_getTransactionCountまたはexpected_nonce_by_address- fee設定(base fee + priorityを考慮)
eth_sendRawTransactioneth_getTransactionReceiptをpoll
落とし穴
- nonce固定値ハードコード
- receipt timeout時に再送して nonce競合
根拠
README.mdtools/rpc-gateway/README.mdcrates/ic-evm-wrapper/src/lib.rs
English version: /en/doc/integration/indexer-integration-points.html
Indexer Integration Points
TL;DR
- pull起点は
export_blocks(cursor,max_bytes)。 - logs補助取得は
rpc_eth_get_logs_paged。 - prune前提で cursor運用を設計する。
根拠
crates/ic-evm-wrapper/evm_canister.didtools/indexer/README.mddocs/specs/indexer-v1.md
English version: /en/doc/indexer/data-model.html
Data Model
TL;DR
- indexerは Postgres-first。
txs,receipts,token_transfers,ops_metrics_samplesなどを保持。
主要ポイント
receipt_statusをtxsに保持- token transfer は receipt logsから抽出
根拠
tools/indexer/README.mdtools/indexer/src/db.ts
English version: /en/doc/indexer/resync-pagination-missing-data.html
Resync, Pagination, Missing Data
TL;DR
- cursorは
block_number/segment/byte_offsetのJSON固定。 Err.Pruned返却時は cursorを補正して継続する設計。
落とし穴
- indexer停止中にprune進行して履歴欠落
- segment上限不一致で復旧不能
根拠
tools/indexer/README.mddocs/specs/indexer-v1.mdtools/indexer/src/config.ts
English version: /en/doc/indexer/event-decoding-tips.html
Event Decoding Tips
TL;DR
- ERC-20 Transfer抽出は topic/data長チェックを厳格に行う。
- 不正ログは行単位スキップし、全体停止を避ける設計。
根拠
tools/indexer/README.mdtools/indexer/src/decode_receipt.ts
English version: /en/doc/security.html
Security Guide
TL;DR
- 署名鍵管理、chain id一致、receipt監視が最低ライン。
- 低fee設定・nonce運用ミス・prune未考慮が典型的事故要因。
安全な使い方
- chain id固定(
4801360) - nonceは毎回取得
eth_sendRawTransaction後に receipt判定- gateway制限値を過剰緩和しない
危険な落とし穴
status=0x0を見落として成功扱い- 誤chain idで署名したtxを再送し続ける
- prune後参照を永続前提にする
推奨設定
RPC_GATEWAY_MAX_BATCH_LENを既定範囲で維持INDEXER_CHAIN_IDを実ネットワークと一致INDEXER_MAX_SEGMENTを canister仕様と一致
根拠
tools/rpc-gateway/src/config.tstools/indexer/src/config.tstools/rpc-gateway/README.mdcrates/evm-core/tests/phase1_eth_decode.rs
English version: /en/doc/troubleshooting.html
Troubleshooting Guide
TL;DR
- まず「入力不正」「state unavailable」「pruned」のどれかを切り分ける。
- submitとexecuteを分けて観測する。
代表エラーと対処
invalid params (-32602)- 原因: address/hash長不正、blockTag不正、callObject制約違反
- 対処: 引数hex長・対応キーを再確認
state unavailable (-32000)- 原因: migration中、critical_corrupt、実行失敗
- 対処:
get_ops_statusを確認
resource not found (-32001)- 原因: pruned範囲、対象なし
- 対処: indexer側履歴を参照
limit exceeded (-32005)- 原因: logs範囲過大/件数過多
- 対処: ブロック範囲分割
落とし穴
eth_getLogsを大範囲一発で引く- 監視なしで再送して nonce競合を増やす
根拠
tools/rpc-gateway/src/handlers.tstools/rpc-gateway/README.mdcrates/ic-evm-wrapper/src/lib.rs(get_ops_status)
English version: /en/doc/appendix/glossary.html
Glossary
tx_id: canister内部識別子eth_tx_hash: Ethereum互換hashIcSynthetic: canister独自tx種別EthSigned: 署名済みEthereum txauto-production: timer駆動の自動ブロック生成PossiblyPruned: prune境界で存在判定が曖昧な状態Pruned: prune済みで参照不可
English version: /en/doc/appendix/config-reference.html
Config Reference (User Scope)
TL;DR
- 開発者がよく触る設定だけを抜粋。
Gateway
EVM_CANISTER_ID(必須)RPC_GATEWAY_IC_HOSTRPC_GATEWAY_PORT
Indexer
EVM_CANISTER_ID(必須)INDEXER_DATABASE_URL(必須)INDEXER_IC_HOSTINDEXER_CHAIN_ID(既定4801360)INDEXER_MAX_BYTES
English version: /en/doc/appendix/versioning-compatibility-policy.html
Versioning & Compatibility Policy
TL;DR
- 互換表の更新正本は Gateway README。
- メソッド追加・制約変更時は同一PRで要約更新する運用。
根拠
tools/rpc-gateway/README.mdREADME.md
English version: /en/doc/_generated/repo-map.html
Repo Map
このページは、Kasane リポジトリの「どこに何があるか」を一次情報だけで整理したものです。
TL;DR
- EVM canister本体は Rust workspace の
ic-evm-wrapper。 - 実行ロジックは
evm-core、永続化/定数はevm-db、RPC補助はic-evm-rpc。 - 外部開発者向け入口は
tools/rpc-gateway(HTTP JSON-RPC)とcrates/ic-evm-wrapper/evm_canister.did(Candid)。 - indexer は
tools/indexer(Postgres-first)。
主要ディレクトリ
crates/ic-evm-wrapper- canisterエントリポイント(
#[ic_cdk::query]/#[ic_cdk::update]) - Candid公開定義(
evm_canister.did)
- canisterエントリポイント(
crates/evm-core- tx decode / submit / produce / call / estimate 実装
- EVM実行とfee計算(
revm_exec.rs,base_fee.rs)
crates/evm-db- stable state、chain constants、runtime defaults、receipt/block/tx型
crates/ic-evm-rpc- wrapperから呼ばれる RPC補助ロジック(eth系参照/変換)
tools/rpc-gateway- canister Candid API を Ethereum JSON-RPC 2.0 へ変換
tools/indexer- export API を pull して Postgresへ保存
scripts- smoke / predeploy / mainnet deploy 補助
docs- 運用runbook・仕様メモ(一次情報として参照可能)
エントリポイント
- canister build/runtime
dfx.jsonのcanisters.evm_canistercrates/ic-evm-wrapper/src/lib.rs
- gateway runtime
tools/rpc-gateway/src/main.tstools/rpc-gateway/src/server.ts
- indexer runtime
tools/indexer/src/main.ts
依存関係の大枠
- Rust workspace members
Cargo.toml[workspace].members
- JSON-RPC層の実装責務
- Gateway: request/responseと制限
- canister: state/実行/永続化
非対象(本GitBookで扱わない)
- ノード運営(validator/sequencer/full node運用手順)
vendor/配下の上流ライブラリ内部詳細
根拠
Cargo.toml(workspace members)dfx.json(canister package/candid)icp.yaml(deploy recipe)crates/ic-evm-wrapper/src/lib.rs(canister entrypoint)tools/rpc-gateway/src/main.ts(gateway entrypoint)tools/indexer/README.md(indexer責務)
English version: /en/doc/_generated/interfaces.html
Interfaces
TL;DR
- 外部I/Fは
Candid(canister直呼び)とHTTP JSON-RPC(gateway)の2系統。 - JSON-RPCは Ethereum完全互換ではなく、制限付き実装。
eth_sendRawTransactionは submit成功≠実行成功。eth_getTransactionReceipt.statusを成功条件にする。- pending/mempool は Ethereum互換APIとしては未対応。送信済み tx の追跡は canister
get_pending(tx_id)を使う。
1. Candid API(公開service)
公開定義: crates/ic-evm-wrapper/evm_canister.did
主要query
rpc_eth_chain_idrpc_eth_block_numberrpc_eth_get_block_by_numberrpc_eth_get_block_by_number_with_statusrpc_eth_get_transaction_by_eth_hashrpc_eth_get_transaction_by_tx_idrpc_eth_get_transaction_receipt_by_eth_hashrpc_eth_get_transaction_receipt_with_status_by_eth_hashrpc_eth_get_transaction_receipt_with_status_by_tx_idrpc_eth_get_balancerpc_eth_get_coderpc_eth_get_storage_atrpc_eth_call_objectrpc_eth_call_rawtxrpc_eth_estimate_gas_objectrpc_eth_get_logs_pagedrpc_eth_get_block_number_by_hashrpc_eth_gas_pricerpc_eth_max_priority_fee_per_gasrpc_eth_fee_historyexpected_nonce_by_addressget_receiptget_pendingexport_blocksget_ops_statushealthmetrics
主要update
rpc_eth_send_raw_transactionsubmit_ic_txset_block_gas_limitset_instruction_soft_limitset_prune_policyset_pruning_enabledset_log_filterprune_blocks
2. Gateway JSON-RPC
実装: tools/rpc-gateway/src/handlers.ts の handleRpc switch
実装済みメソッド
web3_clientVersionnet_versioneth_chainIdeth_blockNumbereth_gasPriceeth_maxPriorityFeePerGaseth_feeHistoryeth_syncingeth_getBlockByNumbereth_getTransactionByHasheth_getTransactionReceipteth_getBalanceeth_getTransactionCounteth_getCodeeth_getStorageAteth_getLogseth_calleth_estimateGaseth_sendRawTransaction
未対応(READMEの互換表)
eth_getBlockByHasheth_getTransactionByBlockHashAndIndexeth_getTransactionByBlockNumberAndIndexeth_getBlockTransactionCountByHasheth_getBlockTransactionCountByNumbereth_newFiltereth_getFilterChangeseth_uninstallFiltereth_subscribeeth_unsubscribeeth_pendingTransactions
3. 制約の正本
- 全体ポリシーの正本:
../rpc/overview.md - JSON-RPC差分の正本:
../compatibility/json-rpc-deviations.md - pending/mempool運用の正本:
../rpc/overview.mdの「Pending/Mempoolポリシー」
本ページは「インターフェース一覧」の要約に限定し、詳細な挙動差分は上記正本に集約する。
4. 返却・識別子の注意
- canister内部識別子:
tx_id - Ethereum互換識別子:
eth_tx_hash - Gateway
eth_sendRawTransactionは canister戻りtx_idからeth_tx_hashを解決して返す。
5. 型境界(代表)
RpcCallObjectView(Candid)EthBlockView/EthTxView/EthReceiptViewRpcBlockLookupView(NotFound/Found/Pruned)RpcReceiptLookupView(NotFound/Found/PossiblyPruned/Pruned)PendingStatusView(Queued/Included/Dropped/Unknown)
根拠
crates/ic-evm-wrapper/evm_canister.didtools/rpc-gateway/src/handlers.tstools/rpc-gateway/README.mdcrates/ic-evm-wrapper/src/lib.rs(get_pending,rpc_eth_send_raw_transaction)
English version: /en/doc/_generated/config-reference.html
Config Reference
TL;DR
- 必須設定は Gateway:
EVM_CANISTER_ID、Indexer:EVM_CANISTER_ID+INDEXER_DATABASE_URL。 - 既定の
chain_idは4801360。 - ガス/採掘/prune の既定値は Rust定数で管理される。
1. Gateway環境変数
定義: tools/rpc-gateway/src/config.ts
- 必須
EVM_CANISTER_ID
- 任意(既定値)
RPC_GATEWAY_IC_HOST(https://icp-api.io)RPC_GATEWAY_FETCH_ROOT_KEY(false)RPC_GATEWAY_IDENTITY_PEM_PATH(null)RPC_GATEWAY_HOST(127.0.0.1)RPC_GATEWAY_PORT(8545)RPC_GATEWAY_CLIENT_VERSION(kasane/phase2-gateway/v0.1.0)RPC_GATEWAY_MAX_HTTP_BODY_SIZE(262144)RPC_GATEWAY_MAX_BATCH_LEN(20)RPC_GATEWAY_MAX_JSON_DEPTH(20)RPC_GATEWAY_CORS_ORIGIN(*)
2. Indexer環境変数
定義: tools/indexer/src/config.ts
- 必須
EVM_CANISTER_IDINDEXER_DATABASE_URL
- 任意(既定値)
INDEXER_IC_HOST(https://icp-api.io)INDEXER_DB_POOL_MAX(10)INDEXER_RETENTION_DAYS(90)INDEXER_RETENTION_ENABLED(true)INDEXER_RETENTION_DRY_RUN(false)INDEXER_ARCHIVE_GC_DELETE_ORPHANS(false)INDEXER_MAX_BYTES(1200000)INDEXER_BACKOFF_INITIAL_MS(200)INDEXER_BACKOFF_MAX_MS(5000)INDEXER_IDLE_POLL_MS(1000)INDEXER_PRUNE_STATUS_POLL_MS(30000)INDEXER_OPS_METRICS_POLL_MS(30000)INDEXER_FETCH_ROOT_KEY(false)INDEXER_ARCHIVE_DIR(./archive)INDEXER_CHAIN_ID(4801360)INDEXER_ZSTD_LEVEL(3)INDEXER_MAX_SEGMENT(2)
3. Chain / Runtime定数
chain constants
定義: crates/evm-db/src/chain_data/constants.rs
CHAIN_ID = 4_801_360MAX_TX_SIZE = 128 * 1024MAX_TXS_PER_BLOCK = 1024MAX_PENDING_GLOBAL = 8192MAX_PENDING_PER_SENDER = 64MAX_PENDING_PER_PRINCIPAL = 32MAX_NONCE_WINDOW = 64MAX_LOGS_PER_TX = 64MAX_LOG_TOPICS = 4
runtime defaults
定義: crates/evm-db/src/chain_data/runtime_defaults.rs
DEFAULT_MINING_INTERVAL_MS = 2000DEFAULT_BASE_FEE = 250_000_000_000DEFAULT_MIN_GAS_PRICE = 250_000_000_000DEFAULT_MIN_PRIORITY_FEE = 250_000_000_000DEFAULT_BLOCK_GAS_LIMIT = 3_000_000DEFAULT_INSTRUCTION_SOFT_LIMIT = 4_000_000_000DEFAULT_PRUNE_TIMER_INTERVAL_MS = 3_600_000DEFAULT_PRUNE_MAX_OPS_PER_TICK = 5_000MIN_PRUNE_TIMER_INTERVAL_MS = 1_000MIN_PRUNE_MAX_OPS_PER_TICK = 1
4. 危険値・注意
INDEXER_CHAIN_IDが実チェーンと不一致だと署名/検証系の運用が破綻しうる。RPC_GATEWAY_MAX_HTTP_BODY_SIZEを過大化すると DoS耐性が下がる。DEFAULT_MIN_GAS_PRICE/DEFAULT_MIN_PRIORITY_FEEを無根拠で下げると低feeスパム耐性が下がる。
根拠
tools/rpc-gateway/src/config.tstools/indexer/src/config.tscrates/evm-db/src/chain_data/constants.rscrates/evm-db/src/chain_data/runtime_defaults.rs
English version: /en/doc/_generated/open-questions.html
Open Questions
現在、このドキュメントセット内に保留事項はありません。