Token-urile ERC-20 în detaliu

token-urile ERC-20 Az ERC20 tokenekről crypto hírek mycryptoption

Cu siguanță ai auzit deja despre token-urile ERC-20, însă puțini le pot defini exact. Ce sunt deci token-urile ERC-20?

Acestea sunt token-uri proiectate și utilizate exclusiv pe platforma Ethereum. Ele urmează o listă de standarde care le permite să poată fi partajate, schimbate pe alt token sau transferate în portofele digitale (wallet-uri). Comunitatea Ethereum a creat aceste standarde prin trei reguli opționale și șase obligatorii.

Nu e ușor de descris impactul pe care token-urile ERC-20 l-au avut asupra comunității crypto. Dar putem afirma cu tărie că sunt singurii responsabili pentru industria ICO de miliarde de dolari și au jucat un rol însemnat în acceptarea criptomonedelor la scară mai largă.

Drumul către contractele smart

Tehnologia blockchain și criptovalutele au intrat în prim-plan atunci un dezvoltator anonim, Satoshi Nakamoto, a creat Bitcoin. Motivele pentru care Bitcoin a fost revoluționar sunt multiple. Pentru prima dată s-a creat un sistem valutar care este deținut de oameni, de utilizator. Prin intermediul portofelului digital puteai trimite Bitcoin oricui, fără să fii nevoit să apelezi la serviciile băncilor.

Fiindcă a introdus lumea în mediul tehnologiei blocklchain, Bitcoin este cunoscut drept „blockchain-ul de primă generație”. În același timp, există restricții uriașe referitoare la efectuarea tranzacțiilor Bitcoin. Dacă dorești să trimiți bani prietenilor în cadrul unei tranzacții simple, individuale, Bitcoin va reprezenta soluția ideală. Dar ce se întâmplă dacă vrei să trimiți bani doar dacă prietenul tău execută o anumită sarcină într-o limită de timp stabilită? Cum poți manipula codul tranzacției pentru contabilizarea unei astfel de tranzacții complexe? La această întrebare a oferit răspuns Vitalik Buterin prin crearea Ethereum.

Ethereum și contractele smart

Vitalik Buterin și-a dat seama că tehnologia blockchain avea mult mai multă utilitate decât ca un simplu sistem de plată. Conform paginii sale web: „Ethereum este o platformă descentralizată care rulează contracte smart: aplicații care funcționează exact așa cum sunt programate, fără orice posibilitate de oprire, cenzură, fraudă sau intervenția unei a treia părți. Aceste aplicații rulează pe un blockchain construit la comandă, o infrastructură distribuită globală cu o capacitate enormă, care poate deplasa valori și poate reprezenta dreptul de proprietate.”

Cu alte cuvinte, Ethereum își propune să devină un supercalculator descentralizat unde oricine, de oriunde, poate închiria capacitate de calcul și crea aplicații descentralizate (Dapps) care vor rula pe platforma sa. Cum poți crea aceste Dapp-uri? Pentru a primi un răspuns, trebuie să analizăm contractele smart.

Contractele smart sunt contracte automate. Ele execută în mod independent instrucțiunile scrise în codul lor, care sunt executate la îndeplinirea anumitor condiții. Contractele smart ne permit să facem lucruri în ecosistemul Ethereum. Dacă cineva dorește să execute o anumită sarcină în Ethereum, va iniția un contract smart cu una sau mai multe persoane.

Întorcându-ne la secțiunea anterioară

Contractele smart ne ajută la codarea detaliilor tranzacționale complicate într-un format simplificat. Acestea au fost conceptualizate de către Nick Szabo. Potrivit acestuia, exemplul din viața reală al funcționării contractelor smart sunt automatele de produse. Dacă dorești ceva de la automat, doar simplu introduci bani în acesta, selectezi ce anume vrei să cumperi, iar mașina îți oferă acel lucru. Interacționezi direct cu automatul, fără implicarea unei terțe părți – atâta timp cât urmezi următorul proces:

  • Introducerea banilor
  • Selectarea produsului

…și vei obține ce ai solicitat. Să presupunem că tu și un prieten, Claudiu să zicem, doriți să interacționați printre voi prin utilizarea unui contract smart. Acesta funcționează în același fel ca automatul. Blochezi o cantitate de Ether (token-ul Ethereum) în contractul smart și stabilești condiția ca atunci când Claudiu îndeplinește anumite sarcini, contractul să deblocheze fondurile și să le trimită în wallet-ul lui Claudiu.

Contractele smart și ICO-urile

Pentru dezvoltatori, contractele smart au deschis o nouă dimensiune. Însă dezvoltatorii aveau nevoie de o modalitate prin care să-și finanțeze proiectele. Care era soluția? Trei litere: ICO. Termenul ICO este prescurtarea Initial Coin Offerings și este versiunea pentru criptomonede a IPO sau Initial Public Offerings. Comparativ cu IPO, ICO-urile sunt mult mai prietenoase cu anteprenorii, din următoarele motive: 

  • În primul rând, prezentarea proiectului în ICO este mult mai simplă. Tot ce trebuie să faci este să prezinți white paper-ul proiectului.
  • Oricine poate investi într-un proiect de care este interesat, poate achiziționa token-urile Dapp-ului, devenind astfel o parte a proiectului.

Despre token-urile ERC-20 în detaliu

Trebuie să precizăm un lucru înainte de a face cunoștință cu modul de funcționare a ICO-urilor. Dezvoltatorii sunt nevoiți să ofere ceva în schimbul investițiilor. Acest „ceva” sunt token-urile. Ca să-l definim în sens larg, dar nu generalizat, token-ul este reprezentarea a ceva din ecosistemul său particular. Acesta poate reprezenta o valoare, miză, drept de vot și multe altele. Token-ul nu se limitează la un anumit rol; în ecosistemul său nativ poate îndeplini diverse funcții.

Deci ce „roluri” pot îndeplini token-urile?

  • Taxă: Un token poate oferi acces la Dapp-uri. Fundamental, pentru a avea acces la aplicația descentralizată, trebuie să deții token.
  • Drepturi de vot: Token-urile pot conferi proprietarilor anumite drepturi de vot. Gândește-te la EOS de exemplu; deținerea de token EOS îți dă dreptul să votezi în legătură cu creatorii blocului.
  • Mijloc de schimb: Este unul dintre cele mai frecvente roluri în ecosistem ale token-urilor. Acestea pot ajuta la crearea unui sistem economic în interiorul aplicațiilor.
  • Îmbunătățirea experienței utilizatorului: Token-ul permite proprietarului să-și îmbogățească experiența de utilizator în limitele unui mediu particular. De exemplu în Brave (navigator web), proprietarii BAT (token-ul utilizat în Brave) au dreptul să-și îmbogățească experiența de utilizator prin adăugarea la platforma Brave a unor anunțuri sau alte servicii bazate pe atragerea atenției, utilizând token-ul BAT.
  • Valută: Poate fi utilizat ca mijloc de stocare a valorilor sau pentru desfășurarea unor tranzacții în interiorul/exteriorul unui ecosistem dat.
Așadar, am văzut cum funcționează contractele smart, ICO-urile și token-urile.

În același timp, am întâmpinat și primul obstacol. Să luăm ca exemplu aparatele de jocuri video. Ce pași trebuie să urmezi pentru a începe jocul?

  • Banii tăi fiat îi convertești în jetoane.
  • Prin intermediul jetoanelor poți juca la aparat, după ce le introduci în orificiu – acestea au fost proiectate să accepte jetoane în formă circulară.
  • După ce ai terminat, dacă ți-au rămas jetoane, le vei converti în bani fiat.

Să facem o paralelă între aparatele de jocuri video și platforma de contracte smart. Aparatele sunt Dapp-ul, iar jetoanele sunt token-urile tale native. Pentru a putea accesa serviciile Dapp-ului, trebuie să deții aceste jetoane.

Totuși, acest sistem are o parte problematică. Pentru a se potrivi în orificiul aparatului, jetoanele trebuie să aibă o mărime specifică. Ce s-ar întâmpla dacă apar aparate care nu acceptă jetoane circulare, ci doar pătrate? Pentru ca afacerea să se deruleze fără probleme, proprietarul aparatului trebuie să stabilească o regulă de bază. Fiecare aparat trebuie fabricat în așa fel încât să accepte jetoane circulare; nu poate accepta alte forme. În esență, este ceea ce face principiul ERC-20.

Problema design-ului diferitelor token-uri

Mai demult, fiecare ICO părea că vrea să „reinventeze roata”, din punct de vedere al execuției. Fiecare token avea propria listă de funcții; iar asta a dus la o serie de probleme noi.

Pentru crearea unui ecosistem sănătos pe Ethereum, este esențial ca Dapp-urile construite pe acesta să poată interacționa fluent. Ce se întâmplă dacă avem două token-uri, să zicem Alpha și Beta, și ambele dispun de o structură de contract smart diferită? În acest caz, dezvoltatorii trebuie să verifice atent ambele contracte și să stabilească precis cum pot interacționa între ele cele două token-uri.

Dacă există o sută de token-uri diferite cu o sută de contracte diferite, avem nevoie de o capacitate de calcul complexă pentru a stabili care contracte sunt capabile să comunice între ele. Acesta nu este cel mai fericit caz. Era nevoie de o soluție, iar pe 19 noiembrie 2015 Fabian Vogelsteller a găsit una ingenioasă.

Conform Wikipedia, ERC-20 este „o listă de reguli pe care un token Ethereum trebuie să o implementeze, oferind dezvoltatorilor posibilitatea să programeze modul în care vor funcționa noile token-uri în ecosistemul Ethereum. Standardul de token ERC-20 a devenit popular prin intermediul companiilor crowdfunding care lucrează la oferta inițială de monede (ICO), datorită simplității implementării și potențialului său de interoperabilitate cu alte standarde de token Ethereum.”

Mai simplu, ERC-20 este un ghid de reguli și reglementări care contribuie la realizarea unui model de creare a token-urilor, pentru contractele smart bazate pe Ethereum. “ERC” înseamnă Ethereum Request for Comment, în timp ce numărul “20” este numărul alocat acestei cereri. Acum c-am aflat ce este ERC-20, să-l disecăm mai mult și să vedem ce se întâmplă în spatele scenei.

Anatomia token-urilor ERC20

Regulile obligatorii sunt următoarele:

totalSupply (stoc total)
balanceOf (sold)
transfer (transfer)
transferFrom (inițiatorul transferului)
approve (aprobare)
alowance (permisiune)

Pe de altă parte, regulile opționale sunt:

Nume Token
Simbol
Decimala (până la 18)

Cele trei reguli opționale

Chiar dacă nu este obligatoriu să denumim token-urile, este important să le dăm o identitate. Numele este declarat astfel:

string public constant name = “Token Name”;

Pe urmă avem simbolurile. Nu putem subestima importanța acestora. Cel mai bun exemplu în acest sens este OmiseGo. Lumea cunoaște mult mai bine ce este OMG, decât termenul OmiseGo. Un simbol captivant ajută la o marcare mai bună. Modul adăugării simbolului:

string public constant symbol = “SYM”;

În final avem divizibilitatea, care ne ajută să determinăm cea mai mică valoare posibilă a unui token. O divizibilitate de 0 înseamnă că valoarea cea mai mică a token-ului este 1. Însă o divizibilitate de 2 înseamnă că cea mai mică valoare a sa va fi 0,01. Numărul maxim de decimale permise este de 18, declarat astfel:

uint8 public constant decimals = 18;

Să trecem la cele șase reguli obligatorii.

#1 totalSupply

[totalSupply] identifică numărul total de token-uri ERC-20 create. Scopul acestei metode este să identifice numărul de token-uri aflate în ecosistem.

Codul arată în felul următor:

contract MyERCToken {

uint256 _totalSupply = 1000000;

 

 function totalSupply() constant returns (uint256 theTotalSupply) {

    theTotalSupply = _totalSupply;

   return theTotalSupply;

 }

}

#2 balanceOf

Funcția balanceOf ne furnizează numărul token-urilor aflate pe o anumită adresă; în acest caz, pe cea a proprietarului contractului.

Codul se prezintă sub forma:

contract MyERCToken {

// Create a table so that we can map addresses

 // to the balances associated with them

mapping(address => uint256) balances;



 // Owner of this contract



 address public owner;

 

 function balanceOf(address _owner) constant returns (uint256 balance) {

 

 // Return the balance for the specific address



   return balances[_owner];

 }

}

#3 approve()

Odată ce soldul a fost verificat, proprietarul contractului poate aproba ca utilizatorul să colecteze numărul de token-uri necesar de pe adresa contractului. Această funcție verifică tranzacția față de stocul total de token-uri, pentru a se convinge că nu lipsește sau nu este în plus vreun token. Cu alte cuvinte, ne asigură că este imposibilă contrafacerea.

Notă: „msg.sender” este adresa proprietarului contractului.

contract MyERCToken {

// Create a table so that we can map

 // the addresses of contract owners to

 // those who are allowed to utilize the owner's contract



 mapping(address => mapping (address => uint256)) allowed;

 

 function approve(address _spender, uint256 _amount) returns (bool success) {

   allowed[msg.sender][_spender] = _amount;



   // Fire the event "Approval" to execute any logic

   // that was listening to it



   Approval(msg.sender, _spender, _amount);

   return true;

 }

}

#4 transfer()

După ce toate aceste verificări au fost efectuate și contractul știe că utilizatorul dispune de cantitatea de token-uri necesară îndeplinirii tranzacției, proprietarul contractului îi poate trimite token-uri folosind funcția transfer(). Această funcție permite proprietarului contractului să trimită o anumită cantitate de token pe o altă adresă- asemenea unei tranzacții convenționale de criptomonede, permite să fie transferate token-uri, din stoc către contul unui utilizator. Înainte ca „jocul” să înceapă, participanții trebuie să primească așa-numitul “BLU” din partea comerciantului.

contract MyERCToken {

 mapping(address => uint256) balances;

 

 // Note: This function returns a boolean value

 //       indicating whether the transfer was successful

 

function transfer(address _to, uint256 _amount) returns (bool success) {



   // If the sender has sufficient funds to send

   // and the amount is not zero, then send to

   // the given address



   if (balances[msg.sender] >= _amount

     && _amount > 0

     && balances[_to] + _amount > balances[_to]) {



     balances[msg.sender] -= _amount;

     balances[_to] += _amount;



     // Fire a transfer event for any

     // logic that's listening

     

Transfer(msg.sender, _to, _amount);

       return true;

     } else {

       return false;

     }

  }

}

#5 transferFrom()

De ce există încă o funcție de transfer?

Să luăm un exemplu, pentru a vedea de ce este transferFrom o completare atât de minunată a contracului ERC-20.

Cu toții trebuie să plătim lunar anumite sume; fie vorba de chirie, facturi, rate, etc. Aceste sume nu suntem obligați să le plătim în numerar; avem întotdeauna posibilitatea utilizării unei opțiuni de plată automate, prin intermediul băncii. Este exact ce ne oferă transferFrom() – ajută automatizarea transferurilor către conturile stabilite.

Codul:

contract MyERCToken {

 mapping(address => uint256) balances;

 

 function transferFrom(address _from, address _to, uint256 _amount) returns (bool success) {

   if (balances[_from] >= _amount

     && allowed[_from][msg.sender] >= _amount

     && _amount > 0

     && balances[_to] + _amount > balances[_to]) {

   balances[_from] -= _amount;

   balances[_to] += _amount;

   Transfer(_from, _to, _amount);

     return true;

   } else {

     return false;

   }

 }

}

#6 allowance()

În vederea efectuării tranzacției, cea mai importantă pe care contractul trebuie s-o cunoască este soldul utilizatorului. La urma urmei, utilizatorul ar trebui să dispună de cantitatea minimă de token-uri necesară efectuării tranzacției. Acesta este motivul pentru care contractul ERC-20 conține și această condiție. Dacă utilizatorul nu deține cantitatea minimă de token necesară, funcția va anula tranzacția. Codul arată așa:

function allowance(address _owner, address _spender) constant returns (uint256 remaining) {

   return allowed[_owner][_spender];

 }

Să adunăm codul

Odată ce știm cum se prezintă funcțiile individual, să aruncăm o privire asupra contractului pentru token-urile ERC-20.

Tehát, most, hogy megláttuk, hogyan működnek az egyes funkciók, vessünk egy pillantást az ERC-20 token szerződésre.

Codul a fost preluat de pe GitHub.

pragma solidity ^0.4.15;



contract MyERCToken

{



 // Create a table so that we can map addresses

 // to the balances associated with them



 mapping(address => uint256) balances;



 // Create a table so that we can map

 // the addresses of contract owners to

 // those who are allowed to utilize the owner's contract



 mapping(address => mapping (address => uint256)) allowed;



 // In this case, the total supply

 // of MyERCToken is fixed, but

 // it can very much be changed

 uint256 _totalSupply = 1000000;

 // Owner of this contract



 address public owner;
 

function totalSupply() constant returns (uint256 theTotalSupply) {



   // Because our function signature

   // states that the returning variable

   // is "theTotalSupply", we'll just set that variable

   // to the value of the instance variable "_totalSupply"

   // and return it



   theTotalSupply = _totalSupply;



   return theTotalSupply;

 }

 

 function balanceOf(address _owner) constant returns (uint256 balance) {

   return balances[_owner];

 }

 

 function approve(address _spender, uint256 _amount) returns (bool success) {

   allowed[msg.sender][_spender] = _amount;

 

 // Fire the event "Approval" to execute any logic

   // that was listening to it



   Approval(msg.sender, _spender, _amount);

   return true;



 }

 

 // Note: This function returns a boolean value

 //       indicating whether the transfer was successful



 function transfer(address _to, uint256 _amount) returns (bool success) {



   // If the sender has sufficient funds to send

   // and the amount is not zero, then send to

   // the given address

 

 if (balances[msg.sender] >= _amount

     && _amount > 0

     && balances[_to] + _amount > balances[_to]) {

     balances[msg.sender] -= _amount;

     balances[_to] += _amount;



     // Fire a transfer event for any

     // logic that's listening



     Transfer(msg.sender, _to, _amount);

       return true;

     } else {

       return false;

     }

  }

  

  function transferFrom(address _from, address _to, uint256 _amount) returns (bool success) {

   if (balances[_from] >= _amount

     && allowed[_from][msg.sender] >= _amount

     && _amount > 0

     && balances[_to] + _amount > balances[_to]) {

   balances[_from] -= _amount;

   balances[_to] += _amount;

   Transfer(_from, _to, _amount);

     return true;

   } else {

     return false;

   }

 }

 

 function allowance(address _owner, address _spender) constant returns (uint256 remaining) {

   return allowed[_owner][_spender];

 }



 // Triggered whenever approve(address _spender, uint256 _value) is called.

 event Approval(address indexed _owner, address indexed _spender, uint256 _value);

 // Triggered when tokens are transferred.

event Transfer(address indexed _from, address indexed _to, uint256 _value);

}

De ce sunt avantajoase token-urile ERC-20?

Din moment ce știm ce este ERC-20, sigur apare întrebarea: de ce este avantajoasă utilizareasa?

În primul rând, datorită comodității. Cum scriam mai devreme, dacă toată lumea și-ar crea propriul token cu propriile funcții, interoperabilitatea ar fi mai degrabă un coșmar. Ar fi chiar dureros dacă am lista aceste token-uri la exchange-uri. Transferul lor s-ar solda cu multe contracte rupte, făcându-la vulnerabile în fața atacului hackerilor.

Lichiditatea de care dispun token-urile ERC-20 are o importanță esențială din punct de vedere al evaluării globale a rețelei Ethereum. Dacă proiectele de pe Ethereum sunt active și interacționează între ele, vor atrage și mai multe proiecte și, în consecință, și mai mulți utilizatori în rețeaua Ethereum.

Neajunsurile pe care le au token-urile ERC-20

Primul este bug-ul Transfer(). Chiar dacă token-urile ERC-20 sunt înzestrate cu multe calități bune, au atras și numeroase critici. În Ethereum există două tipuri de cont: conturi deținute extern (EOA) – controlate de chei private – și conturi de contracte – controlate de codul lor de contract. Dacă dorești să intri în legătură cu un alt cont EOA, prin funcția Transfer () poți transfera token-urile necesare. Dar în cazul în care vrei să trimiți token-uri către un cont de contract utilizând funcția Transfer (), te vei lovi de un bug – care a produs deja pagube în valoare de aproximativ 1 milion de dolari. Marea problemă a funcției Transfer () este că după executarea sa destinatarul nu este informat în legătură cu transferul, chiar dacă tranzacția s-a desfășurat cu succes.

Cel care a atras atenția asupra acestei probleme este un utilizator pe nume “Dexaran”. Potrivit acestuia:

“Tranzacția unui token este o modificare a variabilelor interne ale contractului („soldul” expeditorului va scădea și „soldul” destinatarului va fi crește). Drept urmare, dacă destinatarul este un contract, utilizatorii trebuie să-și transfere token-urile folosind mecanismul approve +transferFrom; dacă destinatarul este o adresă deținută extern, utilizatorii trebuie să transfere token-urile prin funcția “transfer”. Dacă un utilizator comite o eroare și alege o funcție greșită, token-ul se va bloca în contract (contractul nu va recunoaște tranzacția). Token-urile blocate nu pot fi extrase în niciun fel. Crede cineva dintre dezvoltatorii token-urilor ERC-20 că utilizatorii nu vor comite niciodată astfel de greșeli atunci când umblă cu token-urile?”

Deci oferă această situație o bună oportunitate pentru combinarea approval() și transferFrom()? E adevărat, însă apare și o problemă. Nu este o operațiune sigură și, prin urmare, duce la posibilitatea unui atac de dublă cheltuială.

O altă critică adusă ERC-20 de leagă de faptul că permite oamenilor să-și creeze token-uri mult prea ușor. Astfel, punctul de intrare este prea scăzut; ca urmare, piața este inundată de token-uri inutile.

Cum arată viitorul pentru token-urile ERC-20

Cu toate că token-urile ERC-20 au contribuit puternic la creșterea ecosistemului crypto, acestea au abuzat de ospitalitatea cu care au fost primite. Lumea experimentează noi standarde ca ERC223, ERC 777 etc., dar pentru deocamdată ERC20 rămâne pe poziții.

Dexaran subliniază următoarele motive pentru care ERC-20 rămâne deocamdată standardul preferat:

  • Iresponsabilitatea dezvoltatorilor de token nu este incriminată.
  • Fiindcă Ethereum Foundation promovează standardul de token ERC-20, chiar dacă se știe că acesta conține bug-uri. Aceeași situație a fost întâlnită mai demult la TheDAO. Ar trebui să spună „opriți-vă acum”, dar nu face acest lucru.
  • Principalul scop al dezvoltării token-ului este mai degrabă acapararea de fonduri, decât crearea de produse.
  • Utilizarea unui alt standard ar produce efecte mai mari pe rețea. Nu este un lucru de dorit, deoarece Ethereum se confruntă deja cu probleme de scalabilitate.

Schimbarea este întotdeauna un proces lent și se pare că trebuie să mai așteptăm până vom putea aplica un alt standard. Cu toate acestea, să nu comitem greșeala de a degrada standardul ERC-20. Acesta merită tot respectul pentru impactul profund pe care l-a avut asupra spațiului crypto.

Mai multe articole