Sådan oprettes skalerbare dApps og smarte kontrakter i Ethereum med statskanaler trin for trin. Del 1

Der er masser af forskellige løsninger til at skabe decentrale applikationer, der skalerer til tusinder eller endda millioner af realtidsbrugere som plasma- og statskanaler. I denne guide lærer du trin for trin, hvordan statskanaler fungerer, og hvordan du opretter skalerbare applikationer i Ethereum lige nu.

Du behøver ikke vente på fremtidige forbedringer i blockchain. Teknologien er her for at blive, og du kan bruge den til at oprette alle slags dApps. Lige nu bruges statskanaler mest til blockchain-baserede spil i Ethereum.

Tænk spil med kryptovalutaer. Der er måder at kryptere informationerne på for at afsløre dem senere, hvilket er et nøglepunkt i dette system.

Hvad er statskanaler?

Det er en skaleringsløsning til at oprette decentrale applikationer og smarte kontrakter, der kan bruges af millioner af brugere i næsten realtid. De arbejder ved at starte en kanal mellem to eller flere brugere, hvor de udveksler krypterede, underskrevne beskeder med oplysningerne om den transaktion, de vil udføre.

De kaldes "tilstand", fordi hver interaktion skal have en tilstand, der kan opdateres. Tænk på en score på et spil eller en bankbalance.

Hvorfor findes de?

Statlige kanaler blev oprettet, fordi ethereum-applikationer hurtigt voksede i popularitet, hvilket gjorde blockchain ubrugelige, da det blev udviklet med et moderat brug. De tillader kontinuerlige transaktioner uden at betale for gas eller vente på minearbejdere til at behandle transaktionerne.

Hvilket betyder gratis og hurtige transaktioner.

Hvad har vi brug for for at oprette en statskanal?

  1. Mindst 2 brugere, der vil interagere med hinanden. Der skal åbnes en kanal mellem to eller flere brugere. Ligner en chat-applikation.
  2. En smart kontrakt med statskanalens logik, der åbner og lukker den.
  3. Hvis tilstandskanalen vil blive brugt i et spil, kræves der en escrow for begge brugere. Denne escrow i ether gemmes i den smarte kontrakt, når du åbner kanalen.
  4. En javascript-applikation, der genererer de underskrevne meddelelser, der udveksles off-chain mellem brugerne.
  5. Metamask eller et lignende værktøj til signering af meddelelser. Signering af meddelelser koster ikke gas, og de udføres med det samme. Det kræves af begge brugere at underskrive meddelelserne for at garantere, at det er dem, der genererer en sådan transaktion.
  6. E-mail eller en hvilken som helst ekstern applikation for at udveksle de underskrevne meddelelser for at gøre denne applikation mulig.

Hvordan fungerer de?

Statskanaler er lidt komplekse at konfigurere, fordi du skal sørge for, at begge spillere er beskyttet i tilfælde af, at noget går galt, det er derfor, vi har brug for en smart kontrakt. Dette er trinnene:

  1. I en tilstandskanal mellem 2 brugere ophæver den første den smarte kontrakt, der vil "åbne" kanalen.
  2. Den anden udfører en funktion af den smarte kontrakt for at ”slutte sig til” den statskanal ”
  3. Derefter kan de begynde at udveksle underskrevne meddelelser til applikationen. Begge brugere har adgang til et brugerdefineret javascript-program til at generere beskeder med de oplysninger, de ville gøre i en smart kontrakt, men uden for kæden.
  4. Hastigheden på transaktionerne afhænger af, hvor hurtigt hver bruger kan oprette og underskrive disse meddelelser. De udveksler fortsatte beskeder, spiller off-chain, indtil de beslutter, at spillet er forbi.
  5. Når de er færdige med spillet, kan enhver af dem gå til den smarte kontrakt og udføre en funktion for at afslutte den, der starter fasen med "forhandling".
  6. I denne fase har begge brugere en timeout på 1 dag for at uploade de seneste 2 meddelelser, de har til den smarte kontrakt. Den smarte kontrakt kontrollerer de nyeste meddelelser og frigiver midlerne til at afslutte spillet på baggrund af disse oplysninger. Hver meddelelse indeholder resultaterne af de foregående interaktioner, så det er sikkert at bare kontrollere de nyeste.

Hvordan kan du anvende dette i en situation i den virkelige verden?

I denne guide vil jeg vise dig, hvordan du opretter en statskanal mellem 2 brugere til et Ethereum-spil. Husk, at statskanaler kan bruges til enhver form for applikation, der har en "tilstand" eller en tæller. Derfor er spil ideelle. Fordi du kan spore, hvem der vinder hvert spil, er der en tilstand for hvert spil, der kan opdateres.

Vi opretter et terningespil, hvor spiller 1 vælger antallet af terninger, der kommer, og spiller 2 skal gætte det nummer for at vinde. De vil være i stand til at spille så mange spil, som de vil, uden at skulle udføre transaktioner på blockchain. Vi vil også have en webapp, der viser grænsefladen.

Dette er det indeks, vi følger for at oprette en sådan decentral applikation:

  1. Oprettelse af den visuelle webapp. Dette er grænsefladen, hvordan spillet vil se ud for eksterne brugere. Det vil blive brugt som mediet til at udveksle underskrevne meddelelser til statskanaler.
  2. Oprettelse af de funktioner, der kræves for at underskrive og kryptere meddelelser.
  3. Oprettelse af den smarte kontrakt.

1. Oprettelse af den visuelle webapp

Før jeg selv begynder med koden, vil jeg sikre mig, at vi tydeliggør de komplette detaljer i webappen. Hvordan det ser ud, hvad er fokus for opmærksomhed.

I dette tilfælde ønsker vi at vise lignende ting for begge spillere. Spiller 1 vil se de 6 ansigter af terninger som billeder, og han bliver nødt til at vælge, hvilken der vil komme ud, så skal den anden spiller også vælge mellem disse ansigter, og han vil være i stand til at se resultatet.

Så rammen vil være sådan som denne:

  1. Spiller 1 går til webappen, klikker på en knap, der siger “Start nyt spil”, derefter foretager han en metamask-transaktion for at implementere og konfigurere den smarte kontrakt. Han modtager en smart kontraktadresse, som han kan sende til den anden spiller for at starte spillet.
  2. Spiller 2 går til webappen, klikker på en knap, der siger "Deltag i eksisterende spil" med den kontraktadresse, der er modtaget fra spiller 1, derefter foretager han en metamask-transaktion for at opsætte det allerede eksisterende spil og sender en escrow.

Så lad os starte lige der. Lad os oprette en boks midt i webappen med 2 knapper. Opret en mappe kaldet terninger og en fil inde i navnet index.html. Her er koden:

Sådan ser 2 knapper ud som standard


    
        
         Terningens etherum-spil 
    
    
        
                                       

I denne kode oprettede jeg lige den grundlæggende HTML-struktur med en div indeholdende knapperne og en titel. Bemærk, at div har en klasse kaldet hovedindhold, som vi vil bruge i et øjeblik.

Lad os gøre det smukkere med nogle css. Opret en fil kaldet index.css med følgende kode (du kan kopiere og indsætte denne):

Sådan ser det ud
krop {
    font-family: sans-serif;
}
.main-indhold {
    margin: auto;
    max-bredde: 500 px;
    baggrundsfarve: hvidmøg;
    polstring: 50px;
    grænseradius: 10px;
    display: gitter;
    gitter-template-rækker: 1fr 1fr;
    gitter-template-kolonner: 1fr 1fr;
    gitter-søjle-spalte: 10px;
}
.main-indhold h1 {
    gitter-kolonne: 1 / span 2;
}
.knappen til indhold {
    grænse: ingen;
    farve: hvid;
    baggrund-farve: # 007dff;
    polstring: 20px;
    grænseradius: 5px;
    markør: markør;
}
.knappen til indhold: hover {
    opacitet: 0,8;
}
.knap-indhold-knap: aktiv {
    opacitet: 0,6;
}

Jeg føjede en h1-titel til html for at få den til at se bedre ud, så sørg for at opdatere din html ved at tilføje linket til css:



    
        
        
         Terningens etherum-spil 
    
    
        
            

Ethereum terninger

                                       

Du har måske bemærket, at jeg bruger det nye css-net. Det skyldes, at det mest er tilgængeligt for de store browsere, så det er ganske sikkert at bruge det på dette tidspunkt, da de fleste vil se css korrekt.

Jeg besluttede, at den bedste måde at vise den næste handling, der kræves af brugeren, er at vise en div i javascript med de krævede oplysninger. Så når han klikker på "Start nyt spil", ser han en boks, der beder ham om, hvor meget escrow han vil konfigurere til spillet.

Det klikker han på "Deltag i eksisterende spil", han bliver spurgt om det eksisterende spils escrow og kontraktadresse.

Sådan reagerer knaphandlingerne:

Hvordan appen ser ud med javascript

For at gøre det muligt oprettede jeg en index.js-fil med en vis javascript-logik. Her er javascript, husk at skrive det med dine hænder, hvis du vil lære bedre dette:

Lad mig forklare, hvad jeg gjorde der:

  • Først oprettede jeg en funktion kaldet start (), som vil blive udført med det samme for at indpakke indholdet, så det er pænt og indeholdt i en stor funktion.
  • Derefter oprettede jeg 2 begivenhedslyttere, der aktiveres, hver gang jeg klikker på start- eller sammenknytningsknapperne i html-filen. Én til # nyt-spil-knappen og en anden til # -delt-spil-knap. Jeg bruger document.querySelector (), som er en af ​​de mest kraftfulde måder at vælge noget i din js-kode.
  • Inde i disse lyttere viser eller skjuler jeg div-boksen for hvert tilsvarende element. Grundlæggende at vælge den boksede med querySelector og fjerne eller tilføje den skjulte klasse, der er opsat i css til at vise: ingen; .

Derefter kan vi forbinde js-filen med vores modifie index.html:



    
        
        
         Terningens etherum-spil 
    
    
        
            

Ethereum terninger

                         
            
                

Hvor meget escrow vil du bruge i ETH?

                             
            
                

Hvad er det eksisterende konturs adresse på det eksisterende spil?

                             
            
        
        
    

Jeg fedede de nye stykker kode tilføjet. Følgende er den opdaterede css for at style den nye information:

krop {
    font-family: sans-serif;
}
.skjult {
    display: ingen;
}
.main-indhold {
    margin: auto;
    max-bredde: 500 px;
    baggrundsfarve: hvidmøg;
    polstring: 50px;
    grænseradius: 10px;
    display: gitter;
    gitter-template-rækker: 1fr 80px auto;
    gitter-template-kolonner: 1fr 1fr;
    gitter-søjle-spalte: 10px;
}
.main-indhold h1 {
    gitter-kolonne: 1 / span 2;
}
.knappen til indhold {
    grænse: ingen;
    farve: hvid;
    baggrund-farve: # 007dff;
    polstring: 20px;
    grænseradius: 5px;
    markør: markør;
}
.knappen til indhold: hover {
    opacitet: 0,8;
}
.knap-indhold-knap: aktiv {
    opacitet: 0,6;
}
.knap til indhold: deaktiveret {
    opacitet: 0,5;
    baggrundsfarve: grå;
    markør: auto;
}
.inputindhold {
    bredde: 100%;
    grænseradius: 10px;
    polstring: 10px;
    kant: 1px solid lysegrå;
}
.main-content div.new-game-setup, .main-content div.join-game-setup {
    gitter-kolonne: 1 / span 2;
}
# knap - fortsæt {
    gitter-kolonne: 1 / span 2;
    margin-top: 20px;
}

Knappen "Fortsæt" lige nu gør intet, så lad os skabe denne funktionalitet til at implementere en ny smart kontrakt og åbne tilstandskanalen, når en bruger ønsker at oprette et nyt spil i det næste afsnit.

2. Oprettelse og forbindelse af den oprindelige Smart Contract

Det er tid til at oprette en grundlæggende version af den smarte kontrakt og forbinde den med dit javascript ved hjælp af web3.js. For tiden har vi kun brug for konstruktøren og nogle grundlæggende oplysninger. Skriv denne kode ned med dine egne hænder i en ny fil kaldet Dice.sol:

pragma-soliditet 0,4,25;
kontrakt terning {
    adresse offentlig spiller1;
    adresse offentlig spiller2;
    uint256 offentlig spiller1Escrow;
    uint256 offentlig spiller2Escrow;
    konstruktør () offentlig betales {
        kræve (msg.value> 0);
        player1 = msg.sender;
        player1Escrow = msg.value;
    }
    funktion setupPlayer2 () offentlig betales {
        kræve (msg.value> 0);
        player2 = msg.sender;
        player2Escrow = msg.value;
    }
}

Der er 2 funktioner, konstruktøren til opsætning af adresse og escrow for den første afspiller og setupPlayer2 () -funktionen til opsætning af informationen om den anden afspiller.

Vi ønsker at implementere kontrakten og udføre konstruktøren med den angivne msg.value ret, når brugeren klikker på knappen "Fortsæt". For at gøre det, bliver vi nødt til at implementere web3.js i vores smarte kontrakt. Da det er den vigtigste måde at kommunikere med blockchain på browseren.

Hent web3.js i din appmappe herfra: https://github.com/ethereum/web3.js/blob/develop/dist/web3.js, som er den officielle, opdater distributionskode.

For at downloade det til dit projekt skal du gå til det link, klikke på rå for at se den fulde kode og kopiere koden for at indsætte den i en ny fil kaldet web3.js i din projektmappe:

Åbn siden, klik på

Du behøver ikke rigtig gøre det, hvis du bruger metamask, da metamask indsprøjter en version af web3.js til dig, men det er nyttigt at have web3-biblioteket i dit projekt til at interagere med blockchain, hvis metamask ikke er tilgængelig.

Vi bruger metamask for at tale med blockchain. Det fungerer dog ikke, når du åbner en index.html-fil i din browser, fordi filtypenavnet: filtypenavnet ikke understøttes til metamask.

Derefter skal vi køre en lokal server, der serverer filerne til en http: // localhost: 8080 url, da metamask ikke fungerer, når du åbner filen index.html direkte. For at gøre det skal du åbne terminalen og installere denne:

npm i -g http-server

Derefter skal du køre http-server i din projektmappe for at starte en lokal server til dit indeks.html:

http-server

Det vil tjene filerne på localhost: 8080, så du kan få adgang til dem og injicere web3 fra metamask.

Med det ude af vejen, lader vi fokusere på at implementere den kontrakt, vi netop har oprettet fra vores webapp, lige når brugeren klikker på 'Fortsæt'.

For at implementere en ny kontrakt har vi brug for ABI, konstruktørparametrene og bytekoden. Det er kravene til web3.js.

  1. For at generere ABI skal du gå til remix.ethereum.org, indsætte din kode i hovedsektionen og klikke på ABI:

Dette kopierer ABI-koden. Gå til din projektmappe og opret en fil kaldet contractData.js for at indsætte koden der med en variabel kaldet abi som sådan:

2. Nu har vi brug for bytekode for din smarte kontrakt. Bytekoden er den kompilerede smarte kontrakt, der vil blive implementeret til blockchain, vi har brug for disse oplysninger for at kunne implementere den. For at få bytekoden blev remixet igen og klik på denne knap:

Knappen bytecode-kopiering til din kode

Og opret en anden variabel inde i contractData.js kaldet bytecode med de oplysninger som sådan:

Du kan kopiere den samme kode, hvis din smarte kontrakt er nøjagtigt som den, jeg oprettede ovenfor.

Importer den javascript-fil i din html før index.js-filen for at have abi- og bytecode-variablerne tilgængelige:

Før vi opretter kontrakten på javascript, skal vi tilføje en begivenhedslytter til fortsættelsesknappen i afsnittet "Start nyt spil":

Hvad jeg gjorde der er:

  • Jeg føjede id-id til inputene, hvor brugeren bliver spurgt, hvor meget ether han vil lægge i escrow og adresse på kontrakten, hvis han tilslutter sig et eksisterende spil.
  • Derefter tilføjede jeg javascriptimport ovenfor index.js, fordi vi vil have abi og bytecode tilgængelig i index.js, da det først skal importeres.

Derefter tilføjer vi den krævede logik for at få den knap til at fungere. Vi kontrollerer, om indtastningen af ​​kontraktadressen i HTML-koden er tom eller ej.

Hvis det ikke er tomt, antager vi, at spilleren starter et nyt spil, som interessant nok giver dig mulighed for at starte et spil ved at bruge tilmeldingsknappen, hvis du lader adressen være tom.

Før jeg viser dig hele koden, vil jeg forklare dig, hvordan du implementerer en kontrakt ved hjælp af web3.js. Det ser simpelt ud, men jeg sad fast i nogle områder.

Så når brugeren klikker på “Start nyt spil”, giver han os escrow-beløbet i ether og hans adresse, kan vi implementere en ny kontrakt med denne funktion:

I det væsentlige opretter du kontraktforekomsten med abi, og du udfører metoden .new () for den kontrakt med bytekoden.

Derefter i tilbagekaldet får du en fejl, hvis nogen og et resultatobjekt. Resultatobjektet vil indeholde .adressen på den kontrakt, der er implementeret, når transaktionen behandles af minearbejdere.

Hvilket betyder, at denne tilbagekald udføres 2 gange. Én når du udfører oprettelsen af ​​kontrakten og en anden når adressen på den kontrakt er tilgængelig.

Du kan kontrollere, hvornår kontraktens adresse er tilgængelig med en simpel if-erklæring:

if (! result.address) {
    // Kontraktsoprettelsen er startet
} andet {
    // Kontrakten er implementeret, og du kan bruge adressen med result.address
}

Sådan distribuerer du en kontrakt med web3.

Men hvad nu hvis du vil have adgang til en eksisterende kontrakt på blockchain?

Det er nøjagtigt hvad vi har brug for for at "deltage" i et terningespil for at oprette en kontraktforekomst. Til dette formål har vi kun brug for ABI og kontraktens adresse. Bytekoden er ikke nødvendig. Sådan gør du det i web3:

Kontrakt = web3.eth.contract (abi)
contractInstance = Contract.at (adresse valgt)

Derefter kan du udføre funktioner i den kontrakt som sådan:

contractInstance.setupPlayer2 ({
  værdi: web3.toWei (valueSelected),
  gas: 4e6
}, (fejle, resultat) => {
    // Gør noget, når du har udført funktionen
})

Du behøver kun forekomsten, funktionsnavnet, eventuelle parametre og tilbagekaldsfunktionen.

Nu hvor du forstår, hvordan implementering og instantiering af et smart kontrakt fungerer på javascript, viser jeg dig den fulde kode for applikationen:

Ignorer alt ovenfor, hvad du er nødt til at fokusere på er i blokken til '# knap-fortsæt'-lytteren:

document.querySelector ( '# knap-fortsætte'). addEventListener ()

Fordi du kun er interesseret i, hvad der sker, når spiller 1 eller spiller 2 klikker på knappen 'Fortsæt'. Her er fordelingen:

  • Når en spiller klikker på den knap, udføres denne begivenhedslytter
  • Indvendigt får jeg værdierne for inputene til at opsætte escrow og adressen på den indsatte kontrakt, hvis spilleren deltager i et eksisterende spil. Disse er variablerne valgt og adresse valgt.
  • Derefter opretter jeg variablen til opsætning af kontrakten med den abi, som er nødvendig for begge spillere.
  • Derefter ser jeg, om adressen på den implementerede kontrakt er indstillet eller ej. Hvis adressen er tom, betyder det, at spilleren klikkede på "Start nyt spil", da han i så fald ikke ser adresseindtastningen.
  • Hvilket betyder, at jeg implementerer et nyt spil eller en smart kontrakt for den pågældende spiller med den valgte pil.
  • Den første spiller vil se adressen på den smarte kontrakt, der er indsat. Han bliver nødt til at dele denne adresse med den anden spiller for at starte et terningespil, da du har brug for 2 spillere.
  • Hvis han har angivet en adresse, betyder det, at han vil være med i et eksisterende spil. Vi kan gøre det ved at oprette en forekomst af den smarte kontrakt ved hjælp af adressen på den og derefter udføre funktionen setupPlayer2 ().
  • Jeg bruger setInterval-funktionen til at kontrollere hvert 1. sekund, om installationen af ​​afspilleren 2 er afsluttet eller ikke for at starte spillet.

Store! Hvis du har nået det indtil nu, betyder det, at du er forpligtet, og at du faktisk lærer noget. Den bedste del er nærmere, end du tror. I den næste artikel ser du, hvordan du opretter statskanaler til dit spil i javascript for at oprette en skalerbar Ethereum decentral applikation.

Gå ikke glip af det, og vær den første til at læse det, når det er afsluttet. Deltag i min eksklusive mailingliste over Ethereum Developers for at modtage opdateringer og information direkte fra mig her: http://eepurl.com/dDQ2yX

Del 2 nu tilgængelig lige her: https://medium.com/@merunasgrincalaitis/how-to-create-scalable-dapps-and-smart-contracts-in-ethereum-with-state-channels-step-by-step- 690f71a9bf2f

Hvis du føler dig overvældet med så avanceret information, eller du bare er ny på soliditet og Ethereum dapps, kan du tjekke min bog "Ethereum Developer: Learn Solidity From Scratch" her https://merunas.io/