Vai al contenuto

Decodifica della calldata in un wallet

Una guida orientata alla verifica di calldata, parole e offset ABI, collisioni dei selettori, proxy, batch, approvazioni, permit con dati tipizzati, simulazione e riconciliazione post-transazione.

Aggiornato

Solo a scopo educativo; non costituisce consulenza né raccomandazione d’investimento. Gli investimenti possono comportare perdite.

Risposta diretta

La calldata è la sequenza immutabile di byte fornita come input a una transazione Ethereum di primo livello o a una chiamata interna. Una chiamata convenzionale a una funzione Solidity inizia con un selettore di 4-byte, seguito dagli argomenti codificati secondo l’ABI, ma la calldata non è autodescrittiva: gli stessi byte possono assumere significati diversi per differenti codici runtime, implementazioni proxy o schemi. Le funzioni fallback, l’assembly grezzo e i protocolli non Solidity non sono tenuti a seguire l’ABI convenzionale delle funzioni.

Un wallet dovrebbe quindi mostrare più di un possibile nome di funzione. Una revisione sicura associa i byte a chainId, un blocco, from, to, il value nativo, il codeHash runtime, l’implementazione attiva e un’ABI affidabile; decodifica rigorosamente ogni chiamata annidata; distingue la calldata on-chain dalle firme EIP-712; simula in uno stato esplicito; e riconcilia la ricevuta e le variazioni di stato effettive dopo l’inclusione.

Decodifica della calldata
0 / 5
0 elementi recensiti; 5 elementi ancora irrisolti

Il completamento di questa revisione non dimostra che una risorsa, una transazione o un sistema siano sicuri.

Come funziona

  1. Fissa l’envelope di firma e il punto di osservazione: chainId, numero e hash del blocco, from, to, value nativo, byte di input, nonce e campi delle commissioni. Conserva la fonte del wallet o RPC; un payload decodificato su un’altra rete o in un altro blocco non rappresenta la stessa affermazione.
  2. Classifica l’oggetto prima della decodifica. Una transazione, una richiesta EIP-712 di dati tipizzati, un permit ERC-2612, una UserOperation ERC-4337 e un messaggio personal-sign grezzo utilizzano domini e schemi diversi; non forzarli tutti nell’ABI delle transazioni.
  3. Risolvi il target al blocco fissato. Leggi il bytecode runtime e il codeHash; identifica proxy, beacon o implementazione quando applicabile; registra gli slot di implementazione e amministrazione; e ottieni un’ABI corrispondente a quella versione esatta del codice. Un registro di selettori fornisce candidati, non autorità.
  4. Decodifica rigorosamente. Il selettore è costituito dai primi 4 bytes del Keccak-256 della firma canonica della funzione, esclusi i tipi restituiti. I valori statici occupano parole di 32-byte; le head dinamiche contengono offset dall’inizio del blocco degli argomenti dopo il selettore. Rifiuta dati troncati, offset fuori limite, lunghezze impossibili, padding non valido e byte finali inspiegati.
  5. Espandi ricorsivamente multicall, calldata annidata ed esecuzione delegata. Per ogni chiamata figlia, elenca target, valore nativo, selettore, argomenti, tipo di chiamata ed eventuale indicatore allowFailure. Con delegatecall, il codice dell’implementazione viene eseguito nel contesto di indirizzo, saldo e storage del chiamante, preservando msg.sender e msg.value.
  6. Costruisci registri separati di autorità e valore, quindi simula. Registra destinatari, spender, operatori NFT, unità grezze dei token, decimali, scadenze, limiti di slippage e valore nativo. Simula con blocco, mittente e valore esatti, ma considera il risultato un’istantanea condizionale perché stato, prezzi, tempo, codice e ordinamento delle transazioni possono cambiare.
  7. Conferma ogni campo rilevante prima di firmare. Dopo l’inclusione, controlla stato della ricevuta, log, trace disponibili e variazioni di saldi, allowance e stato degli operatori; distingui i fallimenti figli intercettati dal successo al primo livello; contabilizza il gas anche in caso di revert; attendi la finalità richiesta; e interrompi il processo invece di rifirmare alla cieca un errore inspiegato.

Esempi svolti

  • Trasferimento ERC-20 statico. transfer(address,uint256) usa comunemente il selettore 0xa9059cbb. Un selettore più due parole ABI equivale a 4 + 2 * 32 = 68 bytes. Un importo grezzo di 1,500,000 per un token verificato indipendentemente con 6 decimals viene mostrato come 1.5 tokens. I decimali sono metadati esterni del contratto, non codificati in tali argomenti, e il selettore da solo non identifica univocamente contratto o funzione.
  • Offset di byte dinamici. Per f(address,bytes) con un payload di 3-byte, la head di due parole occupa 64 bytes. L’offset dinamico è 0x40, misurato dall’inizio del blocco degli argomenti ed escludendo il selettore. La tail contiene una parola di lunghezza di 32-byte e una parola dati con padding di 32-byte, quindi la calldata totale è 4 + 64 + 32 + 32 = 132 bytes. Trattare l’offset come assoluto dal byte zero porta quattro byte oltre il punto corretto.
  • Il valore di un batch dipende dall’implementazione. Una chiamata esterna trasferisce 1.00 ETH; tre chiamate figlie decodificate richiedono esplicitamente 0.20 ETH, 0.30 ETH e 0.10 ETH, per un totale di 0.60 ETH. I restanti 0.40 ETH potrebbero essere rimborsati, trattenuti, inoltrati o causare un revert, secondo il codice del batch. Se la terza chiamata fallisce con allowFailure=true, le precedenti possono restare confermate; un’implementazione atomica può invece annullare tutto.
  • Un permit non è la calldata del relayer al momento della firma. Un owner con 1,000 USDC firma un permit ERC-2612 da 300 USDC al nonce 41. La firma da sola non modifica saldo né allowance. Dopo l’invio riuscito da parte di un relayer, il nonce diventa 42 e l’allowance 300; dopo che lo spender utilizza 180, il saldo è 820 e l’allowance residua 120. Disconnettere il sito non revoca il permesso.

Rischi

  • Decodificare usando rete, fork, block tag o envelope di transazione sbagliati.
  • Firmare per un dominio, indirizzo target o destinatario contraffatti.
  • Considerare un selettore di 4-byte univoco nonostante possibili collisioni.
  • Usare un’ABI ipotizzata, obsoleta o verificata in modo scorretto.
  • Fidarsi di un’etichetta di sorgente verificato senza confrontarla con il codeHash corrente.
  • Non rilevare un upgrade di implementazione, beacon o amministratore tra revisione ed esecuzione.
  • Ignorare una funzione proxy il cui selettore collide con quello dell’implementazione.
  • Dimenticare che delegatecall scrive nel contesto di storage del chiamante.
  • Accettare offset dinamici, lunghezze, padding o byte finali malformati.
  • Non espandere un batch annidato che nasconde target, valori o permessi.
  • Presumere atomicità quando l’implementazione intercetta o consente fallimenti figli.
  • Ignorare il value nativo di primo livello perché gli argomenti dei token sembrano innocui.
  • Applicare decimali errati o presumere che token fee-on-transfer e rebasing siano ERC-20 standard.
  • Concedere allowance ERC-20 illimitata o gestire male la race condition di aggiornamento dell’allowance.
  • Trascurare l’ambito esteso all’intera collezione di setApprovalForAll per NFT.
  • Scambiare dati tipizzati EIP-712 o un permit ERC-2612 per calldata di transazione.
  • Non rilevare nonce, scadenza, contratto di verifica, dominio della rete o limiti di replay.
  • Considerare stabile una simulazione nonostante cambiamenti di oracolo, timestamp, pending state, MEV o codice.
  • Considerare stato della ricevuta, log o trace del provider una prova completa dello stato economico.
  • Rifirmare alla cieca tramite una UI compromessa o ignorare rischi di inclusione, reorg e finalità.

Idee errate comuni

  • Un selettore di funzione identifica univocamente ciò che il contratto eseguirà.
  • Un riepilogo verificato del frontend è identico ai byte e all’implementazione corrente che si firmano.
  • Una transazione con value=0 non può spostare token, NFT o asset delegati.
  • Una simulazione o una ricevuta riuscite dimostrano sicurezza e il risultato economico desiderato.
  • Disconnettere una dapp revoca approvazioni, permit e permessi degli operatori NFT.

Argomenti correlati

Fonti

Navigazione

Cerca nella wiki...