Steg 3: Starta en Dapp Developer Portal

    Tredje stegen

    Så du har grunderna nere. I föregående avsnitt utvecklade du ett smart kontrakt och distribuerade det med Truffle. Men i föregående avsnitt distribuerades dina smarta kontrakt till ett lokalt utvecklingsnätverk – och det är inte kul, eftersom bara du kan distribuera saker och interagera med det lokala testnätverket! Vi vill ha vänner! Och tillgång till andra smarta kontrakt som andra har distribuerat!

    I det här avsnittet kommer vi därför att övergå till att använda ett offentligt Ethereum-testnät, så att du kan delta i alla åtgärder som händer runt Ethereums ekosystem!

    Låt oss börja!

    Först ska vi prata om hur du får tillgång till dessa offentliga Ethereum-nätverk.

    För att komma åt dessa nätverk måste du ansluta till en nod som är ansluten till respektive nätverk. Du kan se varje Ethereum-nätverk som sin egen lilla Ethereum-värld och du kan se en Ethereum-nod som din gateway eller åtkomstpunkt till var och en av dessa världar! Eftersom Ethereum är ett distribuerat nätverk lagrar varje Ethereum-nod hela tillståndet för nätverket det är anslutet till (det finns noder som inte behöver lagra hela tillståndet, men oroa dig inte för det för närvarande) och kommunicerar ständigt med de andra noderna i nätverket för att hålla det tillståndet uppdaterat! För att kunna läsa från och skriva till detta tillstånd måste vi därför få tillgång till en av dessa noder.

    Du kan mycket väl vara värd för din egen nod genom att använda en av de många tillgängliga Ethereum-klienterna (Hyperledger Besu (Java-klient utvecklad av ConsenSys), Geth (Go-klient), Parity (Rust-klient), etc.) – det finns dock en hel del lite DevOps-omkostnader som kommer med värd och underhåll av din egen Ethereum-nod – speciellt om du vill göra det på ett tillförlitligt sätt! Som sådant har vi på ConsenSys byggt Infura – ett Ethereum-infrastrukturutbud i världsklass. Infura tar hand om hela nodhanteringsdelen för dig och ger dig omedelbar, pålitlig och skalbar åtkomst till kluster av Ethereum-noder! Du kan tänka på Infura som “Ethereum-nodes-as-a-Service” &# 128578;

    Komma igång med Infura

    För att komma igång med Infura vill du registrera ett konto på infura.io. Oroa dig inte – det är helt gratis att komma igång och du behöver inte ange känslig information!

    När du är registrerad skickas du till en sida som ser ut så här:

    infuraLogin

    Som den här sidan föreslår väljer du det första alternativet “Kom igång och skapa ditt första projekt för att komma åt Ethereum-nätverket!”

    Du kan namnge ditt projekt vad du vill – vi kommer att namnge vårt “testprojekt”.

    InfuraNP

    Nu får du de referenser du behöver för att komma åt Infura-noder!

    InfuraC

    Håll den här sidan öppen! Vi kommer tillbaka till det senare &# 128578;

    Nästa sak vi ska göra är att initiera ett nytt Truffle-projekt. Om du behöver hjälp med att installera Truffle, se föregående avsnitt i denna dokumentation.

    För att initiera ett nytt Truffle-projekt, skapa en ny mapp och kör

    tryffel init

    Därefter vill du lägga till Truffle HD Wallet-leverantören i ditt nyligen initierade projekt så att du kan underteckna dina transaktioner innan de skickas till Infura-noder. Varje tillståndsändring som du gör till Ethereum kommer i form av en transaktion – oavsett om det distribuerar ett kontrakt, anropar en funktion i ett kontrakt eller skickar en token! Varje transaktion måste undertecknas av ett konto – därför behöver vår applikation förmågan att underteckna transaktioner så att den kan göra statliga ändringar i Ethereum!

    Varje transaktion kostar också eter. Denna transaktionskostnad kallas ”gaskostnad”. För att våra signerade transaktioner ska kunna behandlas av nätverket när de har skickats till Infura-noder måste vi finansiera vårt konto med lite eter. Vi kommer att täcka detta lite senare, men det här är bara en annan viktig anledning till varför du behöver en plånbok & plånboksleverantör!

    Så här lägger du till Truffle HD Wallet-leverantören till din nyligen initierade projekttyp i din terminal:

    npm install – spara @ tryffel / hdwallet-leverantör

    Detta kan kasta vissa varningar, men så länge det installeras är du redo att gå!

    Nu kan vi skapa ett Ethereum-konto för vår applikation att använda! Eftersom vår plånboksleverantör är en HD-plånbok (hierarkisk deterministisk) kan vi deterministiskt generera konton med samma frasfras, eller mnemonic.

    För att skapa vårt konto måste vi först starta Ganache. Ganache är en Truffle-produkt som gör att vi enkelt kan skapa vårt eget lokala dev-nätverk. För att köra ganache, skriv bara

    ganache-cli

    Om du har slutfört steg 2 i den här guiden bör du ha Ganache / ganache-cli redan installerat – om du inte gör det kan du installera det med kommandot npm:

    npm installera -g ganache-cli

    Eller om du använder garn 

    garn globalt lägg till ganache-cli

    Därefter måste vi tillåta att vår app pratar med Ganache. Gå till din projektkatalog och kolla in truffle-config.js-filen, helt enkelt avmarkera (eller lägg till) följande rader under nätverk:

    utveckling: {värd: "127.0.0.1", // Localhost (standard: ingen) port: 8545, // Standard Ethereum-port (standard: ingen) nätverksid: "*" // Alla nätverk (standard: inget)},

    obefintlig

    Trevlig! Nu kan vår app prata med vårt Ganache-utvecklingsnätverk som körs 127.0.0.1:8545! Kör nu kommandot i ett nytt terminalfönster (men fortfarande i din projektmapp)

    tryffelkonsol

     för att ansluta till ditt Ganache-nätverk. Oroa dig inte – vi ansluter till ett offentligt nätverk senare! Vi behöver bara ansluta till Ganache just nu för att skapa våra nycklar &# 128578;

    Obs: Om du stöter på problem, se till att i Ganache matchar ditt RPC-serverportnummer din tryffelkonfigurationsfil. I standardfallet ska 8545 fungera, annars ändrar du konfigurationsfilen så att den matchar Ganache.

    Ange nu följande kommandon i Truffle-konsolen för att skapa din plånbok:

    const HDWalletProvider = kräver (‘@ tryffel / hdwallet-leverantör’);

    Detta bör resultera i ett svar av “odefinierad”

    För din 12-ords mnemonic kan du använda en mnemonic generator som den här om du vill!

    KONTROLLERA ATT DU SPARAR DIN MNEMONISKA (FRÖ) FRAS! Vi behöver det senare &# 128515;

    Lägg sedan till följande kommando i din terminal (medan du fortfarande är i tryffelutveckling):

    const mnemonic = ’12 ord här ‘; const plånbok = ny HDWalletProvider (mnemonic, "http: // localhost: 8545");

    Ange kommandot nu i din tryffelkonsol 

    plånbok

    Om du rullar uppåt bör du se en lista med konton, så här!

    addy

    Trots att kontot genererades medan vi var anslutna till Ganache kan vi använda samma Ethereum-konto i alla Ethereum-nätverk (Observera dock – även om samma konto kan användas i alla Ethereum-nätverk, tillgångar / aktiviteter som hör till det kontot är nätverksspecifikt – till exempel om jag gör en transaktion på Ethereum Mainnet kommer transaktionen endast att ske i Ethereum Mainnet och inget annat nätverk). Vi ska nu sluta interagera med Ganache (lokalt dev-nätverk) och börja använda det kontot för att interagera med vissa offentliga nätverk!!

    Vanligtvis är det första du behöver göra när du interagerar med ett offentligt nätverk att skaffa en del av nätverkets eter. I vårt fall ansluter vi till Ropstens offentliga testnätverk, så vi måste skaffa lite Ropsteneter (ETH)! Oroa dig inte – testnät ETH är gratis och rikligt och super lätt att få &# 128077;

    Dags att skaffa test ETH

    För att få lite Ropsten ETH, gå över till Ropsten kran. Klistra in din kontoadress och viola! Du har fått lite Ropsten ETH och kan börja skicka transaktioner (dvs. göra tillståndsändringar till) Ropsten-nätverket!

    Som referens är Ropsten-testnätet ett offentligt Ethereum-testnätverk, där du kan testa din kod i en miljö som speglar den Ethereum-mainnet. Huvudskillnaden mellan Ropsten-testnätet (och de andra offentliga Ethereum-testnäten) är att i testnätland är ETH rikligt och har inget verkligt värde! När du börjar interagera med Ethereum-mainnet kostar den eter du använder för att betala för dina transaktioner (bensinkostnader) FAKTA dollar – och så måste vi se till att vi gör saker rätt i förväg, så att vi inte tappar våra hårda -intjänade kontanter / vår dyrbara mainnet ETH!

    Ropsten-testnätet, tillsammans med de flesta andra offentliga testnätverk, har många blockutforskare som du kan se aktiviteten som händer i kedjan (https://ropsten.etherscan.io/). För att se ditt finansierade konto klistrar du bara in ditt kontos adress i utforskaren – så kan du se all historik som är associerad med det:

    Skärmdump 2020 09 01 kl 4 34 21 AM

    OK! Nu när vi har vår plånboksleverantör och ett konto finansierat med Ropsten ETH kan vi gå tillbaka till vårt projekt och peka på Infura-noder anslutna till Ropsten-testnätet.

    Det första vi vill göra är att skapa en.env-fil för att hysa våra värdefulla SECRETS! Dessa hemligheter inkluderar vår Infura API-nyckel (genererad när vi skapade vårt Infura-konto) och vår mnemonic fras.

    Skapa helt enkelt en ny fil “.env” på rotnivån för ditt projekt. Du måste också installera dotenv NPM-paketet genom att ange följande kommando i terminalen

    npm install – spara dotenv

    I den här new.env-filen behöver du två saker:

    INFURA_API_KEY = INSÄTTA DIN API-NYCKEL HÄR (inga offerter)

    MNEMONIC = ”linshvalfläktbubbla online-säte exponerar lager nummer meningen vinnare”

    INFURA_API_KEY är projekt-ID från projektet du tidigare skapade i infura:

    Skärmdump 2020 09 01 kl 4 37 12 AM

    Och MNEMONIC är den frasfras på 12 ord som du tidigare använde för att skapa ditt konto.

    Din fil ska nu se ut så här:

    Skärmdump 2020 09 01 kl 4 41 53 AM

    Okej, vi närmar oss!

    OBS: Om du ska driva detta till ett Github-arkiv eller göra detta projekt offentligt på något sätt, GÖR DIG att ha din.env-fil in.gitignore så att dina hemligheter inte blir exponerade! 

    Nu kommer vi att behöva gå över till filen truffle-config.js. Här inne måste vi lägga till några saker för att beteckna vår leverantör (som används för att interagera med Infura (Truffle HDWallet Provider som vi tidigare installerade), och rikta vår app mot Ropsten Infura-noder.

    Överst i filen, lägg till:

    behöva("dotenv") .config (); const HDWalletProvider = kräver ("@ tryffel / hdwallet-leverantör");

    Därefter vill du lägga till följande nätverk under “nätverk”:

    ropsten: {leverantör: () => ny HDWalletProvider (process.env.MNEMONIC, `https://ropsten.infura.io/v3/$ {process.env.INFURA_API_KEY}`), nätverksid: 3, // Ropstens idgas: 5500000, // Ropsten har en lägre blockgräns än mainnet-bekräftelser: 2, // # av confs för att vänta mellan distributioner. (standard: 0) timeoutBlocks: 200, // # block före en distribution timeout (minimum / default: 50) skipDryRun: true // Hoppa över torr körning före migreringar? (standard: falskt för offentliga nät)}

     

    Nu ska din truffle-config.js-fil se ut så här!

    Sidanot:

    Om du använder Infura-slutpunkter krävs parametern `från` eftersom de inte har en plånbok. Om du använder Ganache- eller Geth RPC-slutpunkter är detta en valfri parameter.

    Skärmdump 2020 09 01 kl 4 50 54 AM

    NU ÄR VI KLAR FÖR TROLLAREN! Det är dags att distribuera ett smart kontrakt till ROPSTEN!

    Ställa in ett smart kontrakt

    Fasthetsinställning

    Först vill vi skapa ett smart kontrakt att distribuera! Du kan ta det smarta kontraktet som du utvecklade i föregående avsnitt i den här guiden, bygga ditt eget smarta kontrakt eller bara använda följande (extremt enkla) provkontrakt:

    pragma soliditet >= 0,5,8; kontrakt SimpleStorage {uint256 storeData; funktionsuppsättning (uint256 x) public {storeData = x; } funktion få () public view returnerar (uint256) {return storedData; }}

    Detta kontrakt bör skapas som en “.sol” (Solidity) -fil i mappen “contract” i ditt projekt (i det här scenariot har vi skapat SimpleStorage.sol-filen, som är vårt SimpleStorage-kontrakt:

    byggnadsställningar

    Migrationsinställningar

    Därefter måste vi konfigurera vår migreringsfil!

    Migrationer är JavaScript-filer som hjälper dig att distribuera kontrakt till Ethereum-nätverket. Dessa filer är ansvariga för att iscensätta dina distributionsuppgifter, och de är skrivna under antagandet att dina distributionsbehov kommer att förändras över tiden. När ditt projekt utvecklas skapar du nya migrationsskript för att främja denna utveckling i blockchain. En historik över tidigare körda migreringar registreras via kedjan genom ett särskilt migrationsavtal. Du kan hitta mer information om dem här.

    Vår migreringsfil för att distribuera vårt kontrakt kommer att se ut så här:

    const SimpleStorage = artifacts.require ("SimpleStorage.sol"); module.exports = function (deployer) {deployer.deploy (SimpleStorage); };

    Spara den här filen i “migrations” -mappen under namnet “2_deploy_contracts.js”.

    Implementera ditt första offentliga kontrakt

    Dags att migrera

    Nu är du faktiskt redo för MAGIC TO HAPPEN! Gå tillbaka till konsolen och skriv

    tryffel migrera – nätverk ropsten

    Bom!&# 128163; Din kod distribuerades till det offentliga Ropsten Ethereum Test Net!!! 

    Vad som just hände var:

    1. Ditt solida smarta kontrakt (i mappen “kontrakt”) sammanställdes till bytecode – den maskinläsbara koden som Ethereum Virtual Machine kan använda.

    2. Denna bytecode, + några andra data, samlades ihop till en transaktion.

    3. Transaktionen undertecknades av ditt konto.

    4. Transaktionen skickades till Infura-noden som är ansluten till Ropsten.

    5. Transaktionen sprids i hela nätverket, plockas upp av en Ropsten-gruvarbetare och ingår i ett Ropsten-block.

    6. Ditt smarta kontrakt är nu LIVE på Ropsten blockchain!

    Du kan se ditt kontrakt med Etherscan: https://ropsten.etherscan.io/ – klistra in i kontraktets adress (ska vara i din terminal) för att visa den!

    Skärmdump 2020 09 01 kl. 5 19 12

    Fantastisk! Vi har precis distribuerat vårt första smarta kontrakt till ett OFFENTLIGT Ethereum-nätverk! &# 129327;

    Processen är exakt samma för distribution till Ethereum mainnet, förutom att du byter ut nätverket i truffle-config.js-filen för Ethereum mainnet (och, naturligtvis, kör mainnet Truffle-migreringskommandot istället för Ropsten) ! Vi kommer inte att gå igenom denna process här, för att distribuera till Ethereum-mainnet kommer att kosta faktiska $ – men om du vill ha hjälp med detta, hoppa vidare till ConsenSys Discord och vi hjälper gärna till!

    Bygga en Web3 frontend 

    Nu när vi har distribuerat vårt kontrakt till Ropsten, låt oss bygga ett enkelt användargränssnitt för att interagera med det!

    Obs! DApp “frontend” är bara dina vanliga, vanliga gamla frontendar – som sådan kan vi använda alla våra gamla verktyg vi är bekanta med (create-react-app, etc.) för att snurra upp vår frontend , och lägg bara till några saker så att frontend kan läsa från och skriva till Ethereum! Det betyder att alla dina gamla webbutvecklingsfärdigheter kan överföras direkt till Ethereum-land / Web3!!

    Snurra upp vårt React-projekt 

    Okej, låt oss komma igång.

    Se först till att du har en katalog som innehåller all information vi just skapat för vårt lagringsavtal. Jag har kallat min mapp “lagring-back” och den innehåller det arbete vi just slutfört för att få vårt kontrakt att konfigureras och distribueras. 

    Skärmdump 09 09 01 kl 5 26 33 AM

    Nu ska vi börja med att spinna upp ett reageringsprojekt, låt oss kalla vårt i detta exempel “lagringslaboratorium”

    Låt oss köra följande i vår terminal för att starta vårt projekt 

    npx create-react-app storage-lab

    Nu när vi har fått vårt nya projekt panna, låt oss gå in i projektkatalogen

    cd-lagringslaboratorium

    Nu när vi är inne i vårt projekt kommer vi nu att lägga till Web3-paketet, vilket gör att vårt projekt kan interagera med Ethereum! Mer på web3 här

    npm installera web3

    Web3 är ett av två stora paket vi kan använda, det andra är ethers.js. För det här exemplet kommer vi att använda web3 men om du vill läsa mer om ethers.js ta en titt här 

    För en detaljerad förklaring av de två, ta en titt på denna skrivning web3 vs etrar

    Bra! Vi är nu nästan redo att få vårt reaktionsprojekt att interagera med vårt kontrakt!

    Låt oss först ta vår katalog från tidigare (för mig är det “lagring-back”) som bara innehåller det arbete vi redan har gjort med våra smarta kontrakt och nu ska vi lägga till det i vårt nya reageringsprojekt. Detta kommer att leva på samma nivå som vår src, och nu borde vi ha allt vi behöver tillsammans i vår reaktiva REPO.

    Skärmdump 09 09 01 kl 5 31 38 AM

    Därefter måste vi ställa in vår fil som innehåller vår ABI-information.

    “ABI?”

    Glad att du frågade! 

    ABI (Contract Application Binary Interface) är det vanliga sättet att interagera med kontrakt inom Ethereums ekosystem, både utanför blockchain och för interaktion mellan kontrakt och kontrakt. När vi sammanställde vårt SimpleStorage-kontrakt i ett tidigare steg skapade det en JSON-fil för oss. Kontrollera själv, vi har en SimpleStorage.json-fil inuti våra build / contract

    Skärmdump 2020 09 01 kl 6 04 20 AM

    En första titt på den här filen kommer att avslöja mycket information, just nu behöver vi bara fokusera på ABI för att synkronisera vårt kontrakt med den frontend vi utvecklar. Denna JSON innehåller den information vi behöver för att kommunicera vårt kontrakt med vår frontend.

    Vårt ABI är en matris som innehåller objekt. Om du tittar på filen närmare kan du se att var och en av dessa objekt faktiskt är varje funktion som vårt SimpleStorage-kontrakt innehåller.

    Skärmdump 09 09 01 kl 5 23 23

    Du kan snabbt se

    “Name”: “set”

    “Namn”: “få”

    båda med en “typ:” funktion “båda funktionerna vi deklarerade när vi skrev vårt smarta kontrakt!

    Även om Truffle fördunklar de närmaste stegen, kommer vi att gå igenom ett mycket mer “manuellt” sätt att göra saker så att du utsätts för alla grunderna &# 128578;

    Först, fortsätt och kopiera din abi-information – vi behöver den på ett ögonblick. 

    Låt oss skapa en mapp inuti vår src som heter “abi”.

    Inuti vår nyligen gjorda abi-mapp, låt oss nu skapa en fil med namnet abi.js

    Obs! Vi behöver tekniskt inte ha den här separationen och kan bara lägga till våra abi.js i vår src, men att behålla våra abi.js-filer innehåller hjälper till med organisationen.

    Nu kommer vi att kopiera vår abi-array som vi tagit tidigare från SimpleStorage.JSON-filen och lägga till den i vår nygjorda abi.js-fil. Vi kommer att ändra filen lite så att vårt projekt kan importera informationen till våra App.js. Glöm inte eftersom det här är en.js-fil, vi måste lägga till en export så att vi har möjlighet att dra den till vår app.js senare. Låt oss namnge const samma som kontraktet, utom med camelcase (se kod nedan):

    Detta kommer att vara koden som vi lagrar i vår abi.js-fil

    export const simpleStorage = [{konstant: falsk, ingångar: [{namn: "x", typ: "uint256", }, ], namn: "uppsättning", utgångar: [], betalas: falsk, tillståndMutabilitet: "obetalt", typ: "fungera", }, {konstant: sant, ingångar: [], namn: "skaffa sig", utgångar: [{namn: "", typ: "uint256", },], betalas: false, stateMutability: "se", typ: "fungera", },];

    Dags att gå till vår App.js och importera både web3 och vår nygjorda abi.js-fil.

    Vi kommer också att använda krokar i det här exemplet (det är därför vi också importerar {useState}. Du kan läsa mer om useState här.

    Toppen av vår App.js-fil ska nu se ut så här:

    importera React, {useState} från "reagera"; importera {simpleStorage} från "./ abi / abi"; importera Web3 från "web3"; importera "./App.css";

    Vi måste nu se till att vi har möjlighet för alla godtyckliga användare att ha möjlighet att ansluta och använda vår dApp, så länge de har en plånboksleverantör!

    Huvudplånboken som används i Ethereum-utrymmet för dApp-interaktion är MetaMask, som introducerades i steg 1.

    Om du inte har MetaMask, besök metamask.io

    Med MetaMask installerad kan vi komma åt vår plånbok inuti vår dapp med:

    const web3 = ny Web3 (Web3.givenProvider);

    “Web3.givenProvider” kommer att ställas in i en webbläsare som stöds av Ethereum.

    (du kan läsa mer om varför detta är nödvändigt här)

    Så nu ska vår kod se ut så här:

    importera React, {useState} från "reagera"; importera {simpleStorage} från "./ abi / abi"; importera Web3 från "web3"; importera "./App.css"; const web3 = ny Web3 (Web3.givenProvider);

    Ok! Hittills har vi:

    • Spun upp ett React-projekt
    • Installerad Web3
    • Lade till vår mapp som innehåller vårt build + kontrakt + migration till vårt React-projekt
    • Skapade en abi.js-fil med de abi-data som vi hämtade från SimpleStorage.json
    • Importerade data vi behöver för att interagera med vårt kontrakt
    • Skapade en variabel som gör att vår dApp kan kommunicera med användarens plånbok

    Även om Truffle gör de närmaste stegen onödiga (vi går igenom en mycket enklare version senare), kommer vi att lägga till lite mer manuell komplexitet i vår dApp för utbildningsändamål.

    Vad vi ska göra nu är att skapa två nya variabler: en för att lagra adressen till kontraktet vi distribuerade på Ropsten och den andra för att matcha det kontraktet till vårt ABI, så att vår app vet hur man pratar med det! 

    För att hitta kontraktsadressen, navigera till den JSON-fil vi befann oss i tidigare (som innehåller ABI (SimpleStorage.json)) och bläddra till botten. Adressen finns i fältet “adress” här:

    "kompilator": { "namn": "solc", "version": "0.5.8 + commit.23d335f2.Emscripten.clang" }, "nätverk": { "3": { "evenemang": {}, "länkar": {}, "adress": "0x24164F46A62a73de326E55fe46D1239d136851d8", "transaktionHash": "0x1f02006b451b9e85f70acdff15a01c6520e4beddfd93a20e88a9b702a607a7b0" }}, "schemaVersion": "3.0.16", "uppdateradAt": "2020-06-30T20: 45: 38.686Z", "devdoc": { "metoder": {}}, "användardoc": { "metoder": {}}}

    Alternativt kan du gå över till https://ropsten.etherscan.io/ och leta upp adressen till kontot som distribuerade kontraktet! I Etherscan exponerar du själva kontraktsadressen genom att klicka på “Kontraktsskapande”.

    Skärmdump 2020 09 01 vid 5 43 46 AM

    Nu tar vi kopian av ditt kontrakts adress och skapar en ny variabel för att lagra den. 

    Utan detta kommer vi inte att kunna kommunicera med kontraktet och vår dApp fungerar inte som avsett.

    Du lägger till detta under vår const web3 = new Web3 (Web3.givenProvider);

    const contractAddress = "din kontraktsadress här";

    Sedan kommer vi att skapa en ny ny variabel med namnet “storageContract” som kommer att innehålla både vår kontraktsadress (så att vår app vet var kontraktet är) och ABI (så att vår app vet hur man interagerar med kontraktet).

    const storageContract = new web3.eth.Contract (simpleStorage, contractAddress);

    Vår App.js ska nu se ut så här

    importera React, {useState} från "reagera"; importera {simpleStorage} från "./ abi / abi"; importera Web3 från "web3"; importera "./App.css"; const web3 = ny Web3 (Web3.givenProvider); const contractAddress = "din kontraktsadress här"; const storageContract = new web3.eth.Contract (simpleStorage, contractAddress);

    Vi måste nu få våra krokar att hålla variabler som kommer att interagera med vårt kontrakt och frontend. Vi kommer att göra detta genom att förklara följande inom vår appfunktion:

    importera React, {useState} från "reagera"; importera {simpleStorage} från "./ abi / abi"; importera Web3 från "web3"; importera "./App.css"; const web3 = ny Web3 (Web3.givenProvider); const contractAddress = "din kontraktsadress"; const storageContract = new web3.eth.Contract (simpleStorage, contractAddress); funktion App () {const [nummer, setUint] = useState (0); const [getNumber, setGet] = useState ("0");

    Vår första användning av useState (0) håller den uint256 som användaren förklarar.

    (namngivningskonventionerna för nummer, setUint, getNumber, setGet förhoppningsvis hjälp att visa vad som händer)

    useState (“0”) fungerar som en platshållare tills vi har bekräftat vår undertecknade åtgärd (vår deklarerade uint256)

    setUint vi kommer snart att ringa in i vår återkomst (mer om detta senare)

    Dags för vår logik

    Därefter lägger vi till vårt antal Set och NumberGet-logik (vi lägger till numberSet inom vår funktion App)

    const numberSet = async (t) => {t.preventDefault (); const-konton = väntar på fönster.ethereum.enable (); const-konto = konton [0]; const gas = väntar på storageContract.methods.set (nummer) .estimateGas (); const post = väntar på storageContract.methods.set (nummer) .send ({från: konto, gas,}); }; const numberGet = async (t) => {t.preventDefault (); const post = väntar på storageContract.methods.get (). call (); setGet (post); };

    Vi ställde in preventDefault (information om preventDefault hittades här)

    Vi använder också ett async-samtal vid get för kontraktet (information om async hittades här)

    Vår hook setGet () lagrar ett standardvärde som vi först tittade på (“0”)

    const-konton = väntar på fönster.ethereum.enable ();

    ser till att vi ringer till vår anslutna adress via MetaMask.

    const-konto = konton [0];

    Dra in anslutningskontot

    Du kanske undrar vad som händer med 

    const gas = väntar på storageContract.methods.set (nummer) .estimateGas ();

    Vår app behöver tillstånd för att få tillgång till användarnas medel för att betala för gasavgifter, alla funktioner som kräver eter oavsett om det finns på testnet eller mainnet. Det är här som vår anslutning till MetaMask är till nytta för att registrera för denna användning för att ställa in vår uint256 och betala för den (med test ETH).

    Så för alla funktioner som behöver gas måste du beräkna den använda gasen.

    “Set” -funktionen i vårt kontrakt kräver gas

    “Få” gör det inte.

    (detta beror på att “Get” visar vad som redan har förklarats med “Set”)

    const post kommer att ta godkänd i uint256, bekräfta transaktionen (posta betala gasavgift) från din MetaMask plånbok på Ropsten-nätverket.

    Därefter skickar vi funktionsparametrarna via methods.set () och med vår deklarerade adress (användaradress) hanterar vi sedan Set-funktionen.

    Vi skapar vår smarta kontraktstransaktion genom att skicka in våra funktionsparametrar till smarta kontraktsmetoder. Set () och uppskattad gas- och användarkontoadress till.send ().

    const post = väntar på storageContract.methods.set (nummer) .send ({från: konto, gas,});

    Detta borde vara all logik vi behöver för att täcka vårt antal Set.

    Nu behöver vi vårt nummer Get

    const numberGet = async (t) => {t.preventDefault (); const post = väntar på storageContract.methods.get (). call (); setGet (post); };

    Vårt första post hämtar vårt inställda nummer och setGet skickar in det nya värde som vi förklarade

    Så vår “0” kommer onClick hänvisa till vårt nummer Få och göra vår unint256!

     Så nu ska din app.js se ut så här

    importera React, {useState} från "reagera"; importera {simpleStorage} från "./ abi / abi"; importera Web3 från "web3"; importera "./App.css"; const web3 = ny Web3 (Web3.givenProvider); const contractAddress = "din kontraktsadress"; const storageContract = new web3.eth.Contract (simpleStorage, contractAddress); funktion App () {const [nummer, setUint] = useState (0); const [getNumber, setGet] = useState ("0"); const numberSet = async (t) => {t.preventDefault (); const-konton = väntar på fönster.ethereum.enable (); const-konto = konton [0]; const gas = väntar på storageContract.methods.set (nummer) .estimateGas (); const post = väntar på storageContract.methods.set (nummer) .send ({från: konto, gas,}); }; const numberGet = async (t) => {t.preventDefault (); const post = väntar på storageContract.methods.get (). call (); setGet (post); };

    Låt oss skapa en mycket grundläggande återgivning för att göra så att vi kan testa om vi kan 

    • ställa in ett unint256-värde,
    • Dra upp vår metamaskplånbok och bekräfta transaktionen
    • Betala bensinkostnaden
    • hämta sedan värdet (unint256) som vi har lagrat när transaktionen har slutförts.

    Vår återkomst ser ut så här: 

    return (Ställ in din uint256: setUint (t.target.value)} /> Bekräfta

    Hämta din uint256 {getNumber}); } exportera standardapp;

    Några snabba CSS

    Låt oss nu gå över till App.css-filen, ta bort pannans plattkod och lägg till den istället

    .huvud {text-align: center; display: flex; justify-content: center; bakgrundsfärg: # f2f1f5; höjd: 100vh; } .card {min-höjd: 50vh; bredd: 50vw; display: flex; flexriktning: kolumn; align-items: center; justify-content: center; } .form {höjd: 20vh; bredd: 20vw; display: flex; rättfärdiga innehåll: utrymme-jämnt; flexriktning: kolumn; } .knapp {bredd: 20vw; höjd: 5vh; }

    Nu är vi redo att testa!

    I din terminal kör

    garnstart

    I vår lokala värd: 3000 ska vi se ut så här

     

    Skärmdump 2020 09 01 kl 6 12 49 AM

    Vi borde nu kunna ange ett unint256-värde i vårt inmatningsfält!

    När vi har bekräftat vårt nummer i vår dApp signerar vi sedan via MetaMask (Se till att din plånbok är inställd på Ropsten-nätverket)

    confrim1

    Vi gjorde det! &# 129303;

    Vi har nu vårt smarta kontrakt anslutet till en frontend och har förmågan att manipulera Set-funktionen (förutsatt att vi har testet ETH för att betala gasavgiften för transaktionen). Sedan kan vi anropa Get-funktionen och hämta det lagrade uint265-värdet.

    Ganska coolt va!?!

    Extra styling 

    Nu är det dags att visa hur enkelt det kan vara att implementera ännu mer populär Web2-teknik i vårt projekt.

    Vi kommer att använda MUI för att lägga till grundläggande styling, om du redan utvecklar med React kanske du känner till material-ui. (Detaljer hittades här) Material-UI eller MUI för kort är ett mycket populärt React-ramverk som låter dig snabbt snurra upp ett projekt med mycket styling tillagad under förutsättning att du följer namngivningskonventionerna. Det är också väldigt enkelt att manipulera om du bara vill använda en foundation och anpassa därifrån.

    * Detta kommer att vara ett mycket kort exempel på hur man lägger till MUI i ett projekt med små tillägg för att visa hur snabbt du kan integrera vårt projekt som det står med en Web2-teknik. 

    Lägga till MUI

    Vi börjar med att köra kommandot (medan du fortfarande är i vår projektkatalog i terminalen (om din app fortfarande körs måste du stänga den (ctrl + c) eller öppna en ny flik)):

    Så här installerar du med npm:

    npm install @ material-ui / core

    Eller med garn:

    garn lägg till @ material-ui / kärna

    Nu när vi har injicerat MUI kommer vi att börja med att ändra vår styling. Överst i vår app.js-fil ska vi importera några nya saker:

    importera {simpleStorage} från "./ abi / abi"; importknappen från "@ material-ui / core / Button"; importera TextField från "@ material-ui / core / TextField"; importera {makeStyles} från "@ material-ui / core / styles";

    Importen av {makeStyles} gör att vi kan manipulera stylingen (i det här fallet) våra knappar och textfält tillsammans med att importera standard MUI-styling. 

    Vi kommer nu att göra en variabel (ovanför vår funktion) som tar in pannans styling från MUI

    const useStyles = makeStyles ((tema) => ({root: { "& > *": {margin: theme.spacing (1),},},}));

    Nu inom vår appfunktion kommer vi också att lägga till en variabel med namnet “klasser” som drar in de definierade stilar som vi just förklarade ovan.

    function App () {const classes = useStyles (); const [nummer, setUint] = useState (0); const [getNumber, setGet] = useState ("0");

    Vi kommer nu att göra justeringar inom vår återkomst för att ersätta några av våra fält med det vi just importerat.

    returnera (setUint (t.target.value)} variant ="beskrivs" /> Bekräfta

    Hämta din uint256 {getNumber}); } exportera standardapp;

    Din kod ska nu se ut så här

    importera React, {useState} från "reagera"; importera {simpleStorage} från "./ abi / abi"; importera Web3 från "web3"; importera "./App.css"; importera {makeStyles} från "@ material-ui / core / styles"; importknappen från "@ material-ui / core / Button"; importera TextField från "@ material-ui / core / TextField"; const useStyles = makeStyles ((tema) => ({root: { "& > *": {margin: theme.spacing (1),},},})); const web3 = ny Web3 (Web3.givenProvider); const contractAddress = "din kontraktsadress här"; const storageContract = new web3.eth.Contract (simpleStorage, contractAddress); function App () {const classes = useStyles (); const [nummer, setUint] = useState (0); const [getNumber, setGet] = useState ("0"); const numberSet = async (t) => {t.preventDefault (); const-konton = väntar på fönster.ethereum.enable (); const-konto = konton [0]; const gas = väntar på storageContract.methods.set (nummer) .estimateGas (); const post = väntar på storageContract.methods.set (nummer) .send ({från: konto, gas,}); }; const numberGet = async (t) => {t.preventDefault (); const post = väntar på storageContract.methods.get (). call (); setGet (post); }; returnera (setUint (t.target.value)} variant ="beskrivs" /> Bekräfta

    Hämta din uint256 {getNumber}); } exportera standardapp;

    Om vi ​​nu tittar på vårt reaktionsprojekt borde det se ut så här!

    Skärmdump 09 09 2020 vid 6 48 55 AM

    Bra gjort!

    Vi har fortfarande alla funktioner från tidigare och har nu injicerat ett lättanvänt ramverk för att ytterligare anpassa vårt projekt hur vi vill. Ta en titt på MUI dokumentation att experimentera med dina egna tillägg / modifieringar!

    Bonusrunda 

    Det skulle vara trevligt att visa användarnas anslutningsadress i vår dApp, eller hur??

    Låt oss göra en mycket snabb och grundläggande komponent för att göra exakt det!

    Vi börjar med att skapa en separat komponent som vi kan importera tillbaka till vår App.js-fil. Det är en bra idé att separera vår logik för att inte bara hålla vår App.js lätt att navigera utan också följa övningen med en komponent, helst bara göra en sak. Om det slutar växa, bör det sönderdelas i mindre delkomponenter.

    Komponentutbyggnad 

    Vi skapar en ny mapp som heter komponenter på samma nivå som vår src och inom den mappen skapar vi en Nav.js-fil. Vårt byggnadsställningar bör nu se ut så här

    Skärmdump 2020 09 01 kl 6 47 07 AM

    Vi kommer också att skapa en Nav.css-fil i komponentmappen för att importera alla stilar vi använder specifikt för Nav-komponenten.

    Låt oss öppna vår Nav.js och låt oss importera vår React-, Web3- och vår tomma.css-fil

    importera Reagera från "reagera"; importera Web3 från "web3"; importera "./Nav.css"

    Nu kommer vi att skapa en klass som heter Nav och vi lägger till några saker i den för att visa vår anslutna adress. Vi börjar med att ställa in vårt tillstånd att läsa kontot

    klass Nav utökar React.Component {state = {account: "" };

    Fortfarande inom vår klass kommer vi att ladda kontot att läsa från genom att lägga till vår async loadAccount-logik

    async loadAccount () {const web3 = new Web3 (Web3.givenProvider || "http: // localhost: 8080"); const-nätverk = väntar på web3.eth.net.getNetworkType (); const-konton = väntar på web3.eth.getAccounts (); this.setState ({konto: konton [0]}); }

    Nästa kommer vi att skapa en componentDidMount (som kommer att åberopas omedelbart efter att komponenten har monterats). I vårt fall drar vi in ​​det laddade kontot. Läs mer här

    componentDidMount () {this.loadAccount (); }

    Sidanot:

    Detta kan göras annorlunda, istället för en klass kan vi skapa en funktion och använda krokar i motsats till componentDidMount, men för detta exempel kommer vi att hålla fast vid den här metoden.

    Vi skapar sedan en rendering ovanför vår retur, render är en metod som krävs när du skriver en React-komponent med en klassmetod. Inom vår återgång lägger vi till en adressklass till vår div (för att ge grundläggande styling till senare) längs en p-tagg för att visa den anslutna adressen som vi hämtar med {this.state.account}

    render () {return (Din anslutna adress: {this.state.account}); }} exportera standardnav;

    Vår Nav.js-fil ska nu se ut så här

    importera Reagera från "reagera"; importera Web3 från "web3"; importera "./Nav.css" klass Nav utökar React.Component {state = {account: "" }; async loadAccount () {const web3 = new Web3 (Web3.givenProvider || "http: // localhost: 8080"); const-nätverk = väntar på web3.eth.net.getNetworkType (); const-konton = väntar på web3.eth.getAccounts (); this.setState ({konto: konton [0]}); } componentDidMount () {this.loadAccount (); } render () {return (Din anslutna adress: {this.state.account}); }} exportera standardnav;

     

    Låt oss gå till Nav.css-filen och lägga till mycket grundläggande styling

    .adress {display: flex; justify-content: center; }

    Du kan tekniskt lägga till detta i App.css-filen, kom ihåg dock ganska snabbt som kan bli rörigt. Komponenter bör vara återanvändbara och för att undvika så mycket friktion som möjligt genom att dela upp ditt arbete kan det spara huvudvärk på vägen.

    Låt oss nu gå tillbaka till vår App.js och importera vår nygjorda komponent och se till att vi lägger till den i vår återkomst för att visa den!

    Vår färdiga App.js-fil ska se ut så här

    importera React, {useState} från "reagera"; importera {simpleStorage} från "./ abi / abi"; importera Web3 från "web3"; importera Nav från "./components/Nav.js"; importera "./App.css"; importera {makeStyles} från "@ material-ui / core / styles"; importknappen från "@ material-ui / core / Button"; importera TextField från "@ material-ui / core / TextField"; const useStyles = makeStyles ((tema) => ({root: { "& > *": {margin: theme.spacing (1),},},})); const web3 = ny Web3 (Web3.givenProvider); const contractAddress = "din adress här"; const storageContract = new web3.eth.Contract (simpleStorage, contractAddress); function App () {const classes = useStyles (); const [nummer, setUint] = useState (0); const [getNumber, setGet] = useState ("0"); const numberSet = async (t) => {t.preventDefault (); const-konton = väntar på fönster.ethereum.enable (); const-konto = konton [0]; const gas = väntar på storageContract.methods.set (nummer) .estimateGas (); const post = väntar på storageContract.methods.set (nummer) .send ({från: konto, gas,}); }; const numberGet = async (t) => {t.preventDefault (); const post = väntar på storageContract.methods.get (). call (); setGet (post); }; lämna tillbaka ( setUint (t.target.value)} variant ="beskrivs" /> Bekräfta

    Hämta din uint256 {getNumber}); } exportera standardapp;

    Vi bör nu se vår anslutna adress på toppen och fortfarande behålla all vår funktionalitet!

    bonusV1

    &# 127881; Vi gjorde det! &# 127881;

    Vi har nu en dApp som vi har byggt från grunden. Vi tog in vårt smarta kontrakt i ett React-projekt, skrev logik för att säkerställa att vi har användarfunktionalitet, skapade en komponent för att återge den anslutna adressen och till och med lade till ett populärt utformningsramverk för vårt projekt.

    Bra gjort! Detta är bara början på dina Web3-utvecklingsäventyr och du har redan något att visa att du inte bara har skapat utan också lindat huvudet. Kontakta oss i Discord och dela ditt projekt (särskilt om du har gjort några ändringar eller tillägg) med oss!

      Onboarding för utvecklare: Steg 1Onboarding för utvecklare Steg 1

      Onboarding för utvecklare: Steg 1

      Onboarding för utvecklare: Steg 2Steg 2 för utvecklare

      Onboarding för utvecklare: Steg 2

      10-minuters Ethereum-orientering10 minuters Ethereum-orientering

      10-minuters Ethereum-orientering
    Mike Owergreen Administrator
    Sorry! The Author has not filled his profile.
    follow me
    Like this post? Please share to your friends:
    map