Guida per principianti a TON: account, token e sicurezza

Sfondo

TON (The Open Network) è una piattaforma blockchain decentralizzata inizialmente progettata e sviluppata dal team di Telegram. TON mira a fornire una piattaforma blockchain scalabile e ad alte prestazioni per supportare applicazioni decentralizzate (DApp) e contratti intelligenti su larga scala.

TON è unico in quanto è facile da usare, profondamente integrato con Telegram, consentendo alle persone comuni di utilizzare facilmente i token. Allo stesso tempo, è complessa, con un’architettura che si distingue dalle altre blockchain e utilizza un linguaggio per contratti intelligenti non mainstream chiamato FunC.

Oggi discuteremo le caratteristiche di TON e la sicurezza degli asset degli utenti dal punto di vista dei conti, dei token e delle transazioni.

Caratteristiche di TON

Generazione di account

Il metodo di generazione dell’indirizzo di un conto su TON è diverso da quello della maggior parte delle blockchain: si tratta di un indirizzo di uno smart contract. Innanzitutto, tutto inizia con una chiave privata. TON utilizza principalmente l’algoritmo Ed25519 per generare una chiave pubblica, con il processo seguente:

Esistono due forme di chiave pubblica: una è la chiave pubblica grezza calcolata a partire dalla chiave privata, che si presenta come:

E39ECDA0A7B0C60A7107EC43967829DBE8BC356A49B9DFC6186B3EAC74B5477D

L’altra è una chiave pubblica “abbellita”, che include alcune informazioni e bit di controllo, e si presenta come:

Pubjns2gp7DGCnEH7EOWeCnb6Lw1akm538YYaz6sdLVHfRB2

Se si pensa che basti ottenere la chiave pubblica per ottenere l’indirizzo dell’account come in Ethereum, ci si sbaglia. Il solo possesso della chiave pubblica dell’utente non è sufficiente per calcolare l’indirizzo dell’account dell’utente.

Come già detto, l’indirizzo dell’account dell’utente è un indirizzo del contratto smart, ma come si può distribuire un contratto smart senza avere un account?

La sequenza corretta consiste nel calcolare prima l’indirizzo, ricevere una certa quantità iniziale di token e quindi distribuire il contratto. Il processo di calcolo dell’indirizzo del conto è mostrato nel diagramma seguente:

Anche l’indirizzo di un utente si presenta in diverse forme. Innanzitutto, c’è la forma grezza, che appare come:

0:b4c1b2ede12aa76f4a44353944258bcc8f99e9c7c474711a152c78b43218e296

C’è poi un modulo di facile utilizzo, che si presenta come:

Mainnet:

  • Rimbalzabile: EQC0wbLt4Sqnb0pENTlEJYvMj5npx8R0cRoVLHi0MhjilkPX
  • Non rimbalzabile: UQC0wbLt4Sqnb0pENTlEJYvMj5npx8R0cRoVLHi0Mhjilh4S

Testnet:

  • Rimbalzabile: kQC0wbLt4Sqnb0pENTlEJYvMj5npx8R0cRoVLHi0Mhjilvhd
  • Non rimbalzabile: 0QC0wbLt4Sqnb0pENTlEJYvMj5npx8R0cRoVLHi0MhjilqWY

Osservando attentamente questi indirizzi, si può notare che si differenziano solo per i primi e gli ultimi caratteri, mentre i account_id centrali sono uguali.

Tuttavia, non si riesce ancora a capire la relazione tra la chiave pubblica e l’indirizzo dell’account.

Il segreto sta nel initial data all’inizio, che contiene la chiave pubblica dell’utente, consentendogli di controllare il contratto del portafoglio. Il workchainId è facile da capire: TON non è un’unica catena, ma è composta da molti frammenti.

Ogni shard fa parte dell’intera rete e gestisce conti e transazioni specifiche. Per individuare e gestire gli smart contract, è necessario specificare in quale shard si trovano. Qual è la differenza tra Bounceable e Non-bounceable?

Questo si riferisce al modo in cui I contratti intelligenti funzionano, ma continuiamo ad approfondire.

Contratto di portafoglio

Di seguito è riportato uno snippet del codice sorgente di un contratto di portafoglio utente. Mostra che quando riceve un messaggio dall’utente, legge quattro parametri: stored_seqno, stored_subwallet, public_key e plugins:

wallet-v4-code.fc



() recv_external(slice in_msg) impure {

var signature = in_msg~load_bits(512);

var cs = in_msg;

var (subwallet_id, valid_until, msg_seqno) = (cs~load_uint(32), cs~load_uint(32), cs~load_uint(32));

throw_if(36, valid_until <= now());

var ds = get_data().begin_parse();

var (stored_seqno, stored_subwallet, public_key, plugins) = (ds~load_uint(32), ds~load_uint(32), ds~load_uint(256), ds~load_dict()); ;;##The Initial Data

ds.end_parse();

throw_unless(33, msg_seqno == stored_seqno);

throw_unless(34, subwallet_id == stored_subwallet);

throw_unless(35, check_signature(slice_hash(in_msg), signature, public_key));

//...

}

Infatti, quando questo contratto di portafoglio utente viene distribuito, richiede alcuni parametri iniziali, tra cui un public_key a 256 bit. Questo assicura che ogni utente abbia un indirizzo di contratto unico anche quando utilizza lo stesso codice di contratto.

Ogni transazione avviata dall’utente deve essere firmata con in_msg, quindi verificata dal contratto del portafoglio (check_signature), dopodiché il contratto eseguirà operazioni sulla blockchain. Da ciò si deduce che la chiave pubblica di un utente può corrispondere a numerosi indirizzi di portafoglio.

L’impiego di contratti di portafoglio diversi o l’utilizzo di dati di inizializzazione diversi darà luogo a indirizzi di contratto completamente diversi.

Gettone Jetton

Un token rappresenta un bene sulla blockchain, il che lo rende un elemento fondamentale da comprendere. Jetton è la forma standard dei token TON ed è composto da due contratti: Jetton-minter e Jetton-wallet.

Quando viene emesso un token, viene creato un contratto Jetton-minter. Questa inizializzazione del contratto registra informazioni come la fornitura totale di token, l’amministratore, il codice del portafoglio e altri dettagli.

Quando i token vengono distribuiti agli utenti, il contratto Minter distribuisce un contratto wallet per ogni utente. Durante l’inizializzazione del contratto, registra il saldo dell’utente, la proprietà, l’indirizzo del contratto Minter del token, il codice del portafoglio dell’utente e altre informazioni rilevanti. Ogni utente ha un contratto distribuito individualmente.

È importante notare che il contratto creato qui è un contratto di portafoglio per la gestione di specifici token Jetton, che è diverso dal contratto di portafoglio dell’account dell’utente. Il owner_address registrato qui è l’indirizzo del portafoglio dell’account dell’utente.

Quando l’utente Alice trasferisce i token all’utente Bob, la relazione di invocazione è la seguente:

Alice firma la transazione tramite un’applicazione fuori catena e invia un comando operativo tramite il suo contratto di portafoglio. Questi comandi invocheranno ulteriormente il suo portafoglio di token per eseguire il trasferimento. Quando il portafoglio di token di Bob riceve i token, notifica il contratto del portafoglio di Bob (l’indirizzo del proprietario del portafoglio Jetton di Bob).

Se durante la transazione rimane del gas, questo viene restituito all’indirizzo appropriato, di solito il contratto del conto di Alice.

Di seguito è riportato un esempio di trasferimento di token Jetton analizzato dal browser Tonviewer:

Mentre un trasferimento ERC20 richiede una sola invocazione di contratto, un trasferimento di token Jetton richiede almeno quattro invocazioni di contratto. Questo metodo è stato progettato per consentire la concomitanza sulla catena, migliorando l’efficienza delle transazioni.

Transazioni

Quando si verifica un determinato evento in un conto TON, si attiva una transazione. L’evento più comune è la “ricezione di un messaggio”. Una transazione comprende i seguenti elementi:

  • Il messaggio in arrivo che attiva inizialmente il contratto (con metodi di attivazione speciali disponibili).
  • Azioni del contratto derivanti dal messaggio in arrivo, come l’aggiornamento della memoria del contratto (opzionale).
  • Messaggi in uscita inviati ad altri partecipanti (opzionale).

Ci sono diverse caratteristiche chiave da tenere presenti per quanto riguarda le transazioni:

  1. Asincrono: Le transazioni TON non vengono completate in un’unica chiamata, ma possono richiedere il passaggio di messaggi a più smart contract diversi per eseguire una serie di chiamate. A causa del diverso routing nelle catene sharded, TON non può garantire l’ordine di consegna dei messaggi tra più smart contract.
  2. Tasse: La natura asincrona delle transazioni introduce una sfida nella stima delle commissioni consumate. Per questo motivo, i portafogli spesso inviano un piccolo gettone in più come commissione quando iniziano una transazione. Se il contratto chiamato ha un buon meccanismo di gestione delle commissioni, le commissioni rimanenti saranno restituite al portafoglio dell’utente. Gli utenti potrebbero notare che i token del loro portafoglio diminuiscono improvvisamente e poi aumentano di nuovo dopo pochi minuti, a causa di questo meccanismo.
  3. Rimbalzo: Il rimbalzo è un meccanismo di gestione degli errori nei contratti. Se il contratto chiamato non esiste o lancia un errore e la transazione è impostata come rimbalzabile, un messaggio di rimbalzo sarà restituito al contratto chiamante. Ad esempio, se un utente avvia un trasferimento e si verifica un errore durante il processo, un messaggio di rimbalzo è necessario affinché il contratto del portafoglio dell’utente possa ripristinare il suo saldo. Quasi tutti i messaggi interni inviati tra smart contract dovrebbero essere rimbalzabili, ovvero dovrebbero avere il bit “bounce” impostato.

Sicurezza delle risorse

TON ha molte caratteristiche che possono portare a problemi di sicurezza, quindi gli utenti devono essere consapevoli di alcune insidie comuni.

Attacco alla ritenuta d’acconto

Come già accennato, i portafogli spesso devono inviare una piccola tassa aggiuntiva per evitare il fallimento della transazione, il che offre un’opportunità agli aggressori. Se siete utenti di un portafoglio TON, potreste aver riscontrato una situazione in cui il vostro portafoglio riceve spesso vari NFT o token.

Inizialmente, questi possono sembrare gettoni spazzatura, ma dopo aver controllato i dettagli della transazione, si scopre che possono essere venduti per una quantità significativa di denaro. Tuttavia, quando si tenta di avviare una transazione, si nota che la commissione richiesta è estremamente elevata (1 TON). A questo punto bisogna essere cauti, perché potrebbe trattarsi di una truffa a pagamento.

Gli aggressori creano un contratto di token accuratamente elaborato che induce il portafoglio a stimare una commissione di trasferimento eccessivamente elevata, ma in realtà viene trattenuta solo la commissione e non viene inviato alcun messaggio di trasferimento.

Phishing con prima e ultima cifra

Il phishing di prima e ultima cifra non è un’esclusiva di TON; questo attacco di phishing è presente in molte delle principali blockchain. Gli aggressori generano un account contraffatto per ogni indirizzo utente della rete con la stessa prima e ultima cifra.

Quando un utente avvia un trasferimento, l’aggressore invia anche un piccolo trasferimento, dopo la transazione dell’utente, per lasciare un record nella cronologia delle transazioni dell’utente. Quando l’utente destinatario vuole rispedire i token, potrebbe copiare l’indirizzo dalla cronologia delle transazioni, che potrebbe essere l’indirizzo dell’aggressore, con conseguente trasferimento all’indirizzo sbagliato. L’aggressore ha sfruttato con precisione il comportamento dell’utente.

Commento Phishing

Quando si trasferiscono token su TON, gli utenti possono aggiungere un commento per annotare la transazione. Questa funzione è spesso utilizzata quando si effettuano depositi sulle borse, dove le borse di solito richiedono agli utenti di includere il loro ID utente nel commento del deposito. Tuttavia, questa funzione è spesso sfruttata da attori malintenzionati, che scrivono informazioni fraudolente nei commenti per rubare i beni degli utenti. Ad esempio:

Gli utenti devono prestare particolare attenzione all’NFT “Numero anonimo di Telegram”. Se un utente attiva il proprio account Telegram con un numero di Telegram anonimo, ma non attiva la verifica in due passaggi, e questo NFT è stato contraffatto, l’hacker può accedere direttamente all’account Telegram di destinazione e procedere con il successivo furto di beni e attività fraudolente.

Vulnerabilità dei contratti intelligenti

Le vulnerabilità di sicurezza negli smart contract possono portare alla perdita dei fondi memorizzati nel contratto. Gli utenti dovrebbero scegliere progetti che sono stati sottoposti a controlli approfonditi. Gli smart contract di TON sono programmati principalmente con il linguaggio FunC, anche se alcuni utilizzano il più avanzato Tact o il Fift di livello inferiore.

Tutti questi linguaggi sono molto originali. I nuovi linguaggi di programmazione comportano nuovi rischi per la sicurezza, in particolare per gli sviluppatori, che devono praticare abitudini di codifica sicure, padroneggiare le migliori pratiche di sicurezza e sottoporsi a rigorosi controlli di sicurezza prima di distribuirli nell’ambiente di produzione. Per motivi di spazio, questo articolo non tratterà in dettaglio la sicurezza dei contratti.

Attacco al falso deposito

Gli utenti dei portafogli o degli exchange dovrebbero essere consapevoli degli attacchi ai falsi depositi, che di solito si presentano in due forme:

  1. Gettoni falsi: Un aggressore emette un token con metadati identici al token di destinazione. Se il programma di deposito automatico non controlla se il token proviene dal contratto del minatore corretto, può portare a depositi errati.
  2. Rimbalzo: Il processo di trasferimento di TON richiede una relazione di invocazione tra i contratti di portafoglio di due utenti. Se il contratto del portafoglio del destinatario non esiste e la transazione è impostata come rimbalzabile, il messaggio rimbalzerà e i fondi originali, meno la commissione, saranno restituiti al mittente. Chi è interessato ai dettagli può consultare il nostro precedente articolo sui depositi falsi.

Conclusione

Questo articolo ha introdotto alcuni principi tecnici fondamentali di TON dal punto di vista della creazione di chiavi e portafogli, delle forme dei token e delle caratteristiche delle transazioni. Ha inoltre esplorato i potenziali problemi di sicurezza nell’utilizzo di TON, sperando di ispirare il vostro percorso di apprendimento.