Pasul 3: Lansați un portal pentru dezvoltatori Dapp

    Al treilea pas

    Deci, ați descărcat elementele de bază. În secțiunea anterioară, ați dezvoltat un contract inteligent și l-ați implementat folosind Truffle. Cu toate acestea, în secțiunea anterioară, contractele dvs. inteligente au fost implementate într-o rețea de dezvoltare locală – și asta nu este deloc distractiv, deoarece doar dvs. puteți implementa lucruri și interacționa cu rețeaua de testare locală! Vrem prieteni! Și accesul la alte contracte inteligente pe care alte persoane le-au desfășurat!

    Prin urmare, în această secțiune, vom trece la utilizarea unei rețele publice de testare Ethereum, astfel încât să vă puteți alătura tuturor acțiunilor care se petrec în jurul ecosistemului Ethereum!

    Să începem!

    În primul rând, vom vorbi despre modul în care obțineți acces la aceste rețele publice Ethereum.

    Pentru a accesa aceste rețele, trebuie să vă conectați la un nod care este conectat la rețeaua respectivă. Puteți vizualiza fiecare rețea Ethereum ca propria sa mică lume Ethereum și puteți vizualiza un nod Ethereum ca poartă sau punct de acces pentru fiecare dintre aceste lumi! Deoarece Ethereum este o rețea distribuită, fiecare nod Ethereum stochează întreaga stare a rețelei la care este conectat (există noduri care nu au nevoie să stocheze starea completă, dar nu vă faceți griji pentru asta pentru moment) și comunică constant cu celelalte noduri din rețea pentru a menține acea stare actualizată! Prin urmare, pentru a putea citi și scrie în această stare, va trebui să avem acces la unul dintre aceste noduri.

    Puteți găzdui propriul nod folosind unul dintre mulți clienți Ethereum disponibili în prezent (Hyperledger Besu (client Java dezvoltat de ConsenSys), Geth (client Go), Parity (client Rust) etc.) – totuși, există un o parte din DevOps care vine cu găzduirea și întreținerea propriului nod Ethereum – mai ales dacă doriți să o faceți în mod fiabil! Ca atare, noi la ConsenSys am construit Infura – o ofertă de infrastructură Ethereum de clasă mondială. Infura are grijă de toată piesa de „gestionare a nodurilor”, oferindu-vă acces instant, fiabil și scalabil la clustere de noduri Ethereum! Vă puteți gândi la Infura ca la „Ethereum-nodes-as-a-Service” &# 128578;

    Noțiuni introductive despre Infura

    Pentru a începe cu Infura, va trebui să vă înregistrați un cont la infura.io. Nu vă faceți griji – este complet gratuit să începeți și nu va trebui să introduceți informații sensibile!

    Odată înregistrat, veți fi direcționat către o pagină care arată astfel:

    infuraLogin

    După cum sugerează această pagină, pentru a începe, veți selecta prima opțiune „Începeți și creați primul dvs. proiect pentru a accesa rețeaua Ethereum!”

    Puteți denumi proiectul oricum doriți – vom numi proiectul nostru „test-proiect”.

    InfuraNP

    Acum, vi se vor prezenta acreditările de care veți avea nevoie pentru a accesa nodurile Infura!


    InfuraC

    Păstrați această pagină deschisă! Vom reveni la el mai târziu &# 128578;

    Următorul lucru pe care îl vom face este să inițializăm un nou proiect Truffle. Dacă aveți nevoie de ajutor pentru instalarea Truffle, vă rugăm să consultați secțiunea anterioară a acestei documentații.

    Pentru a inițializa un nou proiect Truffle, creați un folder nou și rulați

    init trufe

    Apoi, veți dori să adăugați furnizorul Truffle HD Wallet la proiectul dvs. inițializat recent, astfel încât să vă puteți semna tranzacțiile înainte ca acestea să fie trimise către nodurile Infura. Fiecare modificare de stare pe care o efectuați asupra Ethereum vine sub forma unei tranzacții – fie că este vorba de implementarea unui contract, apelarea unei funcții în cadrul unui contract sau trimiterea unui token! Fiecare tranzacție trebuie să fie semnată de un cont – prin urmare, aplicația noastră are nevoie de capacitatea de a semna tranzacții, astfel încât să poată face modificări de stat la Ethereum!

    Fiecare tranzacție costă, de asemenea, eter. Acest cost al tranzacției este denumit „costul gazului”. Prin urmare, pentru ca tranzacțiile noastre semnate să fie procesate de rețea după ce acestea sunt trimise către nodurile Infura, va trebui să ne finanțăm contul cu eter. Vom acoperi acest lucru puțin mai târziu, dar acesta este doar un alt motiv important pentru care veți avea nevoie de un portofel & furnizor de portofele!

    Pentru a adăuga furnizorul Truffle HD Wallet la tipul de proiect nou inițializat din terminal:

    npm install –save @ truffle / hdwallet-provider

    Acest lucru poate genera unele avertismente, dar atâta timp cât se instalează, sunteți bine să mergeți!

    Acum putem crea un cont Ethereum pentru a fi utilizat de aplicația noastră! Deoarece furnizorul nostru de portofel este un portofel HD (ierarhic determinist), putem genera deterministic conturi utilizând aceeași frază de bază sau mnemonică.

    Pentru a ne crea contul, va trebui mai întâi să pornim Ganache. Ganache este un produs Truffle care ne permite să ne creăm cu ușurință propria rețea de dezvoltare locală. Pentru a rula ganache, pur și simplu tastați

    ganache-cli

    Dacă ați finalizat Pasul 2 din acest ghid, ar trebui să aveți deja instalat Ganache / ganache-cli – dacă nu, îl puteți instala folosind comanda npm:

    npm install -g ganache-cli

    Sau dacă utilizați fire 

    yarn global add ganache-cli

    Apoi, va trebui să permitem aplicației noastre să vorbească cu Ganache. Accesați directorul de proiect și verificați fișierul truffle-config.js, pur și simplu decomentați (sau adăugați) următoarele linii din rețea:

    dezvoltare: {host: "127.0.0.1", // Localhost (implicit: none) port: 8545, // Port standard Ethereum (implicit: none) network_id: "*" // Orice rețea (implicit: niciuna)},

    neobișnuit

    Grozav! Acum aplicația noastră poate vorbi cu rețeaua noastră de dezvoltare Ganache care rulează la 127.0.0.1:8545! Acum, într-o fereastră de terminal nouă (dar totuși în folderul proiectului), rulați comanda

    consolă de trufe

     pentru a vă conecta la rețeaua dvs. Ganache. Nu vă faceți griji – ne vom conecta la o rețea publică mai târziu! Trebuie doar să ne conectăm la Ganache chiar acum pentru a ne crea cheile &# 128578;

    Notă: dacă întâmpinați probleme, asigurați-vă că în Ganache numărul portului RPC Server se potrivește cu fișierul de configurare al trufei. În cazul implicit, 8545 ar trebui să funcționeze, altfel modificați fișierul de configurare pentru a se potrivi cu Ganache.

    Acum introduceți următoarele comenzi în consola Truffle pentru a vă crea portofelul:

    const HDWalletProvider = require (‘@ truffle / hdwallet-provider’);

    Acest lucru ar trebui să ducă la un răspuns de „nedefinit”

    Pentru mnemonica dvs. de 12 cuvinte, puteți utiliza un generator mnemonic, cum ar fi Aceasta dacă doriți!

    ASIGURAȚI-VĂ CĂ VĂ SALVAȚI FRAZA MNEMONICĂ (SEMINȚĂ)! Vom avea nevoie mai târziu &# 128515;

    Apoi, adăugați următoarea comandă în terminalul dvs. (încă în curs de dezvoltare a trufelor):

    const mnemonic = ’12 cuvinte aici ‘; portofel const = new HDWalletProvider (mnemonic, "http: // localhost: 8545");

    Acum, în consola de trufe, introduceți comanda 

    portofel

    Dacă derulați în sus, ar trebui să vedeți o listă de conturi, ca aceasta!

    addy

    În ciuda faptului că acel cont a fost generat în timp ce am fost conectați la Ganache, putem folosi aceleași conturi Ethereum în orice rețea Ethereum (vă rugăm să rețineți, totuși – deși același cont poate fi utilizat în orice rețea Ethereum, activele / activitățile aferente acelui cont conturile sunt specifice rețelei – de exemplu, dacă fac o tranzacție pe Ethereum Mainnet, tranzacția respectivă va avea loc numai pe Ethereum Mainnet și nicio altă rețea). Acum vom opri interacțiunea cu Ganache (rețea locală de dezvoltare) și vom începe să folosim acel cont pentru a interacționa cu unele rețele publice!!

    De obicei, primul lucru pe care trebuie să îl faci atunci când interacționezi cu o rețea publică este să obții o parte din eterul acelei rețele. În cazul nostru, ne vom conecta la rețeaua publică de testare Ropsten, așa că va trebui să obținem niște eter Ropsten (ETH)! Nu vă faceți griji – testul ETH net este gratuit și generos și foarte ușor de obținut &# 128077;

    Timpul pentru obținerea testului ETH

    Pentru a obține ceva Ropsten ETH, mergeți la Robinet Ropsten. Inserați adresa contului și viola! Ați primit câteva Ropsten ETH și puteți începe să trimiteți tranzacții (adică să efectuați modificări de stare) rețelei Ropsten!

    Pentru referință, rețeaua de testare Ropsten este o rețea publică de testare Ethereum, unde puteți testa codul într-un mediu care reflectă îndeaproape cel al rețelei principale Ethereum. Principala diferență între rețeaua de testare Ropsten (și celelalte plase publice de testare Ethereum) este că în testnet-land, ETH este abundent și nu are valoare din lumea reală! Când începeți să interacționați cu rețeaua principală Ethereum, eterul pe care îl utilizați pentru a plăti tranzacțiile dvs. (costurile cu gazul) va costa dolari REALI – așa că trebuie să ne asigurăm că facem lucrurile corect înainte, astfel încât să nu ne pierdem din greu – bani câștigați / prețioasa noastră rețea ETH!

    Rețeaua de testare Ropsten, împreună cu majoritatea celorlalte rețele publice de testare, are mulți exploratori de blocuri pentru a vizualiza activitatea care se desfășoară în lanț (https://ropsten.etherscan.io/). Pentru a vedea contul finanțat, lipiți pur și simplu adresa contului în explorator – și puteți vizualiza tot istoricul asociat acestuia:

    Captură de ecran 2020 09 01 la 4 34 21 AM

    Bine! Acum că avem furnizorul nostru de portofel și un cont finanțat cu Ropsten ETH, ne putem îndrepta spre proiectul nostru și îl putem îndrepta către nodurile Infura conectate la rețeaua de testare Ropsten.

    Primul lucru pe care vom dori să-l facem este să creăm un fișier a.env pentru a adăposti prețioasele noastre SECRETE! Aceste secrete includ cheia API Infura (generată când ne-am creat contul Infura) și fraza noastră mnemonică.

    La nivelul rădăcină al proiectului dvs., pur și simplu creați un nou fișier „.env”. De asemenea, va trebui să instalați pachetul dotenv NPM introducând următoarea comandă în terminal

    npm install –salvare dotenv

    În acest fișier new.env, veți avea nevoie de două lucruri:

    INFURA_API_KEY = INSERAȚI CHEIA API AICI (fără cotații)

    MNEMONIC = „lentilă balenă ventilator balon fir scaun online expune numărul câștigător teză propoziție”

    INFURA_API_KEY este ID-ul proiectului din proiectul pe care l-ați creat anterior în infura:

    Captură de ecran 2020 09 01 la 4 37 12 AM

    Și MNEMONIC este sintagma de 12 cuvinte pe care ați folosit-o anterior pentru a vă genera contul.

    Fișierul dvs. ar trebui să arate acum:

    Captură de ecran 2020 09 01 la 4 41 53 AM

    Bine, ne apropiem!

    NOTĂ: Dacă aveți de gând să împingeți acest lucru într-un depozit Github sau să faceți public acest proiect în vreun fel, ASIGURAȚI-vă că fișierul dvs..env este în.gitignore, astfel încât secretele dvs. să nu fie expuse! 

    Acum, va trebui să ne îndreptăm către fișierul truffle-config.js. Aici, va trebui să adăugăm câteva lucruri pentru a indica furnizorul nostru (care este folosit pentru a interacționa cu Infura (furnizorul de trufe HDWallet pe care l-am instalat anterior) și să ne îndreptăm aplicația spre nodurile Ropsten Infura.

    În partea de sus a fișierului, adăugați:

    necesita ("dotenv") .config (); const HDWalletProvider = require ("@ furnizor de trufe / hdwallet");

    Apoi, sub „rețele”, veți dori să adăugați următoarea rețea:

    ropsten: {furnizor: () => nou HDWalletProvider (process.env.MNEMONIC, `https://ropsten.infura.io/v3/$ {process.env.INFURA_API_KEY}`), network_id: 3, // ID-ul gazului Ropsten: 5500000, // Ropsten are un limită de bloc mai mică decât confirmările mainnet: 2, // # de confs pentru a aștepta între implementări. (implicit: 0) timeout Blocks: 200, // # de blocuri înainte de expirarea unei implementări (minim / implicit: 50) skipDryRun: true // Omiteți rularea uscată înainte de migrări? (implicit: fals pentru rețelele publice)}

     

    Acum, fișierul dvs. truffle-config.js ar trebui să arate cam așa!

    Notă marginală:

    Dacă utilizați puncte finale Infura, parametrul „de la” este necesar, deoarece acestea nu au un portofel. Dacă utilizați puncte finale Ganache sau Geth RPC, acesta este un parametru opțional.

    Captură de ecran 2020 09 01 la 4 50 54 AM

    ACUM SUNTEM GATA DE MAGIE! Este timpul să implementați un contract inteligent pentru ROPSTEN!

    Configurarea unui contract inteligent

    Configurare soliditate

    În primul rând, vom dori să creăm un contract inteligent de implementat! Puteți prelua contractul inteligent pe care l-ați dezvoltat în secțiunea anterioară a acestui ghid, puteți construi propriul dvs. contract inteligent sau pur și simplu utilizați următorul exemplu de contract (extrem de simplu):

    soliditatea pragmatică >= 0,5,8; contract SimpleStorage {uint256 storedData; set de funcții (uint256 x) public {storedData = x; } function get () public view return (uint256) {return storedData; }}

    Acest contract ar trebui creat ca un fișier „.sol” (Soliditate) în dosarul „contracte” al proiectului dvs. (în acest scenariu, am creat fișierul SimpleStorage.sol, care este contractul nostru SimpleStorage:

    schele

    Configurarea migrării

    Apoi, va trebui să configurăm fișierul nostru de migrare!

    Migrațiile sunt fișiere JavaScript care vă ajută să implementați contracte în rețeaua Ethereum. Aceste fișiere sunt responsabile pentru organizarea sarcinilor de implementare și sunt scrise în ipoteza că nevoile dvs. de implementare se vor schimba în timp. Pe măsură ce proiectul dvs. evoluează, veți crea noi scripturi de migrare pentru a continua această evoluție pe blockchain. Un istoric al migrațiilor efectuate anterior este înregistrat pe lanț printr-un contract special de migrații. Puteți găsi mai multe informații despre ele Aici.

    Fișierul nostru de migrare pentru a ne implementa contractul va arăta astfel:

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

    Salvați acest fișier în folderul „migrații” sub numele „2_deploy_contracts.js”.

    Implementarea primului dvs. contract public

    E timpul să migrez

    Acum sunteți de fapt gata pentru ca MAGIA să se ÎNTÂMPLE! Mergeți înapoi la consolă și tastați

    trufe migrează – rețea ropsten

    Boom!&# 128163; Codul dvs. a fost implementat pe rețeaua publică Ropsten Ethereum Test Net!!! 

    Ceea ce tocmai s-a întâmplat a fost:

    1. Contractul dvs. inteligent Solidity (în folderul „contracte”) a fost compilat până la bytecode – codul care poate fi citit de mașină pentru ca mașina virtuală Ethereum să o poată utiliza.

    2. Acest bytecode, + alte date, a fost grupat într-o tranzacție.

    3. Acea tranzacție a fost semnată de contul dvs..

    4. Acea tranzacție a fost trimisă nodului Infura care este conectat la Ropsten.

    5. Tranzacția a fost propagată în întreaga rețea, preluată de un miner Ropsten și inclusă într-un bloc Ropsten.

    6. Contractul dvs. inteligent este acum LIVE pe blockchain-ul Ropsten!

    Puteți vizualiza contractul dvs. folosind Etherscan: https://ropsten.etherscan.io/ – pur și simplu lipiți adresa contractului (ar trebui să fie în terminalul dvs.) pentru a o vizualiza!

    Captură de ecran 2020 09 01 la 5 19 12 AM

    Uimitor! Tocmai am implementat primul nostru contract inteligent într-o rețea publică Ethereum! &# 129327;

    Procesul este exact același pentru implementarea pe Ethereum mainnet, cu excepția faptului că veți schimba rețeaua în fișierul truffle-config.js pentru Ethereum mainnet (și, desigur, rulați comanda de migrare mainnet Truffle în locul celei Ropsten) ! Nu vă vom ajuta să parcurgeți acest proces aici, deoarece implementarea pe rețeaua principală Ethereum vă va costa $ reali – dar dacă doriți asistență în acest sens, treceți la Discordia ConsenSys și am fi mai mult decât fericiți să vă ajutăm!

    Construirea unui frontend Web3 

    Acum că ne-am desfășurat contractul către Ropsten, să construim o interfață simplă pentru utilizator pentru a interacționa cu acesta!

    Notă: „front-end-urile” dApp sunt doar front-end-urile dvs. obișnuite, obișnuite – ca atare, putem folosi toate instrumentele noastre vechi cu care suntem familiarizați (create-react-app etc.) pentru a ne învârti și apoi adăugați doar câteva lucruri pentru a permite frontului să citească și să scrie către Ethereum! Aceasta înseamnă că toate vechile abilități de web dev sunt direct transferabile către Ethereum-land / Web3!!

    Întindeți proiectul nostru React 

    Bine, să începem.

    Mai întâi asigurați-vă că aveți un director care conține toate informațiile pe care tocmai le-am făcut pentru contractul nostru de stocare. Mi-am numit folderul „stocare înapoi” și conține lucrările pe care tocmai le-am finalizat pentru a ne configura și implementa contractul. 

    Captură de ecran 2020 09 01 la 5 26 33 AM

    Acum vom începe prin lansarea unui proiect de reacție, să-l numim pe al nostru în acest exemplu „stocare-laborator”

    În terminalul nostru să rulăm următoarele pentru a începe proiectul nostru 

    npx create-react-app storage-lab

    Acum că avem noul nostru cazan de proiect, să mergem în directorul proiectului

    laborator de stocare cd

    Acum că ne aflăm în interiorul proiectului nostru, vom adăuga acum pachetul Web3, care va permite proiectului nostru să interacționeze cu Ethereum! Mai multe pe web3 Aici

    npm instalați web3

    Web3 este unul dintre cele două pachete majore pe care le putem folosi, celălalt fiind ethers.js. Pentru acest exemplu vom folosi web3, dar dacă doriți să citiți mai multe despre ethers.js, aruncați o privire Aici 

    Pentru o explicație detaliată a celor două, aruncați o privire la această scriere web3 vs eteri

    Grozav! Acum suntem aproape gata să avem proiectul nostru de reacție interacționând cu contractul nostru!

    În primul rând, să luăm directorul nostru de mai devreme (pentru mine este „stocare înapoi”) care conține doar munca pe care am făcut-o deja în ceea ce privește contractele noastre inteligente și acum să adăugăm acest lucru la noul nostru proiect de reacție. Acest lucru va trăi la același nivel cu src-ul nostru și acum ar trebui să avem tot ceea ce avem nevoie împreună în cadrul REPO-ului nostru de reacție.

    Captură de ecran 2020 09 01 la 5 31 38 AM

    Apoi, va trebui să configurăm fișierul nostru care conține informațiile ABI.

    „ABI?”

    Mă bucur că ai întrebat! 

    Interfața binară de aplicare a contractului (ABI) este modalitatea standard de a interacționa cu contractele din ecosistemul Ethereum, atât din afara blockchain-ului, cât și pentru interacțiunea contract-la-contract. Când am compilat contractul nostru SimpleStorage într-un pas anterior, acesta a creat un fișier JSON pentru noi. Verificați-vă singur, avem un fișier SimpleStorage.json în cadrul construcției / contractelor noastre

    Captură de ecran 2020 09 01 la 6 04 20 AM

    O privire inițială asupra acestui fișier va dezvălui o mulțime de informații, în acest moment trebuie doar să ne concentrăm asupra ABI pentru a ne sincroniza contractul cu front-end-ul pe care îl dezvoltăm. Acest JSON conține informațiile de care avem nevoie pentru a comunica contractul nostru cu front end-ul nostru.

    ABI-ul nostru este un tablou care conține obiecte. Privind mai atent fișierul, puteți vedea că fiecare dintre aceste obiecte sunt de fapt fiecare funcție pe care o conține contractul nostru SimpleStorage.

    Captură de ecran 2020 09 01 la 5 33 23 AM

    Puteți vedea rapid

    „Nume”: „set”

    „Nume”: „obține”

    ambele cu un „tip:„ funcție ”ambele funcții pe care le-am declarat atunci când am scris contractul nostru inteligent!

    Deși Truffle ascunde următorii pași, vom parcurge un mod mult mai „manual” de a face lucrurile, astfel încât să fiți expus la toate elementele de bază &# 128578;

    Mai întâi, continuați și copiați informațiile dvs. abi – vom avea nevoie de ele într-o clipă. 

    Să creăm un folder în interiorul src-ului nostru numit „abi”.

    În interiorul dosarului nostru abi recent creat, să facem acum un fișier numit abi.js

    Notă: Nu este necesar din punct de vedere tehnic să avem această separare și am putea adăuga doar abi.js la src, dar păstrarea fișierelor abi.js conținute ajută la organizare.

    Acum vom copia matricea abi pe care am luat-o mai devreme din fișierul SimpleStorage.JSON și o vom adăuga în fișierul abi.js nou creat. Vom schimba puțin fișierul pentru a permite proiectului nostru să importe informațiile în App.js. Nu uitați, deoarece acesta este un fișier a.js, trebuie să adăugăm un export, astfel încât să avem posibilitatea să îl extragem în app.js mai târziu. Să numim const același lucru ca și contractul, cu excepția camelcasei (a se vedea codul de mai jos):

    Acesta va fi codul pe care îl stocăm în fișierul nostru abi.js

    export const SimpleStorage = [{constantă: falsă, intrări: [{nume: "X", tip: "uint256", }, ], Nume: "a stabilit", ieșiri: [], de plătit: fals, stateMutabilitate: "neplătibil", tip: "funcţie", }, {constant: true, intrări: [], nume: "obține", ieșiri: [{nume: "", tip: "uint256", },], de plătit: fals, stareMutabilitate: "vedere", tip: "funcţie", },];

    Este timpul să vă îndreptați către App.js și să importați atât web3, cât și fișierul nostru abi.js proaspăt creat.

    De asemenea, vom folosi cârlige în acest exemplu (motiv pentru care importăm și {useState} puteți citi mai multe despre useState Aici.

    Partea de sus a fișierului nostru App.js ar trebui să arate acum:

    import React, {useState} din "reacţiona"; import {simpleStorage} din "./ abi / abi"; import Web3 din "web3"; import "./App.css";

    Acum trebuie să ne asigurăm că avem posibilitatea ca orice utilizator arbitrar să aibă capacitatea de a se conecta și de a folosi dApp-ul nostru, atâta timp cât au un furnizor de portofel.!

    Portofelul principal utilizat în spațiul Ethereum pentru interacțiunea dApp este MetaMask, introdus la Pasul 1.

    Dacă nu aveți MetaMask, vizitați metamask.io

    Cu MetaMask instalat, ne putem accesa portofelul din interiorul aplicației noastre cu:

    const web3 = new Web3 (Web3.givenProvider);

    „Web3.givenProvider” va fi setat într-un browser acceptat de Ethereum.

    (puteți citi mai multe despre motivul pentru care este necesar acest lucru Aici)

    Deci, acum codul nostru ar trebui să arate astfel:

    import React, {useState} din "reacţiona"; import {simpleStorage} din "./ abi / abi"; import Web3 din "web3"; import "./App.css"; const web3 = new Web3 (Web3.givenProvider);

    Bine! Până acum am:

    • Lansați un proiect React
    • Web3 instalat
    • S-a adăugat folderul nostru care conține construirea + contractul + migrarea la proiectul nostru React
    • Am creat un fișier abi.js care conține datele abi pe care le-am extras din SimpleStorage.json
    • Am importat datele de care avem nevoie pentru a interacționa cu contractul nostru
    • Am creat o variabilă care permite dApp-ului nostru să comunice cu portofelul utilizatorului

    Din nou, deși Truffle face următorii pași inutili (vă vom prezenta o versiune mult mai simplă mai târziu), vom adăuga ceva mai multă complexitate manuală dApp-ului nostru în scopuri educaționale.

    Ceea ce vom face acum este să creăm două variabile noi: una pentru a stoca adresa contractului pe care l-am desfășurat pe Ropsten și cealaltă pentru a potrivi acel contract cu ABI-ul nostru, astfel încât aplicația noastră să știe cum să vorbească cu acesta! 

    Pentru a localiza adresa contractului, navigați la fișierul JSON în care ne aflam anterior (care conține ABI (SimpleStorage.json)) și derulați în partea de jos. Adresa este în câmpul „adresă” aici:

    "compilator": { "Nume": "solc", "versiune": "0.5.8 + commit.23d335f2.Emscripten.clang" }, "rețele": { "3": { "evenimente": {}, "link-uri": {}, "abordare": "0x24164F46A62a73de326E55fe46D1239d136851d8", "transactionHash": "0x1f02006b451b9e85f70acdff15a01c6520e4beddfd93a20e88a9b702a607a7b0" }}, "schemaVersion": "3.0.16", "updatedAt": "2020-06-30T20: 45: 38.686Z", "devdoc": { "metode": {}}, "userdoc": { "metode": {}}}

    Alternativ, te-ai putea îndrepta spre https://ropsten.etherscan.io/ și căutați adresa contului care a desfășurat contractul! În Etherscan, făcând clic pe „Crearea contractului” se va expune adresa contractului în sine.

    Captură de ecran 2020 09 01 la 5 43 46 AM

    Acum vom lua copia adresei contractului dvs. și vom crea o nouă variabilă pentru a o stoca. 

    Fără aceasta, nu vom avea capacitatea de a comunica cu contractul, iar dApp-ul nostru nu va funcționa conform intenției.

    Veți adăuga acest lucru sub const web3 = new Web3 (Web3.givenProvider);

    const contractAddress = "adresa contractului dvs. aici";

    Apoi vom crea o altă variabilă nouă numită „storageContract” care va conține atât adresa contractului nostru (astfel încât aplicația noastră să știe unde este contractul), cât și ABI (astfel încât aplicația noastră să știe cum să interacționeze cu contractul).

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

    Aplicația noastră App.js ar trebui acum să arate astfel

    import React, {useState} din "reacţiona"; import {simpleStorage} din "./ abi / abi"; import Web3 din "web3"; import "./App.css"; const web3 = new Web3 (Web3.givenProvider); const contractAddress = "adresa contractului dvs. aici"; const storageContract = new web3.eth.Contract (simpleStorage, contractAddress);

    Acum trebuie să obținem cârligele noastre pentru a păstra variabile care vor interacționa cu contractul și front end-ul nostru. Vom face acest lucru declarând următoarele în funcția noastră de aplicație:

    import React, {useState} din "reacţiona"; import {simpleStorage} din "./ abi / abi"; import Web3 din "web3"; import "./App.css"; const web3 = new Web3 (Web3.givenProvider); const contractAddress = "adresa contractului dvs."; const storageContract = new web3.eth.Contract (simpleStorage, contractAddress); funcția App () {const [number, setUint] = useState (0); const [getNumber, setGet] = useState ("0");

    Prima noastră utilizare a useState (0) va deține uint256 pe care îl declară utilizatorul.

    (convențiile de numire a numărului, setUint, getNumber, setGet, sperăm să ajute să arate ce se întâmplă)

    valoarea useState („0”) acționează ca un substituent până când avem confirmarea acțiunii semnate (uint256 declarat)

    setUint vom apela în curând în întoarcere (mai multe despre asta mai târziu)

    Timp pentru logica noastră

    Apoi vom adăuga logica noastră NumberSet și NumberGet (adăugăm numberSet în funcția noastră App)

    const numberSet = async (t) => {t.preventDefault (); const accounts = await window.ethereum.enable (); const account = conturi [0]; const gas = așteaptă storageContract.methods.set (number) .estimateGas (); const post = await storageContract.methods.set (number) .send ({from: account, gas,}); }; număr const Obțineți = asincron (t) => {t.preventDefault (); const post = await storageContract.methods.get (). call (); setGet (post); };

    Am setat un preventDefault (au fost găsite detalii despre preventDefault Aici)

    De asemenea, folosim un apel asincronizat la get pentru contract (detalii despre asincronizare găsite Aici)

    Cârligul nostru setGet () stochează o valoare implicită pe care o vedem inițial („0”)

    const accounts = await window.ethereum.enable ();

    se asigură că apelăm adresa noastră conectată prin MetaMask.

    const account = conturi [0];

    Trage în contul de conectare

    S-ar putea să vă întrebați ce se întâmplă 

    const gas = așteaptă storageContract.methods.set (number) .estimateGas ();

    Aplicația noastră are nevoie de permisiunea de a accesa fondurile utilizatorilor pentru a plăti taxele de gaz, orice funcție solicită eter, indiferent dacă este pe testnet sau mainnet. Aici este utilă conexiunea noastră cu MetaMask pentru a semna această utilizare pentru a ne seta uint256 și a plăti pentru aceasta (cu testul ETH).

    Deci, pentru orice funcție care are nevoie de gaz, trebuie să calculați gazul potențial utilizat.

    Funcția „Set” a contractului nostru necesită benzină

    „Obțineți” nu.

    (asta pentru că „Obțineți” vizualizează ceea ce a fost deja declarat cu „Set”)

    const post va prelua trecerea în uint256, confirmați tranzacția (după plata taxei de gaz) din portofelul MetaMask din rețeaua Ropsten.

    Apoi trecem parametrii funcțiilor prin methods.set () și cu adresa noastră declarată (adresa utilizatorilor) vom gestiona apoi funcția Set.

    Ne creăm tranzacția cu contract inteligent trecând parametrii funcției noastre la metodele contractului inteligent.set () și adresa estimată a gazului și a contului de utilizator la.send ().

    const post = await storageContract.methods.set (number) .send ({from: account, gas,});

    Aceasta ar trebui să fie toată logica de care avem nevoie pentru a acoperi numărul nostru.

    Acum avem nevoie de numărul nostru

    număr const Obțineți = asincron (t) => {t.preventDefault (); const post = await storageContract.methods.get (). call (); setGet (post); };

    Postul nostru const ne recuperează numărul setat și setGet trece în noua valoare pe care am declarat-o

    Deci, „0” nostru va face clic pe numărul nostru Obțineți și redați unint256!

     Deci, acum app.js ar trebui să arate astfel

    import React, {useState} din "reacţiona"; import {simpleStorage} din "./ abi / abi"; import Web3 din "web3"; import "./App.css"; const web3 = new Web3 (Web3.givenProvider); const contractAddress = "adresa contractului dvs."; const storageContract = new web3.eth.Contract (simpleStorage, contractAddress); funcția App () {const [number, setUint] = useState (0); const [getNumber, setGet] = useState ("0"); const numberSet = async (t) => {t.preventDefault (); const accounts = await window.ethereum.enable (); const account = conturi [0]; const gas = așteaptă storageContract.methods.set (number) .estimateGas (); const post = await storageContract.methods.set (number) .send ({from: account, gas,}); }; număr const Obțineți = asincron (t) => {t.preventDefault (); const post = await storageContract.methods.get (). call (); setGet (post); };

    Să creăm un randament foarte simplu pentru a reda, astfel încât să putem testa dacă putem 

    • setați o valoare unint256,
    • Trageți în sus portofelul metamask și confirmați tranzacția
    • Plătiți costul gazului
    • apoi obțineți valoarea (unint256) stocată după finalizarea tranzacției.

    Întoarcerea noastră arată astfel: 

    return (Setați uint256: setUint (t.target.value)} /> A confirma

    Obțineți uint256 {getNumber}); } exportați aplicația implicită;

    Câteva CSS rapide

    Să trecem acum la fișierul App.css, să ștergem codul plăcii centralei și să-l adăugăm în schimb

    .main {text-align: center; display: flex; justify-content: centru; culoare de fundal: # f2f1f5; înălțime: 100vh; } .card {min-înălțime: 50vh; lățime: 50vw; display: flex; direcție flexibilă: coloană; align-items: centru; justify-content: centru; } .form {înălțime: 20vh; lățime: 20vw; display: flex; justify-content: spațiu uniform; direcție flexibilă: coloană; } .button {width: 20vw; înălțime: 5vh; }

    Acum suntem gata să testăm!

    În terminalul dvs. rulează

    firul începe

    În localhost-ul nostru: 3000 ar trebui să arătăm așa

     

    Captură de ecran 2020 09 01 la 6 12 49 AM

    Acum ar trebui să putem introduce o valoare unint256 în câmpul nostru de intrare!

    După ce ne confirmăm numărul în dApp, semnăm prin MetaMask (Asigurați-vă că portofelul dvs. este setat la rețeaua Ropsten)

    confrim1

    Am reusit! &# 129303;

    Acum avem contractul nostru inteligent conectat la un front-end și avem capacitatea de a manipula funcția Set (cu condiția să avem testul ETH pentru a plăti taxa de gaz pentru tranzacție). Apoi putem apela la funcția Obține și am recuperat valoarea uint265 stocată.

    Destul de cool huh!?!

    Styling suplimentar 

    Acum este timpul să arătăm cât de ușor poate fi implementarea tehnologiei Web2 și mai populare în proiectul nostru.

    Vom folosi MUI pentru a adăuga un stil de bază, dacă dezvoltați deja cu React s-ar putea să fiți familiarizați cu material-ui. (Detalii găsite Aici) Material-UI sau MUI pe scurt este un cadru React foarte popular care vă permite să derulați rapid un proiect cu o mulțime de stiluri gătite, cu condiția să respectați convențiile de numire. De asemenea, este foarte ușor de manipulat dacă doriți să utilizați doar o bază de ten și să personalizați de acolo.

    * Acesta va fi un exemplu foarte scurt despre cum să adăugați MUI la un proiect cu mici adăugiri pentru a demonstra cât de repede puteți încorpora proiectul nostru așa cum este acesta cu o tehnologie Web2. 

    Adăugarea MUI

    Vom începe prin rularea comenzii (încă în directorul nostru de proiecte din terminal (dacă aplicația rulează în continuare, va trebui să o închideți (ctrl + c) sau să deschideți o filă nouă)):

    Pentru a instala cu npm:

    npm instalați @ material-ui / core

    Sau cu fire:

    fire add @ material-ui / core

    Acum că am injectat MUI vom începe cu schimbarea stilului nostru. În partea de sus a fișierului nostru app.js vom importa câteva lucruri noi:

    import {simpleStorage} din "./ abi / abi"; import Butonul din "@ material-ui / core / Button"; import TextField din "@ material-ui / core / TextField"; importați {makeStyles} din "@ material-ui / core / styles";

    Importul de {makeStyles} ne permite să manipulăm stilul (în acest caz) butoanele și câmpul de text împreună cu importarea stilului MUI implicit. 

    Vom face acum o variabilă (deasupra funcției noastre) care aduce stilul boilerplate de la MUI

    const useStyles = makeStyles ((theme) => ({rădăcină: { "& > *": {margin: theme.spacing (1),},},}));

    Acum, în funcția noastră de aplicație, vom adăuga și o variabilă numită „clase” care trage în stilurile definite pe care tocmai le-am declarat mai sus.

    funcția App () {const class = useStyles (); const [număr, setUint] = useState (0); const [getNumber, setGet] = useState ("0");

    Acum vom face ajustări în cadrul întoarcerii noastre pentru a înlocui unele dintre câmpurile noastre cu ceea ce tocmai am importat.

    return (setUint (t.target.value)} variant ="conturat" /> A confirma

    Obțineți uint256 {getNumber}); } exportați aplicația implicită;

    Codul dvs. ar trebui să arate acum

    import React, {useState} din "reacţiona"; import {simpleStorage} din "./ abi / abi"; import Web3 din "web3"; import "./App.css"; importați {makeStyles} din "@ material-ui / core / styles"; import Butonul din "@ material-ui / core / Button"; import TextField din "@ material-ui / core / TextField"; const useStyles = makeStyles ((theme) => ({rădăcină: { "& > *": {margin: theme.spacing (1),},},})); const web3 = new Web3 (Web3.givenProvider); const contractAddress = "adresa contractului dvs. aici"; const storageContract = new web3.eth.Contract (simpleStorage, contractAddress); funcția App () {const class = useStyles (); const [număr, setUint] = useState (0); const [getNumber, setGet] = useState ("0"); const numberSet = async (t) => {t.preventDefault (); const accounts = await window.ethereum.enable (); const account = conturi [0]; const gas = așteaptă storageContract.methods.set (number) .estimateGas (); const post = await storageContract.methods.set (number) .send ({from: account, gas,}); }; număr const Obțineți = asincron (t) => {t.preventDefault (); const post = await storageContract.methods.get (). call (); setGet (post); }; return (setUint (t.target.value)} variant ="conturat" /> A confirma

    Obțineți uint256 {getNumber}); } exportați aplicația implicită;

    Acum, dacă ne uităm la proiectul nostru de reacție, ar trebui să arate așa!

    Captură de ecran 2020 09 01 la 6 48 55 AM

    Foarte bine!

    Avem în continuare toate funcționalitățile de până acum și acum am injectat un cadru ușor de utilizat pentru a ne personaliza în continuare proiectul oricum dorim. Aruncați o privire la MUI documentație să experimentați cu propriile dvs. adăugiri / modificări!

    Runda bonus 

    Ar fi frumos să arătăm utilizatorilor adresa de conectare din dApp-ul nostru, nu-i așa??

    Ei bine, să facem o componentă foarte rapidă și de bază pentru a face exact asta!

    Vom începe prin a crea o componentă separată pe care o putem importa înapoi în fișierul nostru App.js. Este o idee bună să ne separăm logica pentru a ne menține App.js ușor de navigat, dar și pentru a urma practica unei componente, în mod ideal făcând un singur lucru. Dacă ajunge să crească, ar trebui descompus în subcomponenți mai mici.

    Construirea componentelor 

    Vom crea un nou folder numit componente la același nivel cu src-ul nostru și în acel folder vom crea un fișier Nav.js. Schela proiectului nostru ar trebui să arate acum așa ceva

    Captură de ecran 2020 09 01 la 6 47 07 AM

    De asemenea, vom crea un fișier Nav.css în dosarul componentelor noastre pentru a importa orice stiluri pe care le aplicăm în mod specific componentei Nav.

    Să deschidem Nav.js-ul nostru și să importăm fișierele React, Web3 și empty.css

    import React de la "reacţiona"; import Web3 din "web3"; import "./Nav.css"

    Acum vom crea o clasă numită Nav și vom adăuga doar câteva lucruri în cadrul său pentru a afișa adresa noastră conectată. Vom începe prin stabilirea stării noastre pentru a citi contul

    clasa Nav extinde React.Component {state = {account: "" };

    Încă în clasa noastră vom încărca contul din care să citim adăugând logica noastră loadAccount asincronizată

    async loadAccount () {const web3 = new Web3 (Web3.givenProvider || "http: // localhost: 8080"); const network = await web3.eth.net.getNetworkType (); const accounts = await web3.eth.getAccounts (); this.setState ({account: accounts [0]}); }

    În continuare, vom crea un componentDidMount (care va fi invocat imediat după montarea componentei) În cazul nostru, extragerea contului încărcat. Citeste mai mult Aici

    componentDidMount () {this.loadAccount (); }

    Notă marginală:

    Acest lucru se poate face diferit, în loc de o clasă putem crea o funcție și putem folosi cârlige opuse componentDidMount, dar de dragul acestui exemplu vom rămâne la această metodă.

    Vom crea apoi o randare deasupra randamentului nostru, randarea este o metodă care este necesară atunci când scrieți o componentă React folosind o metodă de clasă. În cadrul returului nostru adăugăm o clasă de adresă divului nostru (pentru a da stilul de bază mai târziu) de-a lungul unei etichete p pentru a afișa adresa conectată pe care o preluăm folosind {this.state.account}

    render () {return (Adresa dvs. conectată: {this.state.account}); }} export Nav implicit;

    Fișierul nostru Nav.js ar trebui să arate acum astfel

    import React de la "reacţiona"; import Web3 din "web3"; import "./Nav.css" clasa Nav extinde React.Component {state = {account: "" }; async loadAccount () {const web3 = new Web3 (Web3.givenProvider || "http: // localhost: 8080"); const network = await web3.eth.net.getNetworkType (); const accounts = await web3.eth.getAccounts (); this.setState ({account: accounts [0]}); } componentDidMount () {this.loadAccount (); } render () {return (Adresa dvs. conectată: {this.state.account}); }} export Nav implicit;

     

    Să ne îndreptăm către fișierul Nav.css și să adăugăm un stil foarte simplu

    .adresa {display: flex; justify-content: centru; }

    Din punct de vedere tehnic, puteți adăuga acest lucru la fișierul App.css, rețineți, deși destul de repede, care ar putea deveni dezordonat. Componentele ar trebui să fie reutilizabile și pentru a evita cât mai multe fricțiuni posibil, compartimentându-vă munca, vă poate economisi dureri de cap pe drum.

    Acum, să ne întoarcem la App.js și să importăm componenta nou creată și să ne asigurăm că o adăugăm la întoarcerea noastră pentru a o afișa!

    Fișierul nostru App.js terminat ar trebui să arate astfel

    import React, {useState} din "reacţiona"; import {simpleStorage} din "./ abi / abi"; import Web3 din "web3"; import Nav din "./components/Nav.js"; import "./App.css"; importați {makeStyles} din "@ material-ui / core / styles"; import Butonul din "@ material-ui / core / Button"; import TextField din "@ material-ui / core / TextField"; const useStyles = makeStyles ((theme) => ({rădăcină: { "& > *": {margin: theme.spacing (1),},},})); const web3 = new Web3 (Web3.givenProvider); const contractAddress = "adresa ta aici"; const storageContract = new web3.eth.Contract (simpleStorage, contractAddress); funcția App () {const class = useStyles (); const [număr, setUint] = useState (0); const [getNumber, setGet] = useState ("0"); const numberSet = async (t) => {t.preventDefault (); const accounts = await window.ethereum.enable (); const account = conturi [0]; const gas = așteaptă storageContract.methods.set (number) .estimateGas (); const post = await storageContract.methods.set (number) .send ({from: account, gas,}); }; număr const Obțineți = asincron (t) => {t.preventDefault (); const post = await storageContract.methods.get (). call (); setGet (post); }; întoarcere ( setUint (t.target.value)} variantă ="conturat" /> A confirma

    Obțineți uint256 {getNumber}); } exportați aplicația implicită;

    Acum ar trebui să vedem adresa noastră conectată sus și să păstrăm în continuare toate funcționalitățile noastre!

    bonusV1

    &# 127881; Am reusit! &# 127881;

    Acum avem un dApp pe care l-am construit de la bază. Am tras contractul nostru inteligent într-un proiect React, am scris logică pentru a ne asigura că avem funcționalitatea utilizatorului, am creat o componentă pentru a reda adresa conectată și am adăugat chiar și un cadru de stil popular pentru proiectul nostru.

    Foarte bine! Acesta este doar începutul pentru aventurile dvs. de dezvoltare Web3 și aveți deja ceva de arătat că nu numai că ați creat, ci și că vă înfășurați capul. Contactați-ne în Discord și împărtășiți-ne proiectul (mai ales dacă ați făcut modificări sau adăugiri) cu noi!

      Onboarding pentru dezvoltatori: Pasul 1Onboarding pentru dezvoltatori Pasul 1

      Onboarding pentru dezvoltatori: Pasul 1

      Onboarding pentru dezvoltatori: Pasul 2Onboarding pentru dezvoltatori Pasul 2

      Onboarding pentru dezvoltatori: Pasul 2

      Orientare Ethereum de 10 minuteOrientare Ethereum de 10 minute

      Orientare Ethereum de 10 minute
    Mike Owergreen Administrator
    Sorry! The Author has not filled his profile.
    follow me
    Like this post? Please share to your friends:
    Adblock
    detector
    map