Lompat ke konten

Mengurai Calldata di Dompet

Panduan berorientasi verifikasi untuk calldata transaksi, word dan offset ABI, tabrakan selector, proxy, batch, persetujuan, permit berbasis typed data, simulasi, dan rekonsiliasi pascatransaksi.

Diperbarui

Hanya untuk tujuan edukasi; bukan merupakan nasihat investasi atau rekomendasi investasi. Investasi dapat mengakibatkan kerugian.

Jawaban langsung

Calldata adalah rangkaian byte yang tidak dapat diubah dan diberikan sebagai input kepada transaksi Ethereum tingkat atas atau message call internal. Panggilan fungsi Solidity konvensional dimulai dengan selector 4-byte, lalu argumen yang dikodekan dengan ABI. Namun, calldata tidak mendeskripsikan dirinya sendiri: byte yang sama dapat berarti hal berbeda untuk runtime code, implementasi proxy, atau skema yang berbeda. Fungsi fallback, assembly mentah, dan protokol non-Solidity bahkan tidak harus mengikuti ABI fungsi konvensional.

Karena itu, dompet harus menampilkan lebih dari sekadar kandidat nama fungsi. Peninjauan yang aman mengikat byte tersebut ke chainId, suatu blok, from, to, value native, codeHash runtime, implementasi aktif, dan ABI tepercaya; mengurai setiap panggilan bersarang secara ketat; membedakan calldata on-chain dari tanda tangan EIP-712; melakukan simulasi dalam state yang dinyatakan; lalu merekonsiliasi receipt serta perubahan state aktual setelah transaksi dimasukkan.

Penguraian calldata
0 / 5
0 item yang ditinjau; 5 item yang masih belum terselesaikan

Menyelesaikan tinjauan ini tidak membuktikan suatu aset, transaksi, atau sistem aman.

Cara kerjanya

  1. Kunci signing envelope dan titik observasi: chainId, nomor serta hash blok, from, to, value native, byte input, nonce, dan field biaya. Simpan sumber dompet atau RPC; payload yang diurai dari chain atau blok lain bukanlah klaim yang sama.
  2. Klasifikasikan objek sebelum mengurainya. Transaksi, permintaan typed data EIP-712, permit ERC-2612, UserOperation ERC-4337, dan pesan personal-sign mentah memakai domain serta skema berbeda; jangan memaksakan semuanya melalui ABI transaksi.
  3. Tentukan target pada blok yang dikunci. Baca runtime bytecode dan codeHash; identifikasi proxy, beacon, atau implementasi bila relevan; catat slot implementasi dan admin; serta dapatkan ABI yang cocok dengan versi kode tersebut. Registry selector hanya memberi kandidat, bukan otoritas.
  4. Urai secara ketat. Selector adalah 4 bytes pertama Keccak-256 atas signature fungsi kanonis tanpa tipe return. Nilai statis menempati word 32-byte, sedangkan head dinamis memuat offset dari blok argumen setelah selector. Tolak data terpotong, offset di luar batas, panjang yang mustahil, padding tidak valid, dan byte tambahan yang tidak dapat dijelaskan.
  5. Buka multicall, calldata bersarang, dan eksekusi terdelegasi secara rekursif. Untuk setiap child call, tampilkan target, nilai native, selector, argumen, tipe panggilan, dan setiap flag allowFailure. Dengan delegatecall, kode implementasi berjalan dalam konteks alamat, saldo, dan storage pemanggil, sementara msg.sender serta msg.value tetap dipertahankan.
  6. Susun ledger otoritas dan nilai secara terpisah, lalu lakukan simulasi. Catat penerima, spender, operator NFT, unit token mentah, decimals, deadline, batas slippage, dan nilai native. Simulasikan menggunakan blok, pengirim, dan nilai yang tepat, tetapi perlakukan hasilnya sebagai snapshot bersyarat karena state, harga, waktu, kode, dan urutan transaksi dapat berubah.
  7. Konfirmasikan setiap field material sebelum menandatangani. Setelah transaksi masuk, periksa status receipt, log, trace jika tersedia, serta delta saldo, allowance, dan status operator; bedakan kegagalan child call yang ditangkap dari keberhasilan tingkat atas; perhitungkan gas meski transaksi revert; tunggu finalitas yang diperlukan; dan berhenti alih-alih menandatangani ulang kegagalan yang tidak dapat dijelaskan.

Contoh terhitung

  • Transfer ERC-20 statis. transfer(address,uint256) lazim memakai selector 0xa9059cbb. Satu selector ditambah dua word ABI adalah 4 + 2 * 32 = 68 bytes. Jumlah mentah 1,500,000 untuk token yang telah diverifikasi secara independen menggunakan 6 decimals ditampilkan sebagai 1.5 tokens. Decimals adalah metadata kontrak eksternal, bukan bagian yang dikodekan dalam argumen tersebut, dan selector saja tidak mengidentifikasi kontrak atau fungsi secara unik.
  • Offset byte dinamis. Untuk f(address,bytes) dengan payload 3-byte, head dua word menempati 64 bytes. Offset dinamisnya 0x40, diukur dari awal blok argumen dan tidak mencakup selector. Tail berisi satu word panjang 32-byte dan satu word data ber-padding 32-byte, sehingga total calldata adalah 4 + 64 + 32 + 32 = 132 bytes. Menganggap offset absolut dari byte nol akan meleset empat byte ke belakang.
  • Nilai batch bergantung pada implementasi. Panggilan luar membawa 1.00 ETH; tiga child call yang diurai secara eksplisit meminta 0.20 ETH, 0.30 ETH, dan 0.10 ETH, dengan total 0.60 ETH. Sisa 0.40 ETH dapat dikembalikan, ditahan, diteruskan, atau menyebabkan revert, tergantung kode batch. Jika child ketiga gagal dengan allowFailure=true, child sebelumnya mungkin tetap committed; implementasi atomik dapat memilih me-revert semuanya.
  • Permit bukan calldata relayer saat penandatanganan. Pemilik dengan 1,000 USDC menandatangani permit ERC-2612 sebesar 300 USDC pada nonce 41. Tanda tangan saja tidak mengubah saldo maupun allowance. Setelah relayer berhasil mengirimkannya, nonce menjadi 42 dan allowance menjadi 300; setelah spender memakai 180, saldo menjadi 820 dan sisa allowance 120. Memutus koneksi situs tidak mencabut izin tersebut.

Risiko

  • Mengurai berdasarkan chain, fork, block tag, atau transaction envelope yang salah.
  • Menandatangani untuk domain, alamat target, atau penerima palsu.
  • Menganggap selector 4-byte unik meski tabrakan dapat terjadi.
  • Menggunakan ABI tebakan, usang, atau diverifikasi secara keliru.
  • Memercayai label source terverifikasi tanpa mencocokkannya dengan codeHash runtime saat ini.
  • Melewatkan upgrade implementasi, beacon, atau admin antara peninjauan dan eksekusi.
  • Mengabaikan fungsi proxy yang selectornya bertabrakan dengan implementasi.
  • Lupa bahwa delegatecall menulis dalam konteks storage pemanggil.
  • Menerima offset, panjang, padding dinamis, atau byte tambahan yang malformed.
  • Gagal membuka batch bersarang yang menyembunyikan target, nilai, atau izin.
  • Mengasumsikan atomisitas ketika implementasi menangkap atau mengizinkan kegagalan child call.
  • Mengabaikan value native tingkat atas karena argumen token tampak tidak berbahaya.
  • Menerapkan decimals yang salah atau menganggap token fee-on-transfer dan rebasing sebagai ERC-20 standar.
  • Memberikan allowance ERC-20 tanpa batas atau salah menangani race saat memperbaruinya.
  • Mengabaikan cakupan seluruh koleksi dari setApprovalForAll NFT.
  • Mengira typed data EIP-712 atau permit ERC-2612 sebagai calldata transaksi.
  • Melewatkan batas nonce, deadline, verifying contract, domain chain, atau replay.
  • Menganggap simulasi stabil meski oracle, timestamp, pending state, MEV, atau kode berubah.
  • Menganggap status receipt, log, atau trace penyedia sebagai bukti lengkap state ekonomi.
  • Menandatangani ulang secara buta melalui UI terkompromi atau mengabaikan risiko inclusion, reorg, dan finalitas.

Kesalahpahaman umum

  • Selector fungsi secara unik menentukan apa yang akan dieksekusi kontrak.
  • Ringkasan front-end terverifikasi identik dengan byte serta implementasi aktif yang ditandatangani.
  • Transaksi dengan value=0 tidak dapat memindahkan token, NFT, atau aset terdelegasi.
  • Simulasi atau receipt yang berhasil membuktikan keamanan dan hasil ekonomi yang dimaksud.
  • Memutus koneksi dapp mencabut persetujuan, permit, dan izin operator NFT.

Topik terkait

Sumber

Navigasi

Cari di wiki...