Web3 è stato di tendenza dall’inizio del 2022, proprio come gli NFT stavano esplodendo l’anno scorso.
Tuttavia, l’idea di creare app decentralizzate per casi d’uso mainstream come Facebook, Instagram e Google è stata una lunga ambizione della comunità crittografica. Tuttavia, mentre alcune aziende blockchain hanno già sviluppato alcune DApp, l’industria Web3 ha iniziato solo di recente a guadagnare popolarità. In questo articolo, creeremo un sistema di monitoraggio delle adozioni per un negozio di animali su Ethereum da zero.
Indice dei contenuti:
Sommario (TL;DR)
- Web3 è stato di tendenza dall’inizio del 2022, proprio come gli NFT stavano esplodendo l’anno scorso.
- Non è richiesta una precedente esperienza in strumenti di sviluppo Solidity e Blockchain come Ganache, Truffle ecc.
- Una DApp è un’applicazione software che opera su una rete distribuita.
- Dobbiamo installare VS Code, NodeJS, Git, Truffle e Ganache.
- Successivamente, imposteremo il nostro ambiente di sviluppo utilizzando la Truffle Box, cioè il pet-shop.
- Il prossimo passo è creare un contratto intelligente utilizzando la solidità.
- Compileremo il contratto intelligente utilizzando il comando truffle compile e poi lo migreremo utilizzando il comando truffle migrate.
- Creeremo un file TestAdoption.sol per testare il nostro contratto intelligente insieme al comando di test del tartufo.
- Creeremo un’interfaccia utente con Web3.js e un po ‘di codice esistente nella scatola del tartufo.
- Infine, interagiremo con la nostra DApp usando MetaMask e Ganache.
Dichiarazione del problema
Prendiamo l’esempio di Pete. Pete è proprietario di un negozio di animali a Nuova Delhi, in India.
Come possiamo vedere, la tecnologia Blockchain e la criptovaluta stanno guadagnando l’accettazione mainstream. Il 1 ° febbraio 2022, il ministro delle finanze Nirmala Sitharaman ha annunciato che la Reserve Bank of India avrebbe emesso una rupia digitale utilizzando la tecnologia Blockchain a partire dal 2022-23. Questo è un passo positivo nella direzione dell’adozione delle criptovalute. Ora l’India ha riconosciuto la tecnologia Blockchain.
Quindi Pete è anche interessato a utilizzare la tecnologia Blockchain. Vuole usare la tecnologia Blockchain per il suo negozio. Dopo aver fatto qualche ricerca da solo, Pete è affascinato da Ethereum Blockchain e dall’idea degli Smart Contracts. È interessato a usarlo per gestire le adozioni di animali domestici in modo più efficiente. La sua attività può ospitare fino a 16 animali domestici in qualsiasi momento. Ha già un database di animali domestici pronto. Pete vuole che qualcuno crei una DApp per lui.
L’obiettivo della DApp è quello di collegare un indirizzo Ethereum con un animale domestico da adottare.
Questo è un esempio di come appare una tipica dichiarazione di problema in un’azienda Blockchain. Ora, passiamo al passaggio successivo.
Prerequisiti
Questo articolo è destinato a persone che hanno una conoscenza di base di Ethereum e Smart Contracts. Se non hai conoscenze precedenti su Ethereum, inizia da qui.
Una certa esperienza di codifica di HTML e JavaScript aiuterà a comprendere facilmente la logica di codifica. Se qualcuno è nuovo alle DApps o sta iniziando il suo percorso di sviluppo Web, può facilmente seguire questo articolo. Non è richiesta una precedente esperienza in strumenti di sviluppo Solidity e Blockchain come Ganache, Truffle ecc. Tuttavia, spiegheremo ogni passo mentre andiamo avanti.
Questo articolo sarà utile per ogni principiante e costruiremo una DApp passo dopo passo. Ora, passiamo al passaggio successivo e capiamo cos’è una DApp.
Che cos’è una DApp?
Un’applicazione decentralizzata è un’applicazione software che opera su una rete distribuita. Non è ospitato su un server centralizzato ma su una rete peer-to-peer decentralizzata come IPFS. Per distribuire o interagire con una DApp, non è necessario rivelare alcuna identificazione del mondo reale.
DApp = FrontEnd + Smart Contract BackEnd
BackEnd Code è scritto principalmente in Solidity (o Vyper). Tuttavia, non esiste una lingua specifica per frontend code. Ora passiamo al passaggio successivo e capiamo come funzionano le DApp.
Come funzionano le DApp?
Nel diagramma seguente, possiamo vedere come funziona una tipica DApp. Ora approfondiamo questo diagramma per capirlo in modo migliore.
- Browser client: È un normale browser scritto in HTML, CSS e JS.
- Web3.js: È una raccolta di librerie che ci consentono di interagire con un nodo Ethereum locale o remoto utilizzando HTTP, IPC o WebSocket.
- Provider Web3: La rete Ethereum contiene nodi e tutti i nodi condividono la copia identica dei dati. Impostando un provider web3 in web3.js dice al nostro codice da quale nodo leggeremo e scriveremo i dati. Stiamo usando Metamask nella nostra DApp per iniettare il suo provider web3 nel browser.
- Macchina virtuale Ethereum (EVM): Ogni nodo Ethereum nella rete ha la sua implementazione EVM ed è responsabile dell’esecuzione delle stesse istruzioni Smart Contract sulla rete.
Installazione delle dipendenze
Ci sono alcuni requisiti tecnici prima di iniziare a creare DApp. In questa sezione, installeremo tutte le dipendenze richieste.
1. Installazione di VS Code
In primo luogo, abbiamo bisogno di un IDE, cioè di un ambiente di sviluppo integrato. Un IDE consente ai programmatori di semplificare il processo di creazione di un programma per computer. Aumenta la produttività di un programmatore unendo le tipiche attività di sviluppo software come la modifica del codice sorgente, la creazione di eseguibili e il debug in un’unica posizione.
Useremo Visual Studio Code nel nostro articolo. È un editor di codice sorgente leggero ideale per l’uso quotidiano con funzionalità come l’evidenziazione della sintassi, la corrispondenza tra parentesi, l’indentazione automatica, la selezione delle caselle, gli snippet, ecc. Combina la facilità d’uso di un editor di codice sorgente con funzionalità avanzate per sviluppatori come il completamento e il debug del codice IntelliSense. È disponibile per macOS, Linux e Windows.
2. Installazione di NodeJS e npm
In secondo luogo, abbiamo bisogno di un ambiente di runtime. Useremo NodeJS e npm. npm viene fornito con NodeJS.
Node.js è un ambiente di runtime JavaScript open source e multipiattaforma. È uno strumento ampiamente utilizzato per quasi tutti i progetti. È una piattaforma linguistica leggera, scalabile e open source che semplifica la creazione di app a livello aziendale. Npm contiene pacchetti che utilizziamo nelle nostre app per accelerare e migliorare il processo di sviluppo.
3. Installazione di Git
In terzo luogo, abbiamo bisogno di Git. È un sistema di controllo della versione distribuito gratuito e open source progettato per gestire tutto con velocità ed efficienza. Mantiene le modifiche che apportiamo ai file, quindi abbiamo una registrazione di ciò che è stato fatto.
4. Installazione del tartufo
In quarto luogo, abbiamo bisogno di tartufo. È un ambiente di sviluppo di livello mondiale, un framework di test e una pipeline di risorse per blockchain basate su Ethereum Virtual Machine (EVM).
Per scaricare Truffle, segui questa guida passo-passo.
- Fase 1: Aprire vs Code.
- Fase 2: Fare clic su Terminale.
- Passo 3: Fare clic su Nuovo terminale.
- Passo 4: Incolla questo comando sul terminale.
npm install -g truffle
- Passo 5: Per verificare che Truffle sia installato correttamente, incolla questo comando sul terminale.
truffle version
5. Installazione di Ganache
Infine, abbiamo bisogno di Ganache. È una blockchain locale per lo sviluppo rapido di applicazioni Ethereum e Corda. Possiamo utilizzare Ganache durante l’intero ciclo di sviluppo: sviluppo, distribuzione e test delle DApp in un ambiente sicuro e protetto. Tutte le versioni di Ganache sono disponibili per Windows, Mac e Linux.
Ganache è disponibile in due modalità: GUI e CLI. Ganache UI è un’applicazione desktop che supporta sia Ethereum che Corda. Ganache CLI è disponibile solo per lo sviluppo di Ethereum.
In questo articolo, useremo Ganache CLI perché è semplice e facile da usare. Per scaricare Ganache CLI, segui questa guida dettagliata.
- Fase 1: Aprire vs Code.
- Fase 2: Fare clic su Terminale.
- Passo 3: Fare clic su Nuovo terminale.
- Passo 4: Incolla questo comando sul terminale.
npm install ganache –global
- Passo 5: Per avviare Ganache, incolla questo comando sul terminale.
ganache
Ora abbiamo installato tutte le dipendenze. Il passo successivo è quello di impostare e ottimizzare il nostro ambiente di sviluppo.
Impostazione dell’ambiente di sviluppo
In questa sezione, imposteremo il nostro ambiente di sviluppo. Per configurare l’ambiente di sviluppo, seguire questa guida dettagliata.
- Fase 1: Vai a VS Code e crea una cartella pet-shop-tutorial.
- Fase 2: Ora fai clic con il pulsante destro del mouse su pet-shop-tutorial e fai clic su Apri nel terminale integrato.
Il team di Truffle ha creato Truffle Boxes. Questi sono i boilerplate che contengono moduli utili, contratti e librerie di solidità, viste front-end e molto altro.
- Passo 3: In questo articolo, useremo una Truffle Box, cioè pet-shop, che include la struttura di base del progetto e il codice per l’interfaccia utente. Incolla questo comando sul terminale.
truffle unbox pet-shop
Dopo aver eseguito il comando sopra, il comando scaricherà i file che possiamo vedere nell’immagine sopra.
- Metodo alternativo per il passaggio 3: Se qualcuno desidera creare l’interfaccia utente da zero ma vuole un boilerplate al tartufo. Incolla questo comando sul terminale.
truffle init
- Passo 4: Installeremo l’estensione VS Code Solidity di Juan Blanco per scrivere il codice Solidity in VS Code. Apri VS Code e vai a Estensioni nella barra laterale destra e fai clic su di esso. Cerca Solidity e clicca sull’estensione, il cui autore è Juan Blanco. Fare clic su Installa.
Ora il nostro ambiente di sviluppo è stato creato con successo. Il prossimo passo è creare un contratto intelligente.
Creazione di Smart Contract
In questa sezione, creeremo un contratto intelligente per la nostra DApp. Questa logica fungerà da back-end e archiviazione per la nostra DApp. Per creare un contratto intelligente, segui questa guida dettagliata.
Fase 1: Vai alla directory dei contratti nella cartella pet-shop-tutorial
Questa directory conterrà il nostro codice di contratto intelligente scritto in solidità. Ora crea un nuovo file Adoption.sol.
Passo 2: Ora inizieremo a scrivere il nostro codice di solidità
Incollare questo codice nel file Adoption.sol.
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
contract Adoption {
}
Ora, capiremo il significato del codice scritto sopra.
- SPDX-License-Identifier: GPL-3.0 : Solidity versione 0.6.8 ha introdotto identificatori di licenza SPDX, consentendo agli sviluppatori di definire la licenza utilizzata dal contratto. Gli sviluppatori dovrebbero aggiungerlo in alto. Se questo non è presente nel file del contratto, il compilatore visualizzerà un avviso. Inoltre, se il file del contratto ha più identificatori di licenza, il compilatore mostrerà un errore.
- solidità pragma >=0,4,0 <0,9,0; : questo comando indica al compilatore che il codice sorgente è stato scritto per le versioni di Solidity da 0.4.0 a 0.9.0. La parola chiave pragma viene utilizzata per abilitare le funzionalità e i controlli del compilatore.
- contract Adoption {} : Questo comando specifica la raccolta di codice e dati a un indirizzo specifico sulla blockchain di Ethereum.
Passaggio 3: ora dichiareremo una variabile per il nostro contratto intelligente
Incolla questo codice dopo il contratto Adoption { nel file Adoption.sol.
address[16] public adopters;
Ora, capiremo il significato del codice scritto sopra.
- address[16] : Questa affermazione è una matrice di indirizzi Ethereum. Le matrici contengono un tipo e possono avere una lunghezza fissa o variabile. In questo caso, il tipo è indirizzo e la lunghezza è 16.
- public : le funzioni pubbliche fanno parte dell’interfaccia contrattuale e possono essere chiamate esternamente o internamente. Per le variabili di stato pubblico, viene generata una funzione getter automatica.
- adopters : Questa istruzione è una variabile che è un contenitore per memorizzare valore.
Passo 4: Ora, aggiungeremo la funzione adotta () al nostro contratto intelligente
Abbiamo bisogno di una funzione per consentire agli utenti di effettuare le loro richieste di adozione. Quindi creeremo una funzione adopt(). Incollare questo codice dopo la dichiarazione della variabile nel file Adoption.sol.
// Adopting a pet
function adopt(uint256 petId) public returns (uint256) {
require(petId >= 0 && petId <= 15);
adopters[petId] = msg.sender;
return petId;
}
Ora, capiremo il significato del codice scritto sopra.
- function adopt(uint256 petId) public returns (uint256) {} : Dobbiamo specificare i parametri di funzione e i tipi di output in Solidity. In questo caso, prendiamo l’input petId come numero intero e lo restituiamo come numero intero. Per saperne di più su Funzioni in Solidità, Clicca qui.
- require(petId >= 0 && petId <= 15); : Stiamo usando la funzione require() per verificare se petID rientra nell’intervallo. Poiché gli array sono indicizzati da 0 in Solidity, stiamo prendendo il valore petID tra 0 e 15.
- adopters[petId] = msg.sender; : se l’ID rientra nell’intervallo, la funzione aggiunge l’indirizzo che ha effettuato la chiamata all’array adopters. msg.sender indica l’indirizzo della persona o del contratto intelligente che ha chiamato questa funzione.
- ritorno petId; : Stiamo restituendo il petId come output.
Passo 5: Ora, aggiungeremo la funzione getAdopters() al nostro contratto intelligente
Abbiamo bisogno di una funzione per recuperare gli adottanti. Questa funzione dovrebbe aggiornare tutti gli stati di adozione degli animali domestici. Quindi creeremo una funzione getAdopters(), che restituisce l’intero array. Incollare questo codice dopo la funzione adopt() nel file Adoption.sol.
// Retrieving the adopters
function getAdopters() public view returns (address[16] memory) {
return adopters;
}
Ora, capiremo il significato del codice scritto sopra.
- function getAdopters() public view returns (address[16] memory) {} : La spiegazione della dichiarazione di funzione è simile al passaggio 4. La parola chiave view indica che la funzione non modificherà lo stato del contratto. memory specifica la posizione dei dati della variabile.
- return adopters : Poiché abbiamo già dichiarato la variabile adopters nel passaggio 3. Possiamo restituirlo.
Passo 6: Ecco il nostro codice di solidità completo
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
contract Adoption {
address[16] public adopters;
// Adopting a pet
function adopt(uint256 petId) public returns (uint256) {
require(petId >= 0 && petId <= 15);
adopters[petId] = msg.sender;
return petId;
}
// Retrieving the adopters
function getAdopters() public view returns (address[16] memory) {
return adopters;
}
}
Ora il nostro contratto intelligente è stato creato con successo. Il prossimo passo è compilare il contratto intelligente.
Compilazione di Smart Contract
In questa sezione, compileremo il nostro contratto intelligente. Poiché Solidity è un linguaggio compilato. Pertanto, dobbiamo compilarlo in bytecode prima che EVM possa eseguirlo. Per compilare il contratto intelligente, segui questa guida passo passo.
- Fase 1: Vai alla cartella VS Code pet-shop-tutorial. Ora fai clic destro su di esso e fai clic su Apri nel terminale integrato.
- Fase 2: Incolla questo comando sul terminale. Questo comando compilerà tutti i contratti nella directory dei contratti.
truffle compile
Dopo aver eseguito il comando sopra, vedremo l’output come mostrato nell’immagine sottostante.
Ora il nostro contratto intelligente è stato compilato con successo. Il prossimo passo è migrare il contratto intelligente.
Migrazione di Smart Contract
In questa sezione, eseguiremo la migrazione del nostro contratto intelligente. Le migrazioni sono file JavaScript che aiutano a distribuire i contratti sulla rete Ethereum. Per eseguire la migrazione del contratto intelligente, segui questa guida dettagliata.
Passo 1: Vai alla directory delle migrazioni nella cartella pet-shop-tutorial.
Vedremo che un file JavaScript è già presente, cioè 1 migrazione iniziale.js. Questo file gestisce la distribuzione dello smart contract Migrations.sol. Abbiamo bisogno di un file simile per il nostro contratto Adoption.sol. Creeremo un nuovo file, cioè 2_deploy_contracts.js, simile al nostro 1_initial_migration.js. La parte di codifica sarà simile in entrambi i file. Le uniche modifiche saranno le funzioni require() e deploy(). Qui scriveremo Adozione al posto di Migrazioni. Incollare questo codice nel file 2_deploy_contracts.js.
var Adoption = artifacts.require(“Adoption”);
module.exports = function(deployer) {
de
Passaggio 2: ora è il momento di eseguire Ganache.
Abbiamo bisogno di avere una blockchain operativa prima di migrare il nostro contratto intelligente ad essa. Come discusso in precedenza, useremo Ganache CLI. Anche ora avremo bisogno di due terminali. Il primo sarà per i comandi Ganache e il secondo sarà per i comandi del tartufo. Quindi dobbiamo aprire i nostri terminali integrati due volte. Per avviare Ganache, incolla questo comando sul terminale.
ganache
Questo comando creerà una blockchain che opererà localmente sulla porta 8545.
Passaggio 3: ora cambieremo il numero di porta
La differenza principale tra Ganache GUI e CLI è che Ganache GUI viene eseguita sulla porta 7545, ma Ganache CLI viene eseguita sulla porta 8545. Quindi ora cambieremo il numero di porta nel file truffle-config.js, che è presente nella parte inferiore della cartella pet-shop-tutorial.
Passo 4: Ora è il momento di migrare il contratto intelligente alla blockchain
Incolla questo comando sul terminale. Questo comando eseguirà la migrazione di tutti i contratti nella directory delle migrazioni.
truffle migrate
Dopo aver eseguito il comando sopra, vedremo l’output come mostrato nell’immagine sottostante.
Ora, se torniamo a Ganache, possiamo vedere che lo stato della blockchain è cambiato. La blockchain ora mostra il blocco numero 4. In precedenza, era 0.
Ora il nostro contratto intelligente è migrato con successo. Il prossimo passo è testare il contratto intelligente.
Test dello Smart Contract
In questa sezione, testeremo il nostro contratto intelligente. Testare un contratto intelligente è essenziale perché un bug può costare milioni di dollari. Per testare il contratto intelligente, segui questa guida passo passo.
Passaggio 1: vai alla directory dei test nella cartella pet-shop-tutorial
Questa directory conterrà codice scritto in solidità per il test dei contratti intelligenti. Ora crea un nuovo file TestAdoption.sol. Incollare questo codice nel file TestAdoption.sol.
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
import “truffle/Assert.sol”;
import “truffle/DeployedAddresses.sol”;
import “../contracts/Adoption.sol”;
contract TestAdoption {
Adoption adoption = Adoption(DeployedAddresses.Adoption());
uint expectedPetId = 8;
address expectedAdopter = address(this);
}
Ora, capiremo il significato del codice scritto sopra.
- importare “tartufo/Assert.sol”; : Stiamo importando Assert.sol dalla directory globale dei tartufi. Ci dà vari controlli di asserzione da utilizzare nei nostri test.
- importare “truffle/DeployedAddresses.sol”; : Stiamo importando DeployedAddresses.sol dalla directory globale del tartufo. Truffle distribuirà una nuova istanza del contratto in fase di test sulla blockchain durante l’esecuzione dei test. Questo file ottiene l’indirizzo del contratto distribuito.
- importare “.. /contratti/Adozione.sol”; : Stiamo importando Adoption.sol dalla directory dei contratti in quanto questo è il contratto intelligente su cui vogliamo eseguire i test.
- Adozione adozione = Adozione(DeployedAddresses.Adoption()); : Questo codice contiene l’indirizzo dello smart contract da testare, ovvero il contratto di adozione.
- uint expectedPetId = 8; : questa variabile contiene l’ID animale domestico previsto, che il contratto TestAdoption utilizzerà per i test.
- indirizzo expectedAdopter = address(this); : Abbiamo impostato l’indirizzo dell’adottante previsto su questo, che recupera l’indirizzo del contratto corrente perché il contratto TestAdoption invierà la transazione al contratto Adoption.
Passo 2: Ora, testeremo la funzione adopt()
Incollare questo codice dopo la dichiarazione di expectedPetId nel file TestAdoption.sol.
// Testing the adopt() function
function testUserCanAdoptPet() public {
uint returnedId = adoption.adopt(expectedPetId);
Assert.equal(returnedId, expectedPetId, “Adoption of the expected pet should match what is returned.”);
}
Ora, capiremo il significato del codice scritto sopra.
- uint returnedId = adoption.adopt(expectedPetId); : Chiamiamo il contratto intelligente precedentemente dichiarato, cioè contratto di adozione con l’ID expectedPetId.
- Assert.equal(returnedId, expectedPetId, “L’adozione dell’animale domestico previsto dovrebbe corrispondere a ciò che viene restituito.”); : passiamo il valore effettivo, ovvero returnedId, il valore previsto, ovvero expectedPetId e un messaggio di errore che viene stampato se il test non riesce a assert.equal() funzione.
Passo 3: Ora testeremo il recupero del proprietario di un singolo animale domestico
Incollare questo codice dopo la funzione testUserCanAdoptPet() nel file TestAdoption.sol.
// Testing retrieval of a single pet’s owner
function testGetAdopterAddressByPetId() public {
address adopter = adoption.adopters(expectedPetId);
Assert.equal(adopter, expectedAdopter, “Owner of the expected pet should be this contract”);
}
Ora, capiremo il significato del codice scritto sopra.
- address adopter = adoption.adopters(expectedPetId); Stiamo ottenendo l’indirizzo dell’adottante memorizzato dal contratto di adozione dopo aver superato expectedPetId.
- Assert.equal(adottante, expectedAdopter, “Il proprietario dell’animale domestico previsto dovrebbe essere questo contratto”); Stiamo passando il valore effettivo, il valore previsto e un messaggio di errore che viene stampato se il test determina il fallimento della funzione Assert.equal().
Passo 4: Ora, testeremo il recupero di tutti i proprietari di animali domestici
Incollare questo codice dopo la funzione testGetAdopterAddressByPetId() nel file TestAdoption.sol.
// Testing retrieval of all pet owners
function testGetAdopterAddressByPetIdInArray() public {
address[16] memory adopters = adoption.getAdopters();
Assert.equal(adopters[expectedPetId], expectedAdopter, “Owner of the expected pet should be this contract”);
}
Ora, capiremo il significato del codice scritto sopra.
- address[16] memory adopters = adoption.getAdopters(); : Stiamo memorizzando gli adottanti in memoria piuttosto che nell’archiviazione del contratto.
- Assert.equal(adopters[expectedPetId], expectedAdopter, “Il proprietario dell’animale domestico previsto dovrebbe essere questo contratto”); : stiamo passando il valore effettivo, il valore previsto e un messaggio di errore che viene stampato se il test genera il fallimento della funzione Assert.equal().
Passo 5: Ecco il nostro codice di solidità completo
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
import “truffle/Assert.sol”;
import “truffle/DeployedAddresses.sol”;
import “../contracts/Adoption.sol”;
contract TestAdoption {
// The address of the adoption contract to be tested
Adoption adoption = Adoption(DeployedAddresses.Adoption());
// The id of the pet that will be used for testing
uint256 expectedPetId = 8;
// Testing the adopt() function
function testUserCanAdoptPet() public {
uint256 returnedId = adoption.adopt(expectedPetId);
Assert.equal(returnedId, expectedPetId, “Adoption of the expected pet should match what is returned.”);
}
// Testing retrieval of a single pet’s owner
function testGetAdopterAddressByPetId() public {
address adopter = adoption.adopters(expectedPetId);
Assert.equal(adopter, expectedAdopter, “Owner of the expected pet should be this contract”);
}
// Testing retrieval of all pet owners
function testGetAdopterAddressByPetIdInArray() public {
// Store adopters in memory rather than contract’s storage
address[16] memory adopters = adoption.getAdopters();
Assert.equal(adopters[expectedPetId], expectedAdopter, “Owner of the expected pet should be this contract”
);
}
// The expected owner of adopted pet is this contract
address expectedAdopter = address(this);
}
Passaggio 6: ora è il momento di testare il contratto intelligente
Incolla questo comando sul terminale.
truffle test
Dopo aver eseguito il comando sopra, vedremo l’output come mostrato nell’immagine sottostante.
Ora il nostro contratto intelligente è stato testato con successo. Il prossimo passo è creare un’interfaccia frontend per la nostra DApp.
Creazione di un’interfaccia utente per Smart Contract
In questa sezione, creeremo un’interfaccia utente. Il codice per il front-end della DApp si trova anche nel negozio di animali Truffle Box. È presente all’interno nella directory src. Aggiungeremo solo quelle funzioni che sono uniche per Ethereum. Per creare un’interfaccia utente per smart contract, segui questa guida passo passo.
Passaggio 1: istanziazione di web3
Vai al file app.js nella directory di test della cartella pet-shop-tutorial. Ora, rimuovi il commento a più righe dalla funzione initWeb3() e incolla il codice qui sotto.
// {Part 1}
if (window.ethereum) {
App.web3Provider = window.ethereum;
try {
// Request account access
await window.ethereum.request({ method: “eth_requestAccounts” });;
} catch (error) {
// User denied account access…
console.error(“User denied account access”)
}
}
// {Part 2}
else if (window.web3) {
App.web3Provider = window.web3.currentProvider;
}
// {Part 3}
else {
App.web3Provider = new Web3.providers.HttpProvider(‘http://localhost:8545’);
}
web3 = new Web3(App.web3Provider);
Ora, capiremo il significato del codice scritto sopra.
- Parte 1 cioè se condizione : Stiamo controllando se utilizziamo browser DApp in cui un provider ethereum viene iniettato nell’oggetto finestra. Lo usiamo per creare il nostro oggetto web3, ma dobbiamo anche richiedere l’accesso agli account esplicitamente con ethereum.enable().
- Parte 2 cioè altrimenti se condizione : Se l’oggetto ethereum non esiste, controlliamo un’istanza web3 iniettata. Se esiste, indica che stiamo utilizzando un browser DApp meno recente. Quindi prendiamo il suo provider e lo usiamo per creare il nostro oggetto web3.
- Parte 3, cioè altra condizione: se non esiste un’istanza web3 iniettata, creiamo il nostro oggetto web3 utilizzando il nostro provider locale.
Fase 2: Istanziazione del contratto
Dobbiamo creare un’istanza del nostro contratto intelligente, in modo che web3 capisca dove trovarlo e come funziona. Ora, rimuovi il commento su più righe dalla funzione initContract() e incolla il codice seguente.
$.getJSON(‘Adoption.json’, function(data) {
// Get the necessary contract artifact file and instantiate it with @truffle/contract
var AdoptionArtifact = data;
App.contracts.Adoption = TruffleContract(AdoptionArtifact);
// Set the provider for our contract
App.contracts.Adoption.setProvider(App.web3Provider);
// Use our contract to retrieve and mark the adopted pets
return App.markAdopted();
});
Ora, capiremo il significato del codice scritto sopra.
- var AdoptionArtifact = dati; : Stiamo recuperando il file Artifact per il nostro contratto intelligente.
- App.contracts.Adoption = TruffleContract(AdoptionArtifact); : Passeremo ora il file Artifact a TruffleContract(), che crea un’istanza del contratto con cui interagire.
- App.contracts.Adoption.setProvider(App.web3Provider); : imposteremo il provider web3 del contratto utilizzando il valore App.web3Provider memorizzato in precedenza durante la configurazione di web3.
- restituire App.markAdopted(); : Chiameremo la funzione markAdopted() se gli animali domestici sono già stati adottati da una visita precedente.
Passaggio 3: ottenere gli animali domestici adottati e aggiornare l’interfaccia utente
Ora, rimuovi il commento a più righe dalla funzione markAdopted() e incolla il codice qui sotto.
// Part 1
var adoptionInstance;
App.contracts.Adoption.deployed().then(function(instance) {
adoptionInstance = instance;
return adoptionInstance.getAdopters.call();
// Part 2
}).then(function(adopters) {
for (i = 0; i < adopters.length; i++) {
if (adopters[i] !== ‘0x0000000000000000000000000000000000000000’) {
$(‘.panel-pet’).eq(i).find(‘button’).text(‘Success’).attr(‘disabled’, true);
}
}
}).catch(function(err) {
console.log(err.message);
});
Ora, capiremo il significato del codice scritto sopra.
- Parte 1 : Dichiareremo l’adozione variabileInstance al di fuori delle chiamate smart contract per accedere facilmente all’istanza dopo averla recuperata per la prima volta. Successivamente, utilizzeremo la funzione call(), che ci consente di leggere i dati dalla blockchain senza una transazione.
- Parte 2: Dopo aver chiamato la funzione getAdopters(), useremo il ciclo for per verificare se è memorizzato un indirizzo per ogni animale domestico. Infine, controlliamo tutti i possibili errori.
Passaggio 4: gestione della funzione adotta()
Ora, rimuovi il commento multiriga dalla funzione handleAdopt e incolla il codice qui sotto.
// Part 1
var adoptionInstance;
web3.eth.getAccounts(function(error, accounts) {
if (error) {
console.log(error);
}
var account = accounts[0];
App.contracts.Adoption.deployed().then(function(instance) {
adoptionInstance = instance;
// Execute adopt as a transaction by sending account
return adoptionInstance.adopt(petId, {from: account});
}).then(function(result) {
// Part 2
return App.markAdopted();
}).catch(function(err) {
console.log(err.message);
});
});
Ora, capiremo il significato del codice scritto sopra.
- Parte 1 : Useremo web3 per recuperare gli account utente. Dopo il controllo degli errori, selezioniamo quindi il primo account nel callback. Successivamente, otterremo il contratto distribuito e archivieremo l’istanza in adoptionInstance. Quindi invieremo una transazione anziché una chiamata. Le transazioni richiedono un indirizzo da e hanno un costo associato. Inviamo la transazione eseguendo la funzione adopt() con petID e un oggetto contenente l’indirizzo del conto, cioè l’account.
- Parte 2 : L’oggetto transazione è il risultato dell’invio di una transazione. Se non si verificano problemi, eseguiamo la nostra funzione markAdopted() per sincronizzare l’interfaccia utente con i nostri dati appena memorizzati.
Passo 5: Ecco il codice completo del file app.js
App = {
web3Provider: null,
contracts: {},
init: async function() {
// Load pets.
$.getJSON(‘../pets.json’, function(data) {
var petsRow = $(‘#petsRow’);
var petTemplate = $(‘#petTemplate’);
for (i = 0; i < data.length; i ++) {
petTemplate.find(‘.panel-title’).text(data[i].name);
petTemplate.find(‘img’).attr(‘src’, data[i].picture);
petTemplate.find(‘.pet-breed’).text(data[i].breed);
petTemplate.find(‘.pet-age’).text(data[i].age);
petTemplate.find(‘.pet-location’).text(data[i].location);
petTemplate.find(‘.btn-adopt’).attr(‘data-id’, data[i].id);
petsRow.append(petTemplate.html());
}
});
return await App.initWeb3();
},
initWeb3: async function() {
// Modern dapp browsers…
if (window.ethereum) {
App.web3Provider = window.ethereum;
try {
// Request account access
await window.ethereum.request({ method: “eth_requestAccounts” });;
} catch (error) {
// User denied account access…
console.error(“User denied account access”)
}
}
// Legacy dapp browsers…
else if (window.web3) {
App.web3Provider = window.web3.currentProvider;
}
// If no injected web3 instance is detected, fall back to Ganache
else {
App.web3Provider = new Web3.providers.HttpProvider(‘http://localhost:7545’);
}
web3 = new Web3(App.web3Provider);
return App.initContract();
},
initContract: function() {
$.getJSON(‘Adoption.json’, function(data) {
// Get the necessary contract artifact file and instantiate it with @truffle/contract
var AdoptionArtifact = data;
App.contracts.Adoption = TruffleContract(AdoptionArtifact);
// Set the provider for our contract
App.contracts.Adoption.setProvider(App.web3Provider);
// Use our contract to retrieve and mark the adopted pets
return App.markAdopted();
});
return App.bindEvents();
},
bindEvents: function() {
$(document).on(‘click’, ‘.btn-adopt’, App.handleAdopt);
},
markAdopted: function() {
var adoptionInstance;
App.contracts.Adoption.deployed().then(function(instance) {
adoptionInstance = instance;
return adoptionInstance.getAdopters.call();
}).then(function(adopters) {
for (i = 0; i < adopters.length; i++) {
if (adopters[i] !== ‘0x0000000000000000000000000000000000000000’) {
$(‘.panel-pet’).eq(i).find(‘button’).text(‘Success’).attr(‘disabled’, true);
}
}
}).catch(function(err) {
console.log(err.message);
});
},
handleAdopt: function(event) {
event.preventDefault();
var petId = parseInt($(event.target).data(‘id’));
var adoptionInstance;
web3.eth.getAccounts(function(error, accounts) {
if (error) {
console.log(error);
}
var account = accounts[0];
App.contracts.Adoption.deployed().then(function(instance) {
adoptionInstance = instance;
// Execute adopt as a transaction by sending account
return adoptionInstance.adopt(petId, {from: account});
}).then(function(result) {
return App.markAdopted();
}).catch(function(err) {
console.log(err.message);
});
});
}
};
$(function() {
$(window).load(function() {
App.init();
});
});
Ora la nostra interfaccia utente è stata creata con successo. Il prossimo passo è interagire con DApp.
Interazione con DApp
Questo è il passo finale. In questa sezione, interagiremo con DApp. Per interagire con la DApp, segui questa guida passo passo.
Passaggio 1: installazione di MetaMask
MetaMask è un portafoglio crittografico e gateway Web3 per blockchain DApps. Attualmente è disponibile come estensione del browser e app mobile su dispositivi Android e iOS. Per scaricare MetaMask, segui questa guida passo passo.
Passaggio 2: aggiunta di Ganache a MetaMask
Ora collegheremo MetaMask alla blockchain creata da Ganache CLI. Fai clic sull’icona che mostra Ethereum Mainnet. Quindi, vedremo un’opzione per Aggiungi rete. Fare clic sul pulsante Aggiungi rete.
Ora, aggiungeremo i seguenti parametri indicati di seguito e faremo clic su Salva.
- Nome: Ganache
- RPC-URL: http://127.0.0.1:8545
- ID catena: 1337
Dopo il salvataggio, vedremo questa schermata come mostrato di seguito. Ad ogni account creato da Ganache CLI vengono assegnati 1000 ether. Noteremo meno etere poiché è stato utilizzato del gas quando abbiamo implementato il contratto ed eseguito i test.
Passaggio 3: esecuzione della DApp
Ora è il momento di eseguire la nostra DApp. Andremo al secondo Terminal. Questo comando avvierà un nuovo server Web locale e aprirà una nuova scheda del browser con la nostra DApp. Incolla questo comando sul terminale.
npm run dev
Dopo aver eseguito il comando sopra, vedremo l’output come mostrato nell’immagine sottostante.
Passaggio 4: utilizzo della DApp
- Ora è il momento di usare la nostra DApp. Adotteremo Gina. Fare clic sul pulsante Adotta.
- Apparirà una notifica Metamask e vedrà una transazione. Ora, fai clic su Conferma.
- Vedremo una nuova notifica per la transazione confermata.
- Ora, se torniamo alla sezione attività del portafoglio MetaMask possiamo vedere una transazione.
- Se torniamo alla nostra DApp. Possiamo vedere che il pulsante adotta è ora cambiato in successo.
Conclusione
Abbiamo cercato di spiegare tutto da zero in modo graduale. Abbiamo dato spiegazioni e ragionamenti per ogni singolo passo. Siamo felici per tutti coloro che hanno letto questo articolo e hanno creato questa DApp da zero senza alcuna precedente esperienza di sviluppo DApp. Creeremo una nuova entusiasmante DApp da zero nel prossimo tutorial. Tutti i crediti di codice utilizzati appartengono a Truffle Documentation.
Domande frequenti
Quali sono alcune famose DApp?
CryptoMines, Bomb Crypto, Splinterlands e Axie Infinity sono alcune DApp popolari sul mercato.
Come fa DApp a fare soldi?
Le DApp possono fare soldi attraverso un lancio ICO, pubblicità, commissioni di transazione, abbonamenti, ecc. E molto altro.
Le DApp hanno un futuro?
Le DApp continueranno ad espandersi a un ritmo esponenziale in futuro. Anche se questo processo richiederà tempo, si prevede che il 2022 vedrà miglioramenti significativi e la diffusione della tecnologia blockchain e delle sue applicazioni.
Perché Web3 è il futuro?
La privacy è la più grande preoccupazione per gli utenti regolari nel 2022. In Web3, gli utenti avranno la proprietà completa delle loro risorse. A differenza di ora, dove i giganti della tecnologia controllano la maggior parte delle piattaforme.
Dove possiamo trovare le DApp?
Possiamo trovare tutte le DApp popolari su DApp Radar. È uno dei migliori negozi DApp disponibili sul mercato.