Cum puteți crea dApps scalabile și contracte inteligente în Ethereum cu ajutorul canalelor de stat pas cu pas. Partea 1

Există o mulțime de soluții diferite pentru crearea de aplicații descentralizate care se extind la mii sau chiar milioane de utilizatori în timp real, precum canale de plasmă și de stat. În acest ghid, veți afla pas cu pas cum funcționează canalele de stat și cum să creați aplicații scalabile în Ethereum chiar acum.

Nu trebuie să așteptați îmbunătățiri viitoare în blockchain. Tehnologia este aici pentru a rămâne și o puteți folosi pentru a crea tot felul de dApps. În acest moment, canalele de stat sunt utilizate mai ales pentru jocurile bazate pe blockchain în Ethereum.

Gândiți-vă la jocurile de noroc cu monedele criptoase. Există modalități de criptare a informațiilor pentru a le dezvălui mai târziu, ceea ce este un punct cheie al acestui sistem.

Ce sunt canalele de stat?

Este o soluție de scalare pentru a crea aplicații descentralizate și contracte inteligente, care pot fi utilizate de milioane de utilizatori în timp real aproape. Aceștia lucrează prin inițierea unui canal între 2 sau mai mulți utilizatori în care fac schimb de mesaje criptate, semnate cu informațiile tranzacției pe care doresc să o execute.

Acestea sunt numite „stare” deoarece fiecare interacțiune trebuie să aibă o stare care poate fi actualizată. Gândiți-vă la un scor al unui joc sau al unui sold bancar.

De ce există?

Canalele de stat au fost create pentru că aplicațiile ethereum au crescut rapid în popularitate, făcând blockchain-ul să nu poată fi folosit de când a fost dezvoltat cu o utilizare moderată. Ele permit tranzacții continue, fără să plătească gaz sau așteaptă minerii să proceseze tranzacțiile.

Ceea ce înseamnă tranzacții gratuite și rapide.

De ce avem nevoie pentru a configura un canal de stat?

  1. Cel puțin 2 utilizatori care vor interacționa unul cu celălalt. Un canal trebuie deschis între 2 sau mai mulți utilizatori. Similar cu o aplicație de chat.
  2. Un contract inteligent cu logica canalului de stat care îl va deschide și închide.
  3. Dacă canalul de stat va fi utilizat într-un joc, va fi necesară o escrow pentru ambii utilizatori. Acea escrow în eter va fi stocată în contractul inteligent la deschiderea canalului.
  4. O aplicație javascript care va genera mesaje semnate care vor fi schimbate off-chain între utilizatori.
  5. Metamask sau un instrument similar pentru semnarea mesajelor. Mesajele de semnare nu costă gaz și sunt executate instantaneu. Ambii utilizatori au obligația de a semna mesajele pentru a garanta că acestea sunt cele care generează o astfel de tranzacție.
  6. E-mail sau orice altă aplicație externă pentru a schimba mesajele semnate pentru a face posibilă această aplicație.

Cum funcționează?

Canalul de stat este un pic complex de configurat, deoarece trebuie să vă asigurați că ambii jucători protejați în cazul în care ceva nu merge bine, de aceea avem nevoie de un contract inteligent. Acestea sunt etapele:

  1. Într-un canal de stat între 2 utilizatori, primul implementează contractul inteligent care va „deschide” canalul.
  2. Cel de-al doilea execută o funcție a acelui contract inteligent pentru a „alătura” acel canal de stat ”
  3. Apoi pot începe schimbul de mesaje semnate pentru aplicație. Ambii utilizatori au acces la o aplicație javascript personalizată pentru a genera mesaje cu informațiile pe care le-ar face într-un contract inteligent, dar în afara lanțului.
  4. Viteza tranzacțiilor depinde de cât de rapid poate fiecare utilizator să creeze și să semneze aceste mesaje. Ei continuă să schimbe mesaje, să joace off-chain până când decid că jocul s-a terminat.
  5. Când termină jocul, oricine dintre ei poate merge la contractul inteligent și poate executa o funcție care să o termine, care va începe faza de „negociere”.
  6. În această fază, ambii utilizatori au un interval de timp de o zi pentru a încărca ultimele 2 mesaje pe care le au în contractul inteligent. Contractul inteligent verifică cele mai recente mesaje și eliberează fondurile pentru a termina jocul pe baza informațiilor respective. Fiecare mesaj conține rezultatele interacțiunilor anterioare, astfel încât este sigur să le verifici doar pe cele mai recente.

Cum poți aplica asta într-o situație reală?

În acest ghid, vă voi arăta cum puteți crea un canal de stat între 2 utilizatori pentru un joc Ethereum. Nu uitați că canalele de stat pot fi utilizate pentru orice tip de aplicație care are un „stat” sau un contor. De aceea, jocurile sunt ideale. Deoarece puteți urmări cine câștigă fiecare joc, există o stare pentru fiecare joc care poate fi actualizată.

Vom crea un joc de zar în care jucătorul 1 alege numărul zarurilor care vor ieși, iar jucătorul 2 trebuie să ghicească acest număr pentru a câștiga. Vor putea juca cât mai multe jocuri doresc, fără a fi nevoie să execute tranzacții pe blockchain. Vom avea și o aplicație web pentru a afișa interfața.

Acesta este indicele pe care îl vom urma pentru a crea o astfel de aplicație descentralizată:

  1. Crearea aplicației web vizuale. Aceasta este interfața, cum va arăta jocul utilizatorilor externi. Acesta va fi utilizat ca mediu pentru a schimba mesaje semnate pentru canale de stat.
  2. Crearea funcționalităților necesare pentru semnarea și criptarea mesajelor.
  3. Crearea contractului inteligent.

1. Crearea aplicației web vizuale

Înainte de a începe chiar și cu codul, vreau să mă asigur că clarificăm detaliile complete ale aplicației web. Cum va arăta, care este centrul atenției.

În acest caz, dorim să afișăm lucruri similare pentru ambii jucători. Jucătorul 1 va vedea cele 6 fețe ale zarului ca imagini și va trebui să aleagă care dintre ele va ieși, apoi cel de-al doilea jucător, va trebui, de asemenea, să aleagă între aceste fețe și va putea vedea rezultatul.

Deci, cadrul va fi ceva de genul:

  1. Jucătorul 1 merge la aplicația web, face clic pe un buton care spune „Începe un joc nou”, apoi face o tranzacție cu metamask pentru a implementa și configura contractul inteligent. El primește o adresă inteligentă de contract pe care o poate trimite celuilalt jucător pentru a începe jocul.
  2. Jucătorul 2 merge la aplicația web, face clic pe un buton care spune „Alăturați-vă unui joc existent” cu adresa contractului primită de la jucătorul 1, apoi face o tranzacție cu metamask pentru a configura jocul deja existent și trimite o escrow.

Deci, să începem chiar acolo. Să creăm o casetă în mijlocul aplicației web cu 2 butoane. Creați un folder numit zar și un fișier numit index.html. Iată codul:

Așa arată în mod implicit 2 butoane


    
        
         Dice ethereum game 
    
    
        
                                       

În acel cod am creat doar structura HTML de bază cu un div care conține butoanele și un titlu. Rețineți că div-ul are o clasă numită conținut principal pe care o vom folosi într-un moment.

Să facem asta mai frumos cu ceva CSS. Creați un fișier numit index.css cu următorul cod (îl puteți copia și lipi)

Iată cum va arăta
corp {
    font-family: sans-serif;
}
.conținut principal {
    marja: auto;
    lățime maximă: 500px;
    fundal-culoare: alb alb;
    captusire: 50px;
    rază de graniță: 10px;
    afișare: grilă;
    grid-template-lines: 1fr 1fr;
    grid-template-column: 1fr 1fr;
    grid-column-gap: 10px;
}
.main-content h1 {
    coloană grilă: 1 / span 2;
}
Buton .main-content {
    graniță: niciuna;
    culoare albă;
    culoare de fundal: # 007dff;
    captusire: 20px;
    rază de graniță: 5px;
    cursor: pointer;
}
Butonul conținut principal: hover {
    opacitate: 0,8;
}
Butonul conținut principal: activ {
    opacitate: 0,6;
}

Am adăugat un titlu h1 la html pentru a-l arăta mai bine, asigurați-vă că vă actualizați html-ul adăugând linkul la css:



    
        
        
         Dice ethereum game 
    
    
        
            

Ethereum Zice

                                       

Este posibil să fi observat că folosesc noua grilă css. Acest lucru se datorează faptului că este disponibil în mare parte pentru marile browsere, astfel încât este destul de sigur să îl folosești în acest moment, deoarece majoritatea oamenilor vor vedea css-ul în mod corespunzător.

Am decis că cel mai bun mod de a afișa următoarea acțiune necesară utilizatorului este să afișați un javascript div cu informațiile necesare. Așadar, când face clic pe „Începeți un joc nou”, va vedea o casetă care îl va întreba pentru cât de mult dorește să înființeze jocul.

Faceți clic pe „Alăturați-vă unui joc existent”, i se va cere adresa de încredere și contractul jocului existent.

Iată cum vor răspunde acțiunile butonului:

Cum arată aplicația cu javascript simplu

Pentru a face acest lucru posibil, am creat un fișier index.js cu o anumită logică javascript. Iată javascriptul, asigurați-vă că îl tastați cu mâinile dvs. dacă doriți să aflați mai bine acest lucru:

Permiteți-mi să explic ce am făcut acolo:

  • Mai întâi am creat o funcție numită start (), care va fi executată imediat pentru a înfășura conținutul, astfel încât să fie frumos și conținut într-o singură funcție.
  • Apoi, am creat 2 ascultători de evenimente care se activează ori de câte ori dau clic pe butoanele start sau unire din fișierul html. Una pentru butonul # nou-joc și alta pentru butonul # alătura-joc. Folosesc document.querySelector (), care este unul dintre cele mai puternice moduri de a selecta orice din codul dvs. js.
  • În interiorul acelor ascultători, afișez sau ascund caseta div a fiecărui element corespunzător. Practic selectarea casetei cu querySelector și eliminarea sau adăugarea clasei ascunse care este configurată în css pentru afișare: niciuna; .

Apoi putem conecta fișierul js cu indexul nostru modificator.html:



    
        
        
         Dice ethereum game 
    
    
        
            

Ethereum Zice

                         
            
                

Câtă escrow veți utiliza în ETH?

                             
            
                

Care este adresa contractuală inteligentă a jocului existent?

                             
            
        
        
    

Am îndrăznit noile bucăți de cod adăugate. Urmează css-ul actualizat pentru a stila noile informații:

corp {
    font-family: sans-serif;
}
. ascuns {
    afișare: niciuna;
}
.conținut principal {
    marja: auto;
    lățime maximă: 500px;
    fundal-culoare: alb alb;
    captusire: 50px;
    rază de graniță: 10px;
    afișare: grilă;
    grid-template-lines: 1fr 80px auto;
    grid-template-column: 1fr 1fr;
    grid-column-gap: 10px;
}
.main-content h1 {
    coloană grilă: 1 / span 2;
}
Buton .main-content {
    graniță: niciuna;
    culoare albă;
    culoare de fundal: # 007dff;
    captusire: 20px;
    rază de graniță: 5px;
    cursor: pointer;
}
Butonul conținut principal: hover {
    opacitate: 0,8;
}
Butonul conținut principal: activ {
    opacitate: 0,6;
}
Butonul conținut principal: dezactivat {
    opacitate: 0,5;
    fundal-culoare: gri;
    cursor: auto;
}
Intrare de conținut principal {
    latime: 100%;
    rază de graniță: 10px;
    căptușire: 10px;
    graniță: 1px solid luminos;
}
.main-content div.new-game-setup, .main-content div.join-game-setup {
    coloană grilă: 1 / span 2;
}
# buton-continuare {
    coloană grilă: 1 / span 2;
    marginea de sus: 20px;
}

Butonul „Continuare” în acest moment nu face nimic, astfel încât să creăm această funcționalitate pentru a implementa un nou contract inteligent și a deschide canalul de stat atunci când un utilizator dorește să creeze un nou joc în secțiunea următoare.

2. Crearea și conectarea contractului inteligent inițial

Este timpul să creați o versiune de bază a contractului inteligent și să-l conectați la javascriptul dvs. utilizând web3.js. Deocamdată avem nevoie doar de constructor și de câteva informații de bază. Scrieți acest cod în jos cu propriile mâini într-un nou fișier numit Dice.sol:

soliditatea pragmei 0.4.25;
contract Dice {
    adresa public player1;
    adresa public player2;
    uint256 public player1Escrow;
    uint256 public player2Escrow;
    constructor () public plătitor {
        necesită (msg.value> 0);
        player1 = msg.sender;
        player1Escrow = msg.value;
    }
    function setupPlayer2 () public payable {
        necesită (msg.value> 0);
        player2 = msg.sender;
        player2Escrow = msg.value;
    }
}

Există 2 funcții, constructorul pentru a configura adresa și escrow-ul primului player și funcția setupPlayer2 () pentru a configura informațiile celui de-al doilea player.

Vrem să implementăm contractul și să executăm constructorul cu valoarea msg.value specificată chiar atunci când utilizatorul face clic pe butonul „Continuare”. Pentru a face acest lucru, va trebui să punem în aplicare web3.js în contractul nostru inteligent. Întrucât este principalul mod de a comunica cu blockchain-ul în browser.

Obțineți web3.js în folderul aplicației de aici: https://github.com/ethereum/web3.js/blob/develop/dist/web3.js, care este codul de distribuție oficial, actualizat.

Pentru a-l descărca pentru proiectul dvs., accesați linkul respectiv, faceți clic pe brut pentru a vedea codul complet și copiați codul pentru a-l lipi într-un nou fișier numit web3.js în folderul proiectului:

Deschideți pagina, faceți clic pe „brut”, selectați toate cu ctrl + a, copiați codul și lipiți-l într-un fișier nou din proiectul dvs. numit web3.js

Nu trebuie să faceți acest lucru cu adevărat dacă utilizați metamask, deoarece metamask vă injectează o versiune de web3.js pentru dvs., dar este util să aveți biblioteca web3 în proiectul dvs. pentru a interacționa cu blockchain dacă metamask nu este disponibil.

Folosim metamask pentru a discuta cu blockchain. Cu toate acestea, nu funcționează atunci când deschideți un fișier index.html pe browser, deoarece extensia fișier: // nu este acceptată pentru metamask.

Apoi, trebuie să rulăm un server local care să servească fișierele la un url http: // localhost: 8080, deoarece metamask nu funcționează atunci când deschideți fișierul index.html direct. Pentru a face acest lucru, deschideți terminalul și instalați acest lucru:

npm i -g http-server

Apoi, în folderul de proiect, executați serverul http pentru a porni un server local pentru index.html:

http-server

Acesta va servi fișierele pe localhost: 8080, astfel încât să le puteți accesa și să injectați web3 din metamask.

Cu asta, ne putem concentra pe implementarea contractului pe care tocmai l-am creat din aplicația noastră web, chiar atunci când utilizatorul face clic pe „Continuare”.

Pentru a implementa un nou contract avem nevoie de ABI, parametrii constructorului și bytecode. Acestea sunt cerințele pentru web3.js.

  1. Pentru a genera ABI accesați remix.ethereum.org, lipiți codul în secțiunea principală și faceți clic pe ABI:

Acesta va copia codul ABI. Accesați folderul proiectului și creați un fișier numit contractData.js pentru a lipi codul acolo cu o variabilă numită abi ca atare:

2. Acum avem nevoie de bytecode ale contractului dvs. inteligent. Bytecode este contractul inteligent compilat care va fi implementat în blockchain, avem nevoie de aceste informații pentru a putea să îl implementăm. Pentru a obține bytecode trebuie să remixi din nou și faceți clic pe acest buton:

Butonul de copiere bytecode pentru codul dvs.

Și creați o altă variabilă în contractData.js numită bytecode cu informațiile de acest fel:

Puteți copia același cod dacă contractul dvs. inteligent este exact ca cel pe care l-am creat mai sus.

Importați acel fișier javascript în html dvs. înainte de fișierul index.js pentru a avea variabilele abi și bytecode disponibile:

Înainte de a crea contractul pe javascript, trebuie să adăugăm un ascultător de evenimente la butonul de continuare a secțiunii „Începe un joc nou”:

Ce am făcut acolo este:

  • Am adăugat id-uri la intrările în care utilizatorul este întrebat cât de mult vrea să pună în escrow și adresa contractului dacă se alătură unui joc existent.
  • Apoi am adăugat importul javascript deasupra index.js, deoarece dorim să avem abi și bytecode disponibile în index.js, deoarece trebuie importat mai întâi.

Apoi adăugăm logica necesară pentru ca butonul să funcționeze. Vom verifica dacă adresa de contract introdusă în HTML este goală sau nu.

Dacă nu este gol, atunci presupunem că jucătorul începe un joc nou care, interesant, vă permite să începeți un joc folosind butonul Alăturați dacă lăsați adresa goală.

Înainte de a vă arăta întregul cod, vreau să vă explic cum să implementați un contract folosind web3.js. Pare simplu, dar am rămas blocat în anumite zone.

Așadar, atunci când utilizatorul face clic pe „Începeți un joc nou”, ne oferă suma de încredere în eter și adresa sa, putem implementa un nou contract cu această funcție:

În esență, creați instanța contractului cu abi și executați metoda .new () pentru acel contract cu bytecode.

Apoi, în callback, primiți o eroare dacă există și un obiect rezultat. Obiectul rezultat va conține adresa. A contractului desfășurat atunci când tranzacția este procesată de mineri.

Ceea ce înseamnă că acest apel de apel va fi executat de 2 ori. Una când executați crearea contractului și alta când adresa respectivului contract este disponibilă.

Puteți verifica când adresa contractului este disponibilă cu o declarație simplă dacă:

if (! result.address) {
    // Crearea contractului a început
} altfel {
    // Contractul a fost implementat și puteți utiliza adresa cu result.address
}

Așa implementați un contract cu web3.

Dar dacă doriți să accesați un contract existent pe blockchain?

Acesta este exact ceea ce trebuie să „unim” la un joc de zaruri, pentru a crea o instanță de contract. În acest scop avem nevoie doar de ABI și adresa contractului, bytecode nu este necesară. Iată cum o faci în web3:

Contract = web3.eth.contract (abi)
contractInstance = Contract.at (adresa selectată)

După aceea, puteți executa funcții ale respectivului contract:

contractInstance.setupPlayer2 ({
  valoare: web3.toWei (valoare selectată),
  gaz: 4e6
}, (eroare, rezultat) => {
    // Faceți ceva după executarea funcției
})

Aveți nevoie doar de instanță, numele funcției, parametrii dacă există și funcția de apelare inversă.

Acum că ați înțeles cum funcționează și instantaneu un contract inteligent funcționează pe javascript, vă voi arăta codul complet al aplicației:

Ignoră tot ceea ce este de mai sus, ceea ce trebuie să te concentrezi este în blocul ascultătorului „# buton-continua”:

document.querySelector ( '# butonul de continuare'). addEventListener ()

Deoarece trebuie să vă preocupe doar ce se întâmplă când jucătorul 1 sau jucătorul 2 faceți clic pe butonul „Continuare”. Iată defalcarea:

  • Când orice jucător face clic pe butonul respectiv, acest ascultător de evenimente este executat
  • În interior, primesc valorile de intrare pentru a configura escrow și adresa contractului desfășurat dacă jucătorul se alătură unui joc existent. Acestea sunt variabilele valueSelected și addressSelected.
  • Apoi creez variabila de configurare a contractului cu abi, care va fi necesară pentru ambii jucători.
  • După aceea văd dacă adresa contractului desfășurat este setată sau nu. Dacă adresa este goală, înseamnă că jucătorul a dat clic pe „Începe un joc nou”, deoarece în acest caz nu va vedea intrarea adresei.
  • Ceea ce înseamnă că implementez un joc nou sau un contract inteligent pentru acel jucător cu escrow-ul selectat.
  • Primul jucător va vedea adresa contractului inteligent implementat. El va trebui să împărtășească acea adresă cu celălalt jucător pentru a începe un joc de zar, deoarece ai nevoie de 2 jucători.
  • Dacă a furnizat o adresă, înseamnă că vrea să se alăture unui joc existent. Putem face asta prin crearea unei instanțe a contractului inteligent folosind adresa acestuia și apoi executând funcția setupPlayer2 ().
  • Folosesc funcția setInterval pentru a verifica la fiecare 1 secundă dacă configurarea player-ului 2 a fost finalizată sau nu pentru a începe jocul.

Grozav! Dacă ai făcut-o până acum înseamnă că ești angajat și că de fapt înveți ceva. Partea cea mai bună este mai aproape decât crezi. În următorul articol, veți vedea cum puteți crea canale de stat pentru jocul dvs. în javascript pentru a crea o aplicație descentralizată Ethereum scalabilă.

Nu ratați și fiți primul care a citit-o când a fost finalizat. Alăturați-vă listei mele de distribuție exclusivă a dezvoltatorilor Ethereum pentru a primi actualizări și informații direct de la mine aici: http://eepurl.com/dDQ2yX

Partea a 2-a este disponibilă chiar aici: https://medium.com/@merunasgrincalaitis/how-to-create-scalable-dapps-and-smart-contracts-in-ethereum-with-state-channels-step-by-step- 690f71a9bf2f

Dacă vă simțiți copleșiți de astfel de informații avansate sau sunteți doar nou pentru soliditate și dapps Ethereum, consultați cartea mea „Ethereum Developer: Learn Solidity from Scratch” aici https://merunas.io/