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.
Il completamento di questa revisione non dimostra che una risorsa, una transazione o un sistema siano sicuri.
Come funziona
- Fissa l’envelope di firma e il punto di osservazione:
chainId, numero e hash del blocco,from,to,valuenativo, 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. - 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.
- 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à. - Decodifica rigorosamente. Il selettore è costituito dai primi
4 bytesdel Keccak-256 della firma canonica della funzione, esclusi i tipi restituiti. I valori statici occupano parole di32-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. - 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. Condelegatecall, il codice dell’implementazione viene eseguito nel contesto di indirizzo, saldo e storage del chiamante, preservandomsg.senderemsg.value. - 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.
- 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 selettore0xa9059cbb. Un selettore più due parole ABI equivale a4 + 2 * 32 = 68 bytes. Un importo grezzo di1,500,000per un token verificato indipendentemente con6 decimalsviene mostrato come1.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 di3-byte, la head di due parole occupa64 bytes. L’offset dinamico è0x40, misurato dall’inizio del blocco degli argomenti ed escludendo il selettore. La tail contiene una parola di lunghezza di32-bytee una parola dati con padding di32-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 esplicitamente0.20 ETH,0.30 ETHe0.10 ETH, per un totale di0.60 ETH. I restanti0.40 ETHpotrebbero essere rimborsati, trattenuti, inoltrati o causare un revert, secondo il codice del batch. Se la terza chiamata fallisce conallowFailure=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 USDCfirma un permit ERC-2612 da300 USDCal nonce41. La firma da sola non modifica saldo né allowance. Dopo l’invio riuscito da parte di un relayer, il nonce diventa42e l’allowance300; dopo che lo spender utilizza180, il saldo è820e l’allowance residua120. 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-byteunivoco nonostante possibili collisioni. - Usare un’ABI ipotizzata, obsoleta o verificata in modo scorretto.
- Fidarsi di un’etichetta di sorgente verificato senza confrontarla con il
codeHashcorrente. - 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
delegatecallscrive 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
valuenativo 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
setApprovalForAllper 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=0non 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
- Contract ABI Specification - Solidity Documentation (consultato il: 2026-08-12)
- Introduction to Smart Contracts - Solidity Documentation (consultato il: 2026-08-12)
- Transactions - Ethereum.org (consultato il: 2026-08-12)
- ERC-20: Token Standard - Ethereum Improvement Proposals (consultato il: 2026-08-12)
- EIP-712: Typed structured data hashing and signing - Ethereum Improvement Proposals (consultato il: 2026-08-12)
- ERC-2612: Permit Extension for EIP-20 Signed Approvals - Ethereum Improvement Proposals (consultato il: 2026-08-12)
- ERC-721: Non-Fungible Token Standard - Ethereum Improvement Proposals (consultato il: 2026-08-12)
- ERC-1967: Proxy Storage Slots - Ethereum Improvement Proposals (consultato il: 2026-08-12)