Una guia senzilla per escriure proves d’unitats per a contractes intel·ligents

http://upstate.agency/smart-contracts

Les bones proves d'unitats són crucials per al desenvolupament de contractes intel·ligents. Atès que els contractes intel·ligents són immutables i sovint s’encarreguen de gestionar grans sumes de diners, es podria argumentar que desenvolupar bones proves d’unitats per a contractes intel·ligents és més important que les aplicacions tradicionals web i mòbils.

Durant els darrers dos mesos, hem tingut la sort de treballar estretament amb una empresa de serveis financers que està desenvolupant una innovadora plataforma de simbolització reguladora de valors. La seva plataforma aviat serà llançada per introduir la possibilitat de transferir milers de milions de dòlars en valors a la blockchain.

Per recolzar el seu llançament, vam treballar estretament amb el seu equip d’enginyeria, vam implementar una cobertura de proves extensiva i vam executar-los contra el nostre procés de detecció d’errors. Amb aquesta experiència, hem evitat algunes consideracions importants i alguns consells i trucs que podeu utilitzar per desenvolupar proves d’unitats per als vostres contractes intel·ligents.

Obtenir una comprensió sana de la lògica empresarial

Primer, assegureu-vos d’entendre la lògica empresarial de l’aplicació distribuïda (dapp). És útil documentar quins problemes resol la vostra aplicació i com es resolen. També voleu identificar les diverses limitacions que té la vostra aplicació. Per exemple, la majoria de dapps implementen control d'accés basat en papers o basat en contractes. És important documentar aquestes restriccions i el seu impacte en l'ús.

També voleu transcriure el flux de treball de l’aplicació. Cal que alguns contractes s’hagin d’activar abans que d’altres? S’hauria d’aturar o no aturar un contracte específic per complir una tasca específica? Aquests són els tipus de requeriments relacionats amb la lògica empresarial i el flux de treball que s’han d’entendre bé abans de començar a desenvolupar les proves d’unitats.

Planifica les proves d'unitats

Després de documentar la lògica empresarial i el flux de treball del vostre Dapp, us recomanem que assigneu cada test de components associat a la funcionalitat corresponent del vostre Dapp. Això requereix descompondre l'aplicació per contracte i funcions i, a continuació, especificar totes les proves de components adequades per a cada cas d'ús potencial.

Agrupem les nostres proves d’unitats perquè s’assignin a les funcions corresponents als contractes. A continuació, es mostra una especificació d'exemple per a un cas d'ús únic associat a una funció buyTokens (_amount) en un contracte token:

// quan s’activa el contracte
// si el contracte no s’atura en pausa
// quan ha començat el període d’oferta
// si el termini d’oferta encara no ha caducat
// Hauria de tornar veritat

Per contra, aquí hi ha una altra especificació associada a la funció buyTokens (_amount) quan ha caducat el període d'oferta:

// quan s’activa el contracte
// si el contracte no s’atura en pausa
// quan ha començat el període d’oferta
// quan el període d’oferta ha caducat
// s’hauria de restablir

Resumint d'aquesta manera totes les proves dels vostres components, podeu mantenir converses amb els vostres grups d'interès i la resta del vostre equip d'enginyeria. Així que assegureu-vos que tothom estigui a la mateixa pàgina quan es tracti de les necessitats del vostre dapp. No només això, també us ajuda a dissenyar i crear el vostre dapp d’una manera segura i fiable.

Primer heu de dirigir-vos als modificadors i, a continuació, treballar les instruccions obligatòries i si una a l’altra

Un cop definides les proves d’unitat, primer hauríeu de concentrar-vos en els casos d’ús enllaçats amb els modificadors de funció. Aleshores podeu executar la funció de cada un i desenvolupar proves d’unitat per gestionar tots els casos d’ús que estan associats als respectius requisits i instruccions if.

Per exemple, per a una funció com la següent, primer voldríem cobrir els casos d’ús associats als modificadors atStage (Stages.AuctionStarted) i validBid () abans de manejar les instruccions if i else:

/// @dev La primera persona que hagi ofertat al preu actual rebrà el NFT del beneficiari /// @dev Si un licitador supera la NFT, guanya la subhasta i es reemborsarà la seva oferta.
processBid () Pagable al públic atStage (Stages.AuctionStarted) // Comença aquí primer validBid () // Diregeix aquests casos d’ús com a devolucions segones (uint) // A continuació, dirigeix-te a la següent secció "if", "else" - i "require" -Instruccions {bid = msg.value; ofertant = msg.sender; getCurrentAskingPrice (); if (oferta> actualAskingPrice) {overage = bid.sub (actualAskingPrice); bidder.transfer (beguda); oferta = preu actualAskingPrice; stage = Stages.AuctionEnded; payBeneficiator (); sendToBidder (); } else if (oferta == actualAskingPrice) {stage = Stages.AuctionEnded; payBeneficiator (); sendToBidder (); } else {reset ("L'oferta és inferior al currentAskingPrice"); }}

Hem detectat que l’assistent assertRevert d’assistència d’OpenZeppelin és de gran ajuda per provar quan s’han de restaurar els contractes. Podeu utilitzar-ho així:

wait assertRevert (tokenInstance.buy ({de: inversor, valor: 500}));

Sobrecàrrega de funcions i necessitat de trucades de baix nivell

Mentre continueu desenvolupant les proves de les unitats, probablement trobareu mancances relacionades amb les eines de desenvolupador que utilitzeu. Això es deu a que l’àrea de desenvolupament de contractes intel·ligents és encara molt nova i, per tant, moltes de les eines de desenvolupament encara no estan madures.

Per exemple, el marc de la tòfona, una excel·lent eina i potser el marc més popular a l’àrea d’Ethereum actual, no admet la sobrecàrrega de funcions. Això vol dir que si voleu provar dues funcions amb el mateix nom però propietats diferents, heu de provar la segona funció a l’ABI del contracte mitjançant trucades de baix nivell. Si no, rebrà un missatge d’error: nombre d’arguments no vàlids per a la funció de solidesa. Mirem un breu exemple.

Si teniu dues funcions de buyTokens en un contracte, una que no té arguments i que arriba primer a l'ABI, i una que accepta un argument (_amount) i arriba a la segona ABI, heu d'utilitzar una trucada senzilla per prova la funció buyTokens (_amount) amb cododeCall (vegeu més avall).

data = cododeCall ("buyTokens", ["uint"], [100]); // 100 és el valor de l'argument _amount
contractInstance.sendTransaction ({dades de: inversor, valor: 500})

La comunitat de la tòfona coneix aquest problema i s’abordarà en una publicació propera. Tanmateix, aquests escenaris estranys no són infreqüents si es desenvolupen contractes intel·ligents i les proves d’unitats adequades. Heu d’anar amb compte (però tingueu molta cura) amb les solucions que truqueu de tant en tant.

Com provar les funcions internes

Atès que les funcions en solidesa poden tenir visibilitats diferents (és a dir, públiques, privades, internes i externes), convé tenir en compte que el desenvolupament de proves d’unitats per a funcions internes és una mica diferent del de les funcions públiques. Això es deu al fet que les funcions internes no figuren a l'ABI d'un contracte intel·ligent després que s'hagin compilat. Hi ha dues maneres de provar les funcions internes:

  1. Podeu crear un altre contracte que hereti el contracte a provar per provar una funció interna
  2. O podeu provar la lògica d’una funció interna dins de les altres funcions del contracte que anomenen funció interna

Ambdós enfocaments aconsegueixen la feina, tot i que alguns afirmen que provar la lògica d’una funció interna dins de les altres funcions del contracte és més intuïtiu.

Consells i trucs de ganache pràctics

Com s'ha esmentat anteriorment, utilitzem principalment el marc de la tòfona per crear dapps per als nostres clients. Truffle utilitza una eina anomenada Ganache, que us permet iniciar ràpidament la vostra blockchain d’Ethereum, executar proves, executar ordres i comprovar l’estat mentre controla el funcionament de la cadena. És súper pràctic.

El més bo del ganache és que es pot adaptar fàcilment a les necessitats individuals del vostre dapp. Per exemple, hem desenvolupat proves d’unitats per a dapps on hem de provar casos d’ús per a desenes i desenes d’usuaris. Amb una ordre senzilla, Ganache ens facilita la prova amb tants comptes com necessitem:

ganache-cli -a 40 // Per la qual cosa el indicador "a" indica que Ganache s'inicia amb 40 comptes de prova

A més, podem ajustar els saldos d’aquests comptes de manera que comencin amb tanta ETH com sigui necessari per a les nostres proves. De manera predeterminada, Truffle estableix el saldo a 100 ETH. Podem augmentar o disminuir aquest valor fàcilment segons els nostres propis requisits:

ganache -e 10000` // pel qual la bandera `e` indica amb quina ETH cada compte hauria de començar per defecte

Ganache és una eina extremadament útil per desenvolupar contractes intel·ligents per a Ethereum. Ajuda a racionalitzar el desenvolupament, a reduir el risc i a millorar la fiabilitat dels dapps.

Lligar-ho tot

Les proves unitàries en el camp dels contractes intel·ligents són essencialment similars a les proves d’unitats del món de les aplicacions web i mòbils. La diferència principal és que els contractes intel·ligents són immutables en aquests dies i en general no ofereixen maneres fàcils de superar-los amb el pas del temps [1]. Per tant, el desenvolupament de bones proves d’unitats és fonamental, donada la immutabilitat dels contractes intel·ligents i el fet que sovint són els responsables de gestionar grans sumes de diners. Per assegurar-vos que els vostres contractes intel·ligents són segurs i fiables, heu de provar-los acuradament.

Per a l’adopció massiva de contractes intel·ligents, és fonamental que la nostra comunitat col·labori per ampliar l’espai d’emmagatzematge i faciliti als desenvolupadors escriure aplicacions complexes a través de blockchains públiques.

Esperem que les lliçons apreses de la nostra experiència en el desenvolupament de proves per a unitats us siguin d’ajuda i recolzin els vostres esforços per crear contractes intel·ligents segurs i fiables. Si teniu més preguntes o suggeriments que voleu discutir amb el nostre equip, poseu-vos en contacte amb [email protected]

En els propers dies publicarem un article de seguiment sobre el que he après en provar contractes intel·ligents complexos.

[1] L'equip de Zeppelin va llançar recentment ZeppelinOS. ZeppelinOS ofereix diverses biblioteques estàndard actualitzables que podeu utilitzar per actualitzar els vostres contractes intel·ligents amb patrons de proxy.

☞ Segueix-nos a Medium i Twitter per estar al dia del que tenim a veure amb el desenvolupament de contractes intel·ligents.