Ghidul începătorului pentru TON: Conturi, jetoane și securitate

Context

TON (The Open Network) este o platformă blockchain descentralizată proiectată și dezvoltată inițial de echipa Telegram. TON își propune să ofere o platformă blockchain de înaltă performanță și scalabilă pentru a sprijini aplicații descentralizate (DApps) și contracte inteligente la scară largă.

TON este unic prin faptul că este ușor de utilizat, profund integrat cu Telegram, permițând oamenilor obișnuiți să utilizeze cu ușurință jetoanele. În același timp, este complex, cu o arhitectură care este distinctă de alte blockchains și utilizează un limbaj de contracte inteligente non-mainstream numit FunC.

Astăzi, vom discuta despre caracteristicile TON și securitatea activelor utilizatorilor din perspectiva conturilor, jetoanelor și tranzacțiilor.

Caracteristici ale TON

Generarea de conturi

Metoda de generare a unei adrese de cont pe TON este diferită de cele mai multe blockchains; este o adresă de contract inteligent. În primul rând, totul începe cu o cheie privată. TON utilizează în principal algoritmul Ed25519 pentru a genera o cheie publică, procesul fiind următorul:

Există două forme ale cheii publice: una este cheia publică brută calculată din cheia privată, care arată astfel:

E39ECDA0A7B0C60A7107EC43967829DBE8BC356A49B9DFC6186B3EAC74B5477D

Cealaltă este o cheie publică „înfrumusețată”, care include unele informații și biți de verificare, și arată astfel:

Pubjns2gp7DGCnEH7EOWeCnb6Lw1akm538YYaz6sdLVHfRB2

Dacă credeți că doar obținerea cheii publice vă va permite să obțineți adresa contului, ca în Ethereum, vă înșelați. Simpla obținere a cheii publice a utilizatorului nu este suficientă pentru a calcula adresa contului utilizatorului.

După cum s-a menționat, adresa contului utilizatorului este o adresă a contractului inteligent, dar cum puteți implementa un contract inteligent fără a avea un cont?

Secvența corectă este să se calculeze mai întâi adresa, să se primească o anumită sumă inițială de jetoane și apoi să se implementeze contractul. Procesul de calculare a adresei contului este prezentat în diagrama următoare:

Adresa unui utilizator se prezintă, de asemenea, în mai multe forme. În primul rând, există forma brută, care arată astfel:

0:b4c1b2ede12aa76f4a44353944258bcc8f99e9c7c474711a152c78b43218e296

Apoi există un formular ușor de utilizat, care arată astfel:

Rețea principală:

  • Bounceable: EQC0wbLt4Sqnb0pENTlEJYvMj5npx8R0cRoVLHi0MhjilkPX
  • Non-bounceable: UQC0wbLt4Sqnb0pENTlEJYvMj5npx8R0cRoVLHi0Mhjilh4S

Testnet:

  • Bounceable: kQC0wbLt4Sqnb0pENTlEJYvMj5npx8R0cRoVLHi0Mhjilvhd
  • Non-bounceable: 0QC0wbLt4Sqnb0pENTlEJYvMj5npx8R0cRoVLHi0MhjilqWY

Observând cu atenție aceste adrese, puteți vedea că ele diferă doar la primele și ultimele caractere, cele account_id din mijloc fiind aceleași.

Cu toate acestea, încă nu putem vedea relația dintre cheia publică și adresa contului.

Secretul constă în initial data de la început, care conține cheia publică a unui utilizator, permițându-i acestuia să controleze contractul portofelului. workchainId este ușor de înțeles; TON nu este doar un singur lanț, ci este format din mai multe cioburi.

Fiecare shard este o parte a întregii rețele, gestionând conturi și tranzacții specifice. Pentru a localiza și gestiona contractele inteligente, este necesar să se specifice în ce shard se află acestea. Care este diferența dintre Bounceable și Non-bounceable?

Acest lucru se referă la modul în care contractele inteligente funcționează, dar să continuăm să privim mai departe.

Contract de portofel

Mai jos este prezentat un fragment din codul sursă al unui contract al portofelului utilizatorului. Acesta arată că, atunci când primește un mesaj de la utilizator, citește patru parametri: stored_seqno, stored_subwallet, public_key și 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));

//...

}

Într-adevăr, atunci când acest contract de portofel de utilizator este implementat, acesta necesită anumiți parametri inițiali, inclusiv un public_key pe 256 de biți. Acest lucru garantează că fiecare utilizator are o adresă de contract unică, chiar și atunci când utilizează același cod de contract.

Fiecare tranzacție inițiată de utilizator trebuie să fie semnată cu in_msg, apoi verificată de contractul portofelului (check_signature), după care contractul va efectua operațiuni pe blockchain. De aici, putem deduce că cheia publică a unui utilizator poate corespunde mai multor adrese de portofel.

Implementarea unor contracte de portofel diferite sau utilizarea unor date de inițializare diferite va duce la adrese de contract complet diferite.

Jetton Token

Un token reprezintă un activ pe blockchain, ceea ce îl face un element fundamental pe care trebuie să îl înțelegem. Jetton este forma standard a jetoanelor TON și este compus din două contracte: Jetton-minter și Jetton-wallet.

Atunci când este emis un jeton, este creat un contract Jetton-minter. Această inițializare a contractului înregistrează informații precum oferta totală de jetoane, administratorul, codul portofelului și alte detalii.

Atunci când jetoanele sunt distribuite utilizatorilor, contractul Minter implementează un contract de portofel pentru fiecare utilizator. În timpul inițializării contractului, acesta înregistrează soldul utilizatorului, proprietatea, adresa contractului token Minter, codul portofelului utilizatorului și alte informații relevante. Fiecare utilizator are un contract implementat individual.

Este important să rețineți că contractul creat aici este un contract de portofel pentru gestionarea jetoanelor Jetton specifice, care este diferit de contractul de portofel al contului utilizatorului. owner_address înregistrată aici este adresa portofelului contului utilizatorului.

Atunci când utilizatorul Alice transferă jetoane către utilizatorul Bob, relația de invocare este următoarea:

Alice semnează tranzacția prin intermediul unei aplicații în afara lanțului și trimite o comandă operațională prin intermediul contractului portofelului său. Aceste comenzi vor invoca în continuare portofelul ei de jetoane pentru a executa transferul. Atunci când portofelul de jetoane al lui Bob primește jetoanele, acesta notifică contractul portofelului lui Bob (adresa proprietarului portofelului Jetton al lui Bob).

Dacă în timpul tranzacției există resturi de gaz, acestea vor fi returnate la adresa corespunzătoare, de obicei contractul de cont al lui Alice.

Mai jos este un exemplu de transfer Jetton token analizat de browserul Tonviewer:

În timp ce un transfer ERC20 necesită doar o singură invocare a contractului, un transfer Jetton token necesită cel puțin patru invocări ale contractului. Această metodă este concepută pentru a permite concurența pe lanț, îmbunătățind eficiența tranzacțiilor.

Tranzacții

Atunci când are loc un anumit eveniment într-un cont TON, acesta declanșează o tranzacție. Cel mai comun eveniment este „primirea unui mesaj”. O tranzacție include următoarele elemente:

  • Mesajul primit care declanșează inițial contractul (cu metode speciale de declanșare disponibile).
  • Acțiuni contractuale care rezultă din mesajul primit, cum ar fi actualizarea stocării contractului (opțional).
  • Mesaje de ieșire trimise altor participanți (opțional).

Există mai multe caracteristici cheie de care trebuie să țineți cont în ceea ce privește tranzacțiile:

  1. Asincron: Tranzacțiile TON nu sunt finalizate printr-un singur apel; acestea pot necesita transmiterea de mesaje către mai multe contracte inteligente diferite pentru a executa o serie de apeluri. Din cauza rutei diferite în lanțurile sharded, TON nu poate garanta ordinea de livrare a mesajelor între mai multe contracte inteligente.
  2. Taxe: Natura asincronă a tranzacțiilor introduce o provocare în estimarea comisioanelor consumate. Prin urmare, portofelele trimit adesea un mic jeton suplimentar ca taxă la inițierea unei tranzacții. Dacă contractul solicitat are un mecanism bun de gestionare a taxelor, taxele rămase vor fi returnate portofelului utilizatorului. Utilizatorii pot observa că jetoanele din portofelul lor scad brusc și apoi cresc din nou după câteva minute, ceea ce se datorează acestui mecanism.
  3. Săriți: Bounce este un mecanism de tratare a erorilor în contracte. În cazul în care contractul apelat nu există sau produce o eroare, iar tranzacția este setată ca putând fi respinsă, un mesaj de respingere va fi returnat contractului apelant. De exemplu, dacă un utilizator inițiază un transfer și apare o eroare în timpul procesului, este necesar un mesaj de respingere, astfel încât contractul portofelului utilizatorului să își poată restabili soldul. Aproape toate mesajele interne trimise între contractele inteligente ar trebui să poată fi respinse, ceea ce înseamnă că ar trebui să aibă bitul „bounce” setat.

Securitatea activelor

TON are multe caracteristici care pot duce la probleme de securitate, astfel încât utilizatorii trebuie să fie conștienți de unele capcane comune.

Atacul privind reținerea taxelor

După cum s-a menționat, portofelele trebuie adesea să trimită o mică taxă suplimentară pentru a preveni eșecul tranzacției, ceea ce oferă o oportunitate pentru atacatori. Dacă sunteți un utilizator al portofelului TON, este posibil să fi întâlnit o situație în care portofelul dvs. primește frecvent diverse NFT-uri sau token-uri.

Inițial, acestea pot părea niște aruncări de jetoane de gunoi, dar după ce verificați detaliile tranzacției, aflați că pot fi vândute pentru o sumă semnificativă de bani. Cu toate acestea, atunci când încercați să inițiați o tranzacție, observați că taxa necesară este extrem de mare (1 TON). În acest moment, ar trebui să fiți precaut, deoarece ar putea fi vorba de o înșelătorie cu taxe.

Atacatorii creează un contract simbolic atent elaborat care determină portofelul să estimeze o taxă de transfer excesiv de mare, dar în realitate, doar taxa este reținută și nu este trimis niciun mesaj de transfer.

Prima și ultima cifră Phishing

Phishing-ul cu prima și ultima cifră nu este unic pentru TON; acest atac de phishing există pe multe blockchains importante. Atacatorii generează un cont fals pentru fiecare adresă de utilizator din rețea cu aceleași prime și ultime cifre.

Atunci când un utilizator inițiază un transfer, atacatorul trimite și un transfer mic, după tranzacția utilizatorului, pentru a lăsa o înregistrare în istoricul tranzacțiilor utilizatorului. Atunci când utilizatorul destinatar dorește să trimită jetoanele înapoi, ar putea copia adresa din istoricul tranzacțiilor sale, care ar putea fi adresa atacatorului, ceea ce duce la un transfer la o adresă greșită. Atacatorul a exploatat cu exactitate comportamentul utilizatorului.

Comentariu Phishing

Atunci când transferă jetoane pe TON, utilizatorii pot adăuga un comentariu pentru a adnota tranzacția. Această caracteristică este adesea utilizată atunci când se fac depuneri pe burse, unde bursele solicită de obicei utilizatorilor să își includă ID-ul de utilizator în comentariul de depunere. Cu toate acestea, această caracteristică este frecvent exploatată de actori rău intenționați, care scriu informații frauduloase în comentarii pentru a fura activele utilizatorilor. De exemplu:

Utilizatorii ar trebui să fie deosebit de precauți cu privire la NFT „Număr Telegram anonim”. Dacă un utilizator își activează contul Telegram cu un număr Telegram anonim, dar nu activează verificarea în doi pași, iar acest NFT este fraudat, hackerul se poate conecta direct la contul Telegram vizat și poate continua cu furtul de bunuri și activitățile frauduloase ulterioare.

Vulnerabilități ale contractelor inteligente

Vulnerabilitățile de securitate din contractele inteligente pot duce la pierderea fondurilor stocate în contract. Utilizatorii ar trebui să aleagă proiecte care au fost supuse unui audit aprofundat. Contractele inteligente ale TON sunt programate în principal utilizând limbajul FunC, deși unele utilizează limbajul mai avansat Tact sau limbajul de nivel inferior Fift.

Toate aceste limbaje sunt extrem de originale. Noile limbaje de programare aduc noi riscuri de securitate, în special pentru dezvoltatori, care trebuie să practice obiceiuri de codare sigure, să stăpânească cele mai bune practici de securitate și să se supună unor audituri de securitate riguroase înainte de implementarea în mediul de producție. Din cauza constrângerilor de spațiu, acest articol nu va discuta în detaliu securitatea contractelor.

Atac cu depunere falsă

Utilizatorii de portofele sau schimburi ar trebui să fie conștienți de atacurile cu depozite false, care de obicei se prezintă sub două forme:

  1. Jetoane false: Un atacator emite un jeton cu metadate identice cu jetonul țintă. În cazul în care programul de depunere automată nu verifică dacă jetonul provine de la contractul de minare corect, acesta poate duce la depuneri incorecte.
  2. Săriți: Procesul de transfer al TON necesită o relație de invocare între contractele portofel ale celor doi utilizatori. În cazul în care contractul de portofel al destinatarului nu există și tranzacția este setată ca putând fi respinsă, mesajul va fi respins, iar fondurile originale, minus taxa, vor fi returnate expeditorului. Cei interesați de detalii pot consulta articolul nostru anterior privind depozitele false.

Concluzie

Acest articol a prezentat câteva principii tehnice fundamentale ale TON din perspectiva creării cheii și a portofelului, a formelor de jetoane și a caracteristicilor tranzacțiilor. De asemenea, a explorat potențialele probleme de securitate la utilizarea TON, în speranța de a vă inspira în călătoria dumneavoastră de învățare.