Selle artikli eesmärk on näidata, kuidas luua võimalikult lühikese ajaga ERC20 luba.
Alustame põhitõdedest: Mis on ERC20 märk?
Viimastel aastatel on ERC20 märgistuse spetsifikatsioonist saanud Ethereumi märkide defacto standard. Teisisõnu, enamik Ethereumi lepinguid, mis seal täna on, vastavad ERC20 nõuetele. Selles artiklis kirjeldatakse üksikasjalikult, kuidas saate oma Ethereumi märgi luua, kuid enne alustamist uurime lähemalt ERC20 standardit.
Mis teeb ERC20 märgid nii atraktiivseks ja edukaks? Mängul on mitu tegurit:
Nii nagu teised Ethereumi märgid, rakendatakse ka ERC20 märgid nutikate lepingutena ja täidetakse Ethereumi virtuaalses masinas (EVM) detsentraliseeritud viisil.
Ethereumi nutikad lepingud on kirjutatud soliidsuses. Kuigi on ka alternatiivseid keeli, siis vaevalt keegi neid selleks otstarbeks kasutab. Tugevus on sarnane JavaScripti versiooniga, nii et kui teil on JavaScripti või isegi Java ja teiste C-tüüpi keelte osas mõningaid teadmisi, ei tohiks teil olla raskusi selle välja selgitamisega, mida Solidity'i kooditükk teeb, isegi enne, kui olete piisavalt Solidity'i kasutamiseks piisavalt kasutanud seda.
Siit saabki see lõbu alguse, kuna peaksite saama lihtsa ERC20 lepingu loomisega alustada kohe. See on lihtne ülesanne, piisavalt lihtne, et see artikkel näitab, kuidas saate kirjutada ja juurutada ERC20 märki vähem kui tunni jooksul.
Sellel demonstratsioonil loome märgiks ERC20 paljaste kontidega rakenduse, ilma liiga paljude kellade ja viledeta. Kuid ma olen reaalses maailmas näinud palju sama lihtsaid märke ja neil kipub üsna hästi minema.
Lihtsamalt öeldes määratleb ERC20 standard funktsioonide komplekti, mida peavad rakendama kõik ERC20 märgid, et võimaldada integreerumist teiste lepingute, rahakottide või turuplatsidega. See funktsioonide komplekt on üsna lühike ja põhiline.
function totalSupply() public view returns (uint256); function balanceOf(address tokenOwner) public view returns (uint); function allowance(address tokenOwner, address spender) public view returns (uint); function transfer(address to, uint tokens) public returns (bool); function approve(address spender, uint tokens) public returns (bool); function transferFrom(address from, address to, uint tokens) public returns (bool);
ERC20 funktsioonid võimaldavad välisel kasutajal, näiteks krüptotaskurakendusel, teada saada kasutaja saldot ja kanda nõuetekohase volitusega raha ühelt kasutajalt teisele.
Nutilepingus määratletakse kaks konkreetselt määratletud sündmust:
event Approval(address indexed tokenOwner, address indexed spender, uint tokens); event Transfer(address indexed from, address indexed to, uint tokens);
Nendele sündmustele viidatakse või eraldunud kui kasutajale antakse õigused kontolt märkide väljavõtmiseks ja pärast märkide tegelikku ülekandmist.
Lisaks standardsetele ERC20 funktsioonidele on paljudel ERC20 žetoonidel ka täiendavad väljad ja mõned neist on muutunud de facto osaks ERC20 standardist, kui mitte kirjalikult, siis praktikas. Siin on mõned näited sellistest väljadest.
string public constant name; string public constant symbol; uint8 public constant decimals;
Siin on mõned punktid seoses ERC20 ja usaldusväärsuse nomenklatuuriga:
public
funktsioonile pääseb juurde väljaspool lepingutview
tähendab põhimõtteliselt konstantset, s.t lepingu sisemist olekut funktsioon ei muudaevent
on Solidity viis lubada klientidel nt. teie rakenduse kasutajaliidese teavitamine lepingus sisalduvate konkreetsete juhtumite kohtaEnamik Solidity keelekonstruktsioone peaksid olema selged, kui teil on juba Java / JavaScripti põhioskused.
Nüüd, kui oleme visandanud põhitõed ja selgitanud, mida on vaja ERC20 loa loomiseks, on aeg hakata loogikat kirjutama.
Esiteks peame määratlema kaks kaardistusobjekti. See on assotsiatiivse või võtme / väärtuse massiivi tugevuse mõiste:
mapping(address => uint256) balances; mapping(address => mapping (address => uint256)) allowed;
Avaldis mapping(address => uint256)
määratleb assotsiatiivse massiivi, mille võtmed on tüüpi address
- number, mida kasutatakse konto aadresside tähistamiseks, ja mille väärtused on tüüpi uint256
- 256-bitine täisarv, mida tavaliselt kasutatakse märgisaldode salvestamiseks.
Esimene kaardistusobjekt balances
hoiab iga omaniku konto märgisaldot.
Teine kaardistusobjekt allowed
sisaldab kõiki kontosid, mis on antud kontolt väljavõtmiseks heaks kiidetud, ja nende jaoks lubatud väljamaksesummat.
Nagu näete, on lubatud kaardistamise väärtus väli iseenesest kaardistamise joonistamiskonto aadress tema kinnitatud väljamakse summaga.
Need kaardistused koos kõigi teiste lepinguväljadega salvestatakse plokiahelas ja need ka jäävad kaevandatud mille tulemusel levitatakse muudatusi kõikidele võrgu kasutaja sõlmedele.
Blockchaini salvestusruum on kallis ja teie lepingu kasutajad peavad ühel või teisel viisil maksma. Seetõttu peaksite alati proovima minimeerida salvestusmahtu ja kirjutada plokiahelasse.
Nüüd, kui nõutavad andmestruktuurid on paigas, saame hakata ERC20 loogikat tegelikult vastavatesse funktsioonidesse kirjutama.
Kuidas me määrame ICO-märkide arvu? Noh, ICO-märkide maksimaalse arvu määramiseks on mitmeid viise ja see asi võib olla väärt pikka arutelu iseenesest.
Meie ECR20 õpetuse jaoks kasutame kõige lihtsamat lähenemisviisi: määrake märkide kogusumma lepingu loomise ajal ja määrake need kõik algselt „lepingu omanikule“, st kontole, mis nutika lepingu juurutas:
uint256 totalSupply_; constructor(uint256 total) public { totalSupply_ = total; balances[msg.sender] = _totalSupply; }
Konstruktor on spetsiaalne funktsioon, mille Ethereum kutsub automaatselt kohe pärast lepingu rakendamist. Seda kasutatakse tavaliselt loa oleku initsialiseerimiseks parameetrite abil, mille on edastanud lepingu juurutuskonto.
msg
on Ethereumi enda deklareeritud ja asustatud globaalne muutuja. See sisaldab lepingu täitmiseks olulisi andmeid. Siin kasutatav väli: msg.sender
sisaldab Ethereumi kontot, mis täidab praeguse lepingu funktsiooni.
Ainult kasutusel olev konto saab sisestada lepingu ehitaja. Lepingu sõlmimisel eraldab see funktsioon saadaolevad märgid lepingu omaniku kontole.
function totalSupply() public view returns (uint256) { return totalSupply_; }
See funktsioon tagastab kõigi selle lepinguga eraldatud märkide arvu olenemata omanikust.
function balanceOf(address tokenOwner) public view returns (uint) { return balances[tokenOwner]; }
balanceOf
tagastab konto praeguse märgisaldo, mis on identifitseeritud selle omaniku aadressi järgi.
function transfer(address receiver, uint numTokens) public returns (bool) { require(numTokens <= balances[msg.sender]); balances[msg.sender] = balances[msg.sender] — numTokens; balances[receiver] = balances[receiver] + numTokens; emit Transfer(msg.sender, receiver, numTokens); return true; }
Nagu nimigi ütleb, on transfer
funktsiooni kasutatakse numTokens
liikumiseks märkide kogus omaniku saldolt teise kasutaja saldole või receiver
. Ülemineku omanik on msg.sender
st funktsiooni täitja, mis tähendab, et ainult märkide omanik saab neid teistele üle kanda.
Kindluse viis predikaadi väitmiseks on require
Sel juhul on ülekandval kontol ülekande teostamiseks piisav saldo. Kui a require
avaldus ebaõnnestub, tehing viiakse kohe tagasi, ilma et plokiahelasse oleks muudatusi kirjutatud.
Vahetult enne väljumist käivitab funktsioon ERC20 sündmuse Transfer
võimaldades registreeritud kuulajatel reageerida selle valmimisele.
Seda funktsiooni kasutatakse kõige sagedamini märgituru stsenaariumi korral.
function approve(address delegate, uint numTokens) public returns (bool) { allowed[msg.sender][delegate] = numTokens; emit Approval(msg.sender, delegate, numTokens); return true; }
Mis approve
on lubada omanikul, st msg.sender
kinnitada delegeeritud konto - võib-olla ka turg ise - oma kontolt märgid välja võtma ja teistele kontodele kandma.
Nagu näete, kasutatakse seda funktsiooni stsenaariumide jaoks, kus omanikud pakuvad turul märke. See võimaldab turuosal tehingu lõpule viia ilma eelnevat nõusolekut ootamata.
Selle funktsiooni käivitamisel käivitab see funktsioon Approval
sündmus.
function allowance(address owner, address delegate) public view returns (uint) { return allowed[owner][delegate]; }
See funktsioon tagastab omaniku praeguse heakskiidetud märkide arvu konkreetsele delegaadile, nagu on sätestatud approve
funktsioon.
transferFrom
funktsioon on approve
eakaaslane funktsioon, mida me varem arutasime. See võimaldab tagasivõtmiseks heakskiidetud delegaadil kanda omaniku raha kolmanda osapoole kontole.
function transferFrom(address owner, address buyer, uint numTokens) public returns (bool) { require(numTokens <= balances[owner]); require(numTokens <= allowed[owner][msg.sender]); balances[owner] = balances[owner] — numTokens; allowed[owner][msg.sender] = allowed[from][msg.sender] — numTokens; balances[buyer] = balances[buyer] + numTokens; Transfer(owner, buyer, numTokens); return true; }
Need kaks require
avaldused funktsiooni alguses peavad kontrollima, kas tehing on seaduslik, st et omanikul on ülekandmiseks piisavalt märke ja volitatud isikul on (vähemalt) numTokens
tagasi tõmbuma.
Lisaks numTokens
summa omanikult ostjale, lahutab see funktsioon ka numTokens
delegaadi toetusest. Põhimõtteliselt võimaldab see antud toetusega delegaadil jagada see mitmeks eraldi väljavõtmiseks, mis on tüüpiline turu käitumine.
Võiksime siin peatuda ja meil oleks kehtiv ERC20 rakendus. Siiski tahame minna sammu kaugemale, kuna soovime tööstuslikku tugevuse märki. See eeldab, et peaksime oma koodi natuke turvalisemaks muutma, ehkki suudame siiski märgi suhteliselt lihtsana hoida, kui mitte lihtsalt.
SafeMath on raamatukogu Solidity, mille eesmärk on tegeleda häkkeritega ühel viisil lepingute rikkumisega: täisarvu ülevoolu rünnak. Sellise rünnaku korral sunnib häkker lepingu kasutama valesid arvväärtusi, edastades parameetrid, mis võtavad asjakohased täisarvud minevik nende maksimaalsed väärtused.
SafeMath kaitseb selle eest enne aritmeetilise toimingu tegemist ülevoolu testimisega, eemaldades seeläbi ülevoolu rünnaku ohu. Raamatukogu on nii väike, et mõju lepingu suurusele on minimaalne, see ei too kaasa jõudlust ja hoiukulusid on vähe.
Lisagem SafeMath meie koodile:
library SafeMath { // Only relevant functions function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a — b; } function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; assert(c>= a); return c; } }
SafeMath kasutab assert
avaldused edastatud parameetrite õigsuse kontrollimiseks. Peaks assert
ebaõnnestub, funktsiooni käivitamine peatatakse kohe ja kõik plokiahela muudatused veeretatakse tagasi.
Järgmisena lisame järgmise teeki tutvustava lause kompuutrisse Solidity:
using SafeMath for uint256;
Seejärel asendame alguses kasutatud naiivse aritmeetika funktsioonidega SafeMath:
balances[msg.sender] = balances[msg.sender].sub(numTokens); balances[receiver] = balances[receiver].add(numTokens); balances[buyer] = balances[buyer].add(numTokens); balances[owner] = balances[owner].sub(numTokens);
Rakenduses Solidity on nutika lepingu funktsioonid ja sündmused pakitud üksusesse, mida nimetatakse a leping mille saate vaikselt tõlkida „plokiahelaklassiks“. Allpool on meie loodud ERC20-ga ühilduv leping, sealhulgas meie koodi kokkuvõte. Nime ja sümbolivälju saab soovi korral muuta. Enamik märke hoiab kümnendväärtust 18-ga, nii et me teeme sama.
On kätte jõudnud aeg kasutage meie lepingut plokiahelas . Pärast juurutamist kantakse meie leping üle kõigile võrgus osalevatele sõlmedele. Kõik lepingus tehtud muudatused levitatakse kõigis osalevates sõlmpunktides.
Ethereumi arendajad kasutavad tavaliselt juurutamisvahendeid nagu Trühvel . Isegi Trühvel on selle artikli piiratud vajaduste rahuldamiseks ülitugev ja lihtne veebitööriist nimega Remiks piisab.
Selle kasutamiseks peate installima MetaMask pistikprogramm oma brauseris ja Rinkeby (Ethereumi testvõrk) konto, milles on vähemalt mõni Rinkeby Eeter. Need on suhteliselt lihtsad toimingud, nii et me ei hakka seda üksikasjalikumalt kirjeldama.
Kui teil pole kumbagi, minge üle MetaMask ja Rinkeby allalaadimislinkide jaoks ning selgete installimis- ja kasutusjuhiste saamiseks.
Nüüd, kui meil on kõik ehitusplokid paigas, läheme üle Remiks ja kleepige ülaltoodud kood, sealhulgas pragmarida ja SafeMathi teek, veebiredaktorisse.
Seejärel liigume paremale teisele vahelehele nimega “ Jookse 'Ja klõpsake nuppu' Juuruta . ” Ilmub hüpikaken MetaMask, mis palub meil tehingut kinnitada. Muidugi kiidame selle heaks.
Põhiline : https://gist.github.com/giladHaimov/8e81dbde10c9aeff69a1d683ed6870be#file-basicerc20-sol
Palju õnne! Olete just juurutanud oma esimese ERC20 loa, nagu tõene Ethereumi professionaal . Nagu lubatud, on märgis lihtne ja kerge, kuid siiski täiesti töökorras, ühilduv ERC20 standardiga ja turvatud MathSafe abil. See on kogu Blockchaini ostmiseks valmis, sellega saab tasuda ja üle kanda.
Ei, isegi mitte lähedal, kuna meie lühike meeleavaldus kriimustab vaevu pinda ja tegeleb ainult nutika lepingute väljatöötamise ühe aspektiga.
Nutikad lepingud võivad olla palju keerukamad, sõltuvalt teie äriloogikast, kasutajate interaktsiooni modelleerimisest, olenemata sellest, kas lubate märkide vermimist ja kirjutamist, lepingusse sisse viidud olelusringi muudatusi või vajadust administraatori taseme võimaluste järele, mis tavaliselt kaasnevad admini poolt lubatud funktsioonide kogum ja nii edasi. Saate pildi.
Siiski, kui saate korrata seda, mida me siin tegime, on see kindel alus oma teadmiste laiendamiseks ja vajadusel keerukamate lepingute sõlmimiseks.
Nutikas leping on kooditükk, mis täidetakse Ethereumi virtuaalses masinas. Ethereumi nutileping on muutumatu ning võib eetri ja andmeid saata või vastu võtta.
Lihtsustatult öeldes on ERC20 märgid lepingud, mis rakendavad ERC20 standardit. Nende lepingutega hõlmatud toimingud hõlmavad žetoonide kogu pakkumise ja tasakaalu ning nende ülekandmiseks kasutatud meetodite hankimist.
Ethereumi arendamine toimub praegu Solidity'is, lepingupõhises programmeerimiskeeles, mis on inspireeritud JavaScripti, Pythoni ja C ++ versioonidest.
ERC tähistab Ethereumi kommentaaritaotlust. Sellele taotlusele määratakse number 20, seega ka järelliide.