Lihtne juhend nutikate lepingute ühikatsete kirjutamiseks

http://upstate.agency/smart-contracts

Head ühikatestid on nutika lepingu arendamise jaoks kriitilise tähtsusega. Kuna arukad lepingud on muutumatud ja vastutavad sageli suurte rahasummade haldamise eest, võiks väita, et nutikate lepingute jaoks heade ühiktestide väljatöötamine on olulisem kui traditsioonilised veebi- ja mobiilirakendused.

Viimase kahe kuu jooksul on meil olnud väga suur õnn teha tihedat koostööd finantsteenuste pakkujaga, kes on välja töötanud uuendusliku platvormi väärtpaberite märgistamiseks regulatiivsel viisil. Nende peagi avaldatav platvorm tutvustab võimalust miljardite dollarite väärtpaberite ülekandmiseks plokiahelale.

Nende käivitamise toetuseks tegime tihedat koostööd nende insenerimeeskonnaga, rakendasime põhjalikku testkatet ja viisime läbi meie veaotsingu protsessi. Kogemustest eemaldusime mõne peamise kaalutlusega, samuti paar näpunäidet, mida saate kasutada nutikate lepingute jaoks ühiskatsete väljatöötamisel.

Hankige mõistlik ülevaade äriloogikast

Esimese asjana veenduge, et olete oma hajutatud rakenduste (dapp) äriloogikast põhjalikult aru saanud. On kasulik dokumenteerida probleemid, mida teie dapp lahendab, ja kuidas see nende lahendamisel sujub. Samuti peate tuvastama erinevad piirangud, mis teie dappil on. Näiteks kehtestavad enamus dappide rakendusi mingil kujul rollipõhise juurdepääsu kontrollimise või lepingupõhise juurdepääsu kontrolli. Oluline on dokumenteerida need piirangud ja nende mõju kasutamisele.

Ja mitte ainult, soovite ka oma dapi töövoo ümber kirjutada. Kas on vaja, et teatud lepingud aktiveeritaks enne teisi? Kas konkreetse lepingu täitmiseks tuleks konkreetset lepingut peatada või mitte? jne Need on äriloogika ja töövooga seotud nõuded, mida tuleks hästi mõista, enne kui sukeldute ja hakkate oma ühikatseid arendama.

Kaardistage ühiku testid

Kui olete oma dapp'i äriloogika ja töövoo dokumenteerinud, soovitame teil kaardistada iga üksustesti, mis on seotud teie dappide vastavate funktsioonidega. See eeldab, et peate oma dapp-punktid, lepingud-lepingud ja funktsioonid-funktsioonid jaotama ning lõpuks välja uurima kõik vastavad potentsiaalsed kasutusjuhud hõlmavad ühiku testid.

Selleks rühmitame ühiku testid kokku nii, et need kaardistatakse vastavate funktsioonidega lepingutes. Siin on näidis ühekordseks kasutamiseks mõeldud juhtumi kohta, mis on seotud funktsiooniga buyTokens (_amount) Tokeni lepingus:

// kui leping aktiveeritakse
   // kui lepingut ei peatata
      // kui pakkumisperiood on alanud
         // kui pakkumise periood pole lõppenud
            // see peaks naasma tõeseks

Vastupidi, siin on veel üks funktsioon, mis on seotud funktsiooniga buyTokens (_amount), kui pakkumisperiood on lõppenud:

// kui leping aktiveeritakse
   // kui lepingut ei peatata
      // kui pakkumisperiood on alanud
         // kui pakkumisperiood on lõppenud
             // see peaks tagasi pöörduma

Kõigi niimoodi seadmetestide kaardistamine on hea viis vestluste hõlbustamiseks sidusrühmade ja ülejäänud insenerimeeskonnaga. See aitab tagada, et kõik on teie dappide nõudmistega samal lehel. Lisaks sellele aitab see teid juhendada ja luua oma dapp turvalisel ja usaldusväärsel viisil.

Esmalt pöörduge modifikaatorite poole, seejärel töötage läbi oma nõude ja kui avaldused järjest

Kui olete ühikatsed kaardistanud, soovitame teil keskenduda kõigepealt funktsioonide modifikaatoritega seotud kasutusjuhtumite käsitlemisele. Seejärel saate funktsiooni järjestikku läbi vaadata ja ühikatestid välja töötada, et käsitleda kõiki iga nõude ja vajaduse korral avaldusega seotud kasutusjuhte.

Näiteks järgmise funktsiooni jaoks tahaksime kõigepealt käsitleda modifikaatoritega atStage (Stages.AuctionStarted) ja validBid () seotud kasutusjuhtumeid, enne kui käsitleme järgnevaid if- ja other-avaldusi:

/// @dev Esimene, kes pakub pakkumise aadressil currentAskingPrice, saab abisaaja NFT
/// @dev Kui pakkuja teeb NFT-l ülepakkumise, võidab ta enampakkumise ja tema ületusfunktsioon tagastatakse
protsessBid ()
avalik
makstav
atStage (Stages.AuctionStarted) // Alustage siit kõigepealt
validBid () // Pöörake need kasutusjuhud teiseks
tagastab (uint) // Seejärel adresseerige järgnevad väited "kui", "muud" ja "nõua"
{
  pakkumine = msg.väärtus;
  pakkuja = msg.sender;
  
  getCurrentAskingPrice ();
  if (pakkumine> currentAskingPrice)
  {
    üleküllus = bid.sub (currentAskingPrice);
    bidder.transfer (ületatud);
    pakkumine = currentAskingPrice;
    etapp = Stages.AuctionEnded;
    payBeneficiary ();
    sendToBidder ();
  }
  else if (bid == currentAskingPrice)
  {
    etapp = Stages.AuctionEnded;
    payBeneficiary ();
    sendToBidder ();
  }
  muud
  {
    tagasi ("Pakkumine on madalam kui currentAskingPrice");
  }
}

Testimiseks, millal teie lepingud peaksid taastuma, leidsime, et OpenZeppelini assertRevert abimees on äärmiselt abivalmis. Saate seda kasutada nii:

ootama assertRevert (tokenInstance.buy ({pärit: investor, väärtus: 500}));

Funktsioonide ülekoormus ja madalkõnede vajadus

Kui jätkate oma ühikatsetuste väljatöötamist, ilmneb tõenäoliselt kasutatavate arendajariistadega seotud puudusi. Selle põhjuseks on asjaolu, et arukas lepinguruumide arendamise ruum on endiselt väga uus ja seetõttu on paljud seal olevad arendaja tööriistad veel ebaküpsed.

Näiteks trühvlite raamistik - mis on suurepärane tööriist ja võib-olla tänapäeval kõige populaarsem raamistik Ethereumi ruumis - ei toeta funktsioonide ülekoormamist. See tähendab, et kui teil on vaja testida kahte sama nimega, kuid erineva ariteediga funktsiooni, peate lepingu ABI-s teise funktsiooni testimiseks kasutama madala taseme kõnesid. Kui te seda ei tee, kuvatakse tõrge: funktsiooni Solidity argumentide arv on vale. Vaatame kiiret näidet.

Kui teil on lepingus kaks funktsiooni buyTokens, üks, mis ei võta argumente ja on esimesena loetletud ABI-s, ja see, mis aktsepteerib (_umount) argumenti ja on ABI-s teisel kohal, peate kasutama madala taseme kõnet funktsiooni buyTokens (_amount) testimiseks, kasutades encodeCall, nagu allpool näha.

data = encodeCall (“buyTokens”, [“uint”], [100]); // 100 on argumendi `_maht` väärtus
lepingInstance.sendTransaction ({andmed, pärit: investor, väärtus: 500})

Trühvlite kogukond on sellest probleemist teadlik ja sellega käsitletakse tulevases väljaandes. Niisugused pentsikud stsenaariumid pole aga arukate lepingute ja neile vastavate ühiktestide väljatöötamisel ebatüüpilised. Aeg-ajalt pakutavate lahendustega peate olema kaval (kuid olema siiski äärmiselt ettevaatlik).

Kuidas testida sisemisi funktsioone

Arvestades, et Solidity funktsioonidel võib olla erinev nähtavus (st avalik, privaatne, sisemine ja väline), tasub märkida, et sisemiste funktsioonide ühiskatsete väljatöötamine on pisut erinev kui nende arendamine avalike funktsioonide jaoks. Selle põhjuseks on asjaolu, et sisemisi funktsioone ei ole aruka lepingu ABI-s pärast selle koostamist loetletud. Seetõttu on teil sisemiste funktsioonide testimiseks kaks võimalust:

  1. Sisefunktsiooni testimiseks saate luua teise lepingu, mis pärib teie testitavat lepingut
  2. Või võite testida sisemise funktsiooni loogikat muude lepingufunktsioonide kaudu, mis kutsuvad sisemist funktsiooni

Mõlemad lähenemisviisid saavad töö tehtud, ehkki mõned võivad sisemise funktsiooni loogika testimist lepingu muude funktsioonide seest paremini mõista.

Käepärased Ganache näpunäited ja nipid

Nagu ma varem mainisin, kasutame trühvlite raamistikku oma klientide jaoks täppide ehitamiseks. Trühvel kasutab Ganache nimelist tööriista, mis võimaldab teil kiiresti käivitada oma isikliku Ethereumi plokiahela, mida saate kasutada testide käivitamiseks, käskude täitmiseks ja oleku kontrollimiseks, kontrollides samal ajal, kuidas ahel töötab. See on ülimalt mugav.

Ganache puhul on tõeliselt tore, kuidas seda saab hõlpsasti kohandada, et see vastaks teie dapi ainulaadsetele vajadustele. Näiteks oleme välja töötanud pikslitega ühiskatsed, mis nõuavad kümnete ja kümnete kasutajate kasutamise juhtumite testimist. Ühe lihtsa käsu abil on Ganache hõlpsasti meil võimalik testida nii paljude kontodega kui vaja:

ganache-cli -a 40 // Kui lipp tähistab Ganache käivitamist 40 testkontoga

Lisaks saame seada nende kontode saldod alustuseks nii palju ETH-d, kui on meie testide jaoks vajalik. Vaikimisi seab trühvel tasakaaluks 100 ETH. Saame seda väärtust hõlpsalt suurendada või vähendada, sõltuvalt meie enda ainulaadsetest nõuetest:

ganache -e 10000` // Seal, kus lipp tähistab, kui palju ETH-d peaks vaikimisi iga konto alustama

Ganache on Ethereumi jaoks nutikate lepingute väljatöötamisel äärmiselt kasulik tööriist. See aitab arengut sujuvamaks muuta, leevendada riske ja parandada dappide töökindlust.

Sidudes selle kõik kokku

Ühiku testimine nutilises lepinguruumis on põhimõtteliselt sarnane ühiku testimisega veebi- ja mobiilirakenduste maailmas. Suurim erinevus on see, et arukad lepingud on tänapäeval muutumatud ega paku üldiselt lihtsaid viise, kuidas neid aja jooksul korrata [1]. Seetõttu on hea ühikutestide väljatöötamine kriitilise tähtsusega, arvestades aruka lepingu muutmatust ja tõsiasja, et sageli vastutavad nad suurte rahasummade haldamise eest. Ainus viis olla kindel, et teie nutikad lepingud on turvalised ja usaldusväärsed, on neid hoolikalt kontrollida.

Nutikate lepingute massiliseks vastuvõtmiseks on oluline, et meie kogukond teeks ruumi edendamiseks koostööd ja lihtsustaks arendajatel keerukate rakenduste kirjutamist avalike plokiahelate peal.

Loodame, et need õppetunnid, mis on saadud ühiskatsete arendamise kogemusest, on kasulikud ja toetame teie püüdlusi turvaliste ja usaldusväärsete nutikate lepingute loomisel. Kui teil on lisaküsimusi või-mõtteid, mida soovite meie meeskonnaga põhjalikumalt arutada, ärge kartke ühendust võtta ja pöörduge meie poole - [email protected]

Lähipäevadel avaldame selle kohta järelmeetmete artikli, mida õppisin keerukate nutikate lepingute testimisel.

[1] Zeppelini meeskond käivitas hiljuti ZeppelinOSi, mis pakub uuendatavate standardraamatukogude ahelakomplekti ja võimaldab puhverserverite abil teie nutikaid lepinguid uuendada.

☞ Et olla kursis oma nutika lepinguarenduse tööga, jälgige meid meediumites ja Twitteris.