NewsDevelopersEnterpriseBlockchain ExplainedEvents and ConferencesPressButlletins informatius
Subscriu-te al nostre butlletí.
Correu electrònic
Respectem la vostra privadesa
IniciBlogDesenvolupament de la cadena de blocs
Una guia d’esdeveniments i registres en contractes intel·ligents d’Ethereum
Una introducció tècnica per utilitzar casos per a esdeveniments i registres a la cadena de blocs d’Ethereum amb codi de mostra de Joseph Chow 6 de juny de 2016 Publicat el 6 de juny de 2016
Els esdeveniments i els registres són importants a Ethereum perquè faciliten la comunicació entre els contractes intel·ligents i les seves interfícies d’usuari. En el desenvolupament web tradicional, es proporciona una resposta del servidor en una devolució de trucada al frontend. A Ethereum, quan s’extreu una transacció, els contractes intel·ligents poden emetre esdeveniments i escriure registres a la cadena de blocs que el frontend pot processar. Hi ha diferents maneres d’abordar esdeveniments i registres. Aquesta introducció tècnica explicarà algunes fonts de confusió quant a esdeveniments i alguns exemples de codi per treballar amb ells.
Els esdeveniments poden ser confusos perquè es poden utilitzar de diferents maneres. Un esdeveniment per a un pot no semblar un esdeveniment per a un altre. Hi ha 3 casos d’ús principals per a esdeveniments i registres:
- Valors de devolució de contracte intel·ligent per a la interfície d’usuari
- Activadors asíncrons amb dades
- Una forma d’emmagatzematge més econòmica
La terminologia entre esdeveniments i registres és una altra font de confusió i això s’explicarà en el tercer cas d’ús.
1) Valors de devolució de contracte intel·ligent per a la interfície d’usuari
L’ús més senzill d’un esdeveniment és transmetre els valors de retorn dels contractes al frontend d’una aplicació. A tall d’il·lustració, aquí teniu el problema:
contract ExampleContract {// algunes variables d’estat … function foo (int256 _value) retorna (int256) {// manipula l’estat … retorna _value; }} Idioma del codi: JavaScript (javascript)
Suposant que exampleContract és una instància de ExampleContract, un frontend que utilitza web3.js, pot obtenir un valor de retorn simulant l’execució del contracte:
var ReturnValue = exampleContract.foo.call (2); console.log (returnValue) // 2 Idioma del codi: JavaScript (javascript)
No obstant això, quan web3.js envia la trucada de contracte com a transacció, no pot obtenir el valor de retorn [1]:
var ReturnValue = exampleContract.foo.sendTransaction (2, {from: web3.eth.coinbase}); console.log (returnValue) // transaction hash Idioma del codi: JavaScript (javascript)
El valor de retorn d’un mètode sendTransaction sempre és el hash de la transacció creada. Les transaccions no retornen el valor del contracte al frontend perquè les transaccions no s’extreuen immediatament i no s’inclouen a la cadena de blocs.
La solució recomanada és utilitzar un esdeveniment, i aquest és un dels propòsits previstos per als esdeveniments.
contract ExampleContract {event ReturnValue (adreça indexada _de, int256 _value); function foo (int256 _value) retorna (int256) {ReturnValue (msg.sender, _value); retorn _valor; }} Un frontend pot obtenir el valor de retorn: var exampleEvent = exampleContract.ReturnValue ({_ from: web3.eth.coinbase}); exampleEvent.watch (function (err, result) {if (err) {console.log (err) return;} console.log (result.args._value) // comproveu que result.args._from és web3.eth.coinbase llavors // mostra result.args._value a la IU i truca // exampleEvent.stopWatching ()}) exampleContract.foo.sendTransaction (2, {from: web3.eth.coinbase}) Llenguatge del codi: JavaScript (javascript)
Quan s’extreu la transacció que invoca foo, s’activarà la devolució de trucada dins del rellotge. Això permet eficaçment al frontend obtenir valors de retorn de foo.
2) Activadors asíncrons amb dades
Els valors de retorn són un cas d’ús mínim per als esdeveniments i, generalment, els esdeveniments es poden considerar com a activadors asíncrons amb dades. Quan un contracte vol activar el frontend, el contracte emet un esdeveniment. Com que el frontend mira els esdeveniments, pot dur a terme accions, mostrar un missatge, etc. Un exemple d’això es proporciona a la secció següent (una interfície d’usuari es pot actualitzar quan un usuari fa un ingrés).
3) Una forma d’emmagatzematge més barata
El tercer cas d’ús és molt diferent del que s’ha tractat i fa servir els esdeveniments com a forma d’emmagatzematge significativament més econòmica. A la màquina virtual Ethereum (EVM) i Paper groc Ethereum, els esdeveniments s’anomenen registres (hi ha codis d’opció LOG). Quan es parla d’emmagatzematge, seria tècnicament més precís dir que les dades es poden emmagatzemar en registres, en lloc de les dades emmagatzemades en esdeveniments. No obstant això, quan superem el nivell del protocol, és més precís dir que els contractes emeten o desencadenen esdeveniments als quals el frontend pot reaccionar. Sempre que s’emet un esdeveniment, els registres corresponents s’escriuen a la cadena de blocs. La terminologia entre esdeveniments i registres és una altra font de confusió, perquè el context dicta quin terme és més precís.
Els registres van ser dissenyats per ser una forma d’emmagatzematge que costa significativament menys gas que l’emmagatzematge contractual. Els registres bàsicament [2] costen 8 gasos per byte, mentre que l’emmagatzematge per contracte costa 20.000 gasos per 32 bytes. Tot i que els registres ofereixen un estalvi enorme de gas, els registres no són accessibles des de cap contracte [3].
No obstant això, hi ha casos d’ús per utilitzar registres com a emmagatzematge barat, en lloc de desencadenants per a la interfície. Un exemple adequat per als registres és l’emmagatzematge de dades històriques que el frontend pot representar.
Un intercanvi de criptomonedes pot voler mostrar a l’usuari tots els dipòsits que ha realitzat a l’intercanvi. En lloc d’emmagatzemar aquestes dades de dipòsit en un contracte, és molt més barat emmagatzemar-les com a registres. Això és possible perquè una borsa necessita l’estat del saldo d’un usuari, que emmagatzema al magatzem del contracte, però no necessita conèixer els detalls dels dipòsits històrics..
contract CryptoExchange {event Deposit (uint256 indexed _market, addressed indexed _sender, uint256 _amount, uint256 _time); la funció de dipòsit (uint256 _amount, uint256 _market) retorna (int256) {// realitza el dipòsit, actualitza el saldo de l’usuari, etc. Diposa (_market, msg.sender, _amount, ara); } Idioma del codi: JavaScript (javascript)
Suposem que volem actualitzar una interfície d’usuari a mesura que l’usuari realitza dipòsits. Aquí teniu un exemple d’utilitzar un esdeveniment (Dipòsit) com a activador asíncron amb dades (_market, msg.sender, _amount, now). Suposem que cryptoExContract és una instància de CryptoExchange:
var depositEvent = cryptoExContract.Deposit ({_ remitent: usuariAdreça}); depositEvent.watch (function (err, result) {if (err) {console.log (err) return;} // afegiu detalls de result.args a la IU}) Idioma del codi: JavaScript (javascript)
Millorar l’eficiència d’obtenir tots els esdeveniments per a un usuari és la raó per la qual s’indexa el paràmetre _sender de l’esdeveniment: Dipòsit d’esdeveniments (uint256 indexat _market, adreça indexada _sender, uint256 _amount, uint256 _time).
Per defecte, l’escolta d’esdeveniments només comença en el moment en què s’instancia l’esdeveniment. Quan es carrega la IU per primera vegada, no hi ha cap dipòsit per afegir. Per tant, volem recuperar els esdeveniments des del bloc 0 i això es fa afegint un paràmetre fromBlock a l’esdeveniment.
var depositEventAll = cryptoExContract.Deposit ({_ sender: userAddress}, {fromBlock: 0, toBlock: ‘latest’}); depositEventAll.watch (function (err, result) {if (err) {console.log (err) return;} // afegiu detalls de result.args a la IU}) Idioma del codi: JavaScript (javascript)
Quan es reprodueix la IU, s’ha de cridar depositEventAll.stopWatching ().
A part: paràmetres indexats
Es poden indexar fins a 3 paràmetres. Per exemple, un estàndard de testimoni proposat té: transferència d’esdeveniments (adreça indexada _de, adreça indexada _a, uint256 _valor). Això significa que un frontend només pot vigilar les transferències de tokens que siguin:
- enviat per una adreça tokenContract.Transfer ({_ from: senderAddress})
- o rebut per una adreça tokenContract.Transfer ({_ a: receiverAddress})
- o enviat per una adreça a una adreça específica tokenContract.Transfer ({_ from: senderAddress, _to: receiverAddress})
Conclusió
S’han presentat tres casos d’ús per a esdeveniments. En primer lloc, utilitzar un esdeveniment per obtenir simplement un valor de retorn d’una funció contractual invocada amb sendTransaction (). En segon lloc, utilitzar un esdeveniment com a activador asíncron amb dades, que pot notificar a un observador com una interfície d’usuari. En tercer lloc, utilitzar un esdeveniment per escriure registres a la cadena de blocs com a forma d’emmagatzematge més econòmica. Aquesta introducció ha mostrat alguns dels API per treballar amb esdeveniments. N’hi ha altres enfocaments per treballar amb esdeveniments, registres i rebuts i aquests temes es poden tractar en futurs articles.
Gràcies a Aaron Davis, Vincent Gariepy i Joseph Lubin pels comentaris sobre aquest article.
Referències
[1] web3.js podria vigilar que la transacció s’inclogués a la cadena de blocs i, a continuació, tornar a reproduir la transacció en una instància de l’EVM per obtenir el valor retornat, però es tracta d’una quantitat lògica significativa que cal afegir a web3.js
[2] Hi ha uns costos de gas de 375 per a una operació LOG i 375 gasos per tema, però quan s’emmagatzemen molts bytes, aquests costos representen una fracció insignificant del cost total de l’emmagatzematge.
[3] Les proves de Merkle per als registres són possibles, de manera que si una entitat externa subministra un contracte amb aquesta prova, un contracte pot verificar que el registre existeix realment dins de la cadena de blocs..
Voleu guies per a desenvolupadors directament a la safata d’entrada?
Subscriviu-vos al butlletí de notícies per a desenvolupadors de ConsenSys
Subscriu-te al nostre butlletí per obtenir les últimes novetats, solucions empresarials, recursos per a desenvolupadors i molt més sobre Ethereum. Adreça de correu electrònic Contingut exclusiuSeminari web
Com es pot crear un producte Blockchain amb èxit
Seminari web
Com configurar i executar un node Ethereum
Seminari web
Com es crea la seva pròpia API Ethereum
Seminari web
Com es crea un testimoni social
Seminari web
Ús d’eines de seguretat en el desenvolupament de contractes intel·ligents
Seminari web