Zum Hauptinhalt springen

Hello World Smart Contract für Anfänger - Fullstack

Solidity
Hardhat
Alchemy
Smart Contracts
Bereitstellung
Blocksuchmaschine
Frontend
Transaktionen
Framework
Anfänger
nstrike2
25. Oktober 2021
45 Minuten Lesezeit

Dieser Leitfaden ist für Sie, wenn Sie neu in der Blockchain-Entwicklung sind und nicht wissen, wo Sie anfangen sollen oder wie Sie Smart Contracts bereitstellen und mit ihnen interagieren können. Wir werden die Erstellung und Bereitstellung eines einfachen Smart Contracts im Goerli-Testnet unter Verwendung von MetaMask (opens in a new tab), Solidity (opens in a new tab), Hardhat (opens in a new tab) und Alchemy (opens in a new tab) durchgehen.

Sie benötigen ein Alchemy-Konto, um dieses Tutorial abzuschließen. Melden Sie sich für ein kostenloses Konto an (opens in a new tab).

Wenn Sie zu irgendeinem Zeitpunkt Fragen haben, können Sie sich gerne im Alchemy Discord (opens in a new tab) melden!

Teil 1 – Erstellen und Bereitstellen Ihres Smart Contracts mit Hardhat

Mit dem Ethereum-Netzwerk verbinden

Es gibt viele Möglichkeiten, Anfragen an die Ethereum-Chain zu stellen. Der Einfachheit halber verwenden wir ein kostenloses Konto bei Alchemy, einer Blockchain-Entwicklerplattform und API, die es uns ermöglicht, mit der Ethereum-Chain zu kommunizieren, ohne selbst einen Blockchain-Knoten betreiben zu müssen. Alchemy verfügt auch über Entwicklertools für Überwachung und Analysen; wir werden diese in diesem Tutorial nutzen, um zu verstehen, was bei der Bereitstellung unseres Smart Contracts unter der Haube passiert.

Erstellen Sie Ihre App und Ihren API-Schlüssel

Sobald Sie ein Alchemy-Konto erstellt haben, können Sie einen API-Schlüssel generieren, indem Sie eine App erstellen. Dies ermöglicht es Ihnen, Anfragen an das Goerli-Testnet zu stellen. Wenn Sie nicht mit Testnets vertraut sind, können Sie Alchemys Leitfaden zur Auswahl eines Netzwerks lesen (opens in a new tab).

Suchen Sie im Alchemy-Dashboard das Dropdown-Menü Apps in der Navigationsleiste und klicken Sie auf Create App.

Hello world create app

Geben Sie Ihrer App den Namen „Hello World“ und schreiben Sie eine kurze Beschreibung. Wählen Sie Staging als Ihre Umgebung und Goerli als Ihr Netzwerk.

create app view hello world

Hinweis: Stellen Sie sicher, dass Sie Goerli auswählen, da dieses Tutorial sonst nicht funktioniert.

Klicken Sie auf Create app. Ihre App wird in der Tabelle unten angezeigt.

Ein Ethereum-Konto erstellen

Sie benötigen ein Ethereum-Konto, um Transaktionen zu senden und zu empfangen. Wir werden MetaMask verwenden, ein virtuelles Wallet im Browser, mit dem Benutzer ihre Ethereum-Konto-Adresse verwalten können.

Sie können hier (opens in a new tab) kostenlos ein MetaMask-Konto herunterladen und erstellen. Wenn Sie ein Konto erstellen oder bereits eines haben, stellen Sie sicher, dass Sie oben rechts zum „Goerli Test Network“ wechseln (damit wir nicht mit echtem Geld hantieren).

Schritt 4: Ether von einem Faucet hinzufügen

Um Ihren Smart Contract im Testnetzwerk bereitzustellen, benötigen Sie etwas falsches ETH. Um ETH im Goerli-Netzwerk zu erhalten, gehen Sie zu einem Goerli-Faucet und geben Sie Ihre Goerli-Konto-Adresse ein. Beachten Sie, dass Goerli-Faucets in letzter Zeit etwas unzuverlässig sein können – auf der Testnetzwerk-Seite finden Sie eine Liste mit Optionen, die Sie ausprobieren können:

Hinweis: Aufgrund von Netzwerküberlastung kann dies eine Weile dauern. ``

Schritt 5: Überprüfen Sie Ihr Guthaben

Um sicherzustellen, dass sich das ETH in Ihrem Wallet befindet, stellen wir eine eth_getBalance (opens in a new tab)-Anfrage mit dem Composer-Tool von Alchemy (opens in a new tab). Dies gibt die Menge an ETH in unserem Wallet zurück. Um mehr zu erfahren, sehen Sie sich Alchemys kurzes Tutorial zur Verwendung des Composer-Tools (opens in a new tab) an.

Geben Sie Ihre MetaMask-Konto-Adresse ein und klicken Sie auf Send Request. Sie werden eine Antwort sehen, die wie der folgende Codeausschnitt aussieht.

1{ "jsonrpc": "2.0", "id": 0, "result": "0x2B5E3AF16B1880000" }

Hinweis: Dieses Ergebnis ist in Wei, nicht in ETH. Wei wird als die kleinste Stückelung von Ether verwendet.

Puh! Unser falsches Geld ist komplett da.

Schritt 6: Unser Projekt initialisieren

Zuerst müssen wir einen Ordner für unser Projekt erstellen. Navigieren Sie zu Ihrer Kommandozeile und geben Sie Folgendes ein.

1mkdir hello-world
2cd hello-world

Jetzt, da wir uns in unserem Projektordner befinden, verwenden wir npm init, um das Projekt zu initialisieren.

Wenn Sie npm noch nicht installiert haben, folgen Sie diesen Anweisungen, um Node.js und npm zu installieren (opens in a new tab).

Für die Zwecke dieses Tutorials spielt es keine Rolle, wie Sie die Initialisierungsfragen beantworten. Hier ist als Referenz, wie wir es gemacht haben:

1package name: (hello-world)
2version: (1.0.0)
3description: hello world smart contract
4entry point: (index.js)
5test command:
6git repository:
7keywords:
8author:
9license: (ISC)
10
11About to write to /Users/.../.../.../hello-world/package.json:
12
13{
14 "name": "hello-world",
15 "version": "1.0.0",
16 "description": "hello world smart contract",
17 "main": "index.js",
18 "scripts": {
19 "test": "echo \"Error: no test specified\" && exit 1"
20 },
21 "author": "",
22 "license": "ISC"
23}
Alle anzeigen

Bestätigen Sie die package.json und wir können loslegen!

Schritt 7: Hardhat herunterladen

Hardhat ist eine Entwicklungsumgebung zum Kompilieren, Bereitstellen, Testen und Debuggen Ihrer Ethereum-Software. Es hilft Entwicklern beim lokalen Erstellen von Smart Contracts und Dapps, bevor sie auf der Live-Chain bereitgestellt werden.

Führen Sie in unserem hello-world-Projekt Folgendes aus:

1npm install --save-dev hardhat

Auf dieser Seite finden Sie weitere Details zu den Installationsanweisungen (opens in a new tab).

Schritt 8: Hardhat-Projekt erstellen

Führen Sie in unserem hello-world-Projektordner Folgendes aus:

1npx hardhat

Sie sollten dann eine Willkommensnachricht und die Option sehen, auszuwählen, was Sie tun möchten. Wählen Sie „create an empty hardhat.config.js“:

1888 888 888 888 888
2888 888 888 888 888
3888 888 888 888 888
48888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888
5888 888 "88b 888P" d88" 888 888 "88b "88b 888
6888 888 .d888888 888 888 888 888 888 .d888888 888
7888 888 888 888 888 Y88b 888 888 888 888 888 Y88b.
8888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888
9
10👷 Welcome to Hardhat v2.0.11 👷‍
11
12What do you want to do? …
13Create a sample project
14❯ Create an empty hardhat.config.js
15Quit
Alle anzeigen

Dadurch wird eine hardhat.config.js-Datei im Projekt generiert. Wir werden diese später im Tutorial verwenden, um das Setup für unser Projekt festzulegen.

Schritt 9: Projektordner hinzufügen

Um das Projekt übersichtlich zu halten, lassen Sie uns zwei neue Ordner erstellen. Navigieren Sie in der Kommandozeile zum Stammverzeichnis Ihres hello-world-Projekts und geben Sie ein:

1mkdir contracts
2mkdir scripts
  • contracts/ ist der Ort, an dem wir unsere Hello-World-Smart-Contract-Codedatei aufbewahren werden
  • scripts/ ist der Ort, an dem wir Skripte zur Bereitstellung und Interaktion mit unserem Vertrag aufbewahren werden

Schritt 10: Unseren Vertrag schreiben

Sie fragen sich vielleicht, wann wir endlich Code schreiben werden? Es ist soweit!

Öffnen Sie das hello-world-Projekt in Ihrem bevorzugten Editor. Smart Contracts werden am häufigsten in Solidity geschrieben, was wir auch verwenden werden, um unseren Smart Contract zu schreiben.‌

  1. Navigieren Sie zum Ordner contracts und erstellen Sie eine neue Datei namens HelloWorld.sol
  2. Unten finden Sie einen beispielhaften Hello-World-Smart-Contract, den wir für dieses Tutorial verwenden werden. Kopieren Sie den folgenden Inhalt in die Datei HelloWorld.sol.

Hinweis: Lesen Sie unbedingt die Kommentare, um zu verstehen, was dieser Vertrag tut.

1// Specifies the version of Solidity, using semantic versioning.
2// Learn more: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma
3pragma solidity >=0.7.3;
4
5// Defines a contract named `HelloWorld`.
6// A contract is a collection of functions and data (its state). Once deployed, a contract resides at a specific address on the Ethereum blockchain. Learn more: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html
7contract HelloWorld {
8
9 //Emitted when update function is called
10 //Smart contract events are a way for your contract to communicate that something happened on the blockchain to your app front-end, which can be 'listening' for certain events and take action when they happen.
11 event UpdatedMessages(string oldStr, string newStr);
12
13 // Declares a state variable `message` of type `string`.
14 // State variables are variables whose values are permanently stored in contract storage. The keyword `public` makes variables accessible from outside a contract and creates a function that other contracts or clients can call to access the value.
15 string public message;
16
17 // Similar to many class-based object-oriented languages, a constructor is a special function that is only executed upon contract creation.
18 // Constructors are used to initialize the contract's data. Learn more:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors
19 constructor(string memory initMessage) {
20
21 // Accepts a string argument `initMessage` and sets the value into the contract's `message` storage variable).
22 message = initMessage;
23 }
24
25 // A public function that accepts a string argument and updates the `message` storage variable.
26 function update(string memory newMessage) public {
27 string memory oldMsg = message;
28 message = newMessage;
29 emit UpdatedMessages(oldMsg, newMessage);
30 }
31}
Alle anzeigen

Dies ist ein grundlegender Smart Contract, der bei der Erstellung eine Nachricht speichert. Sie kann durch Aufrufen der Funktion update aktualisiert werden.

Schritt 11: MetaMask & Alchemy mit Ihrem Projekt verbinden

Wir haben ein MetaMask-Wallet und ein Alchemy-Konto erstellt sowie unseren Smart Contract geschrieben. Nun ist es an der Zeit, die drei miteinander zu verbinden.

Jede von Ihrem Wallet gesendete Transaktion erfordert eine Signatur mit Ihrem einzigartigen Private-Key. Um unserem Programm diese Berechtigung zu erteilen, können wir unseren Private-Key sicher in einer Umgebungsdatei speichern. Wir werden hier auch einen API-Schlüssel für Alchemy speichern.

Um mehr über das Senden von Transaktionen zu erfahren, sehen Sie sich dieses Tutorial (opens in a new tab) zum Senden von Transaktionen mit web3 an.

Installieren Sie zunächst das dotenv-Paket in Ihrem Projektverzeichnis:

1npm install dotenv --save

Erstellen Sie dann eine .env-Datei im Stammverzeichnis des Projekts. Fügen Sie Ihren MetaMask-Private-Key und die HTTP-Alchemy-API-URL hinzu.

Ihre Umgebungsdatei muss .env heißen, sonst wird sie nicht als Umgebungsdatei erkannt.

Nennen Sie sie nicht process.env oder .env-custom oder ähnlich.

Animated walkthrough of getting an Alchemy API key

Ihre .env sollte so aussehen:

1API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key"
2PRIVATE_KEY = "your-metamask-private-key"

Um diese tatsächlich mit unserem Code zu verbinden, werden wir in Schritt 13 in unserer hardhat.config.js-Datei auf diese Variablen verweisen.

Schritt 12: Ethers.js installieren

Ethers.js ist eine Bibliothek, die die Interaktion und das Stellen von Anfragen an Ethereum erleichtert, indem sie Standard-JSON-RPC-Methoden (opens in a new tab) in benutzerfreundlichere Methoden verpackt.

Hardhat ermöglicht es uns, Plugins (opens in a new tab) für zusätzliche Tools und erweiterte Funktionalität zu integrieren. Wir werden das Ethers-Plugin (opens in a new tab) für die Bereitstellung von Verträgen nutzen.

Geben Sie in Ihrem Projektverzeichnis Folgendes ein:

npm install --save-dev @nomiclabs/hardhat-ethers "ethers@^5.0.0"

Schritt 13: hardhat.config.js aktualisieren

Wir haben bisher mehrere Abhängigkeiten und Plugins hinzugefügt, jetzt müssen wir hardhat.config.js aktualisieren, damit unser Projekt von allen weiß.

Aktualisieren Sie Ihre hardhat.config.js, sodass sie wie folgt aussieht:

1/* *
2 * @type import('hardhat/config').HardhatUserConfig */
3
4
5
6
7require("dotenv").config()
8require("@nomiclabs/hardhat-ethers")
9
10const { API_URL, PRIVATE_KEY } = process.env
11
12module.exports = {
13 solidity: "0.7.3",
14 defaultNetwork: "goerli",
15 networks: {
16 hardhat: {},
17 goerli: {
18 url: API_URL,
19 accounts: [`0x${PRIVATE_KEY}`],
20 },
21 },
22}
Alle anzeigen

Schritt 14: Unseren Vertrag kompilieren

Um sicherzustellen, dass bisher alles funktioniert, lassen Sie uns unseren Vertrag kompilieren. Die Aufgabe compile ist eine der integrierten Hardhat-Aufgaben.

Führen Sie in der Kommandozeile Folgendes aus:

npx hardhat compile

Möglicherweise erhalten Sie eine Warnung über SPDX license identifier not provided in source file, aber darüber müssen Sie sich keine Sorgen machen – hoffentlich sieht alles andere gut aus! Wenn nicht, können Sie jederzeit im Alchemy-Discord (opens in a new tab) nachfragen.

Schritt 15: Unser Bereitstellungsskript schreiben

Jetzt, da unser Vertrag geschrieben ist und unsere Konfigurationsdatei einsatzbereit ist, ist es an der Zeit, unser Skript zur Bereitstellung des Vertrags zu schreiben.

Navigieren Sie zum Ordner scripts/ und erstellen Sie eine neue Datei namens deploy.js. Fügen Sie ihr den folgenden Inhalt hinzu:

1async function main() {
2 const HelloWorld = await ethers.getContractFactory("HelloWorld")
3
4 // Startet die Bereitstellung und gibt ein Promise zurück, das zu einem Vertragsobjekt aufgelöst wird
5 const hello_world = await HelloWorld.deploy("Hello World!")
6 console.log("Contract deployed to address:", hello_world.address)
7}
8
9main()
10 .then(() => process.exit(0))
11 .catch((error) => {
12 console.error(error)
13 process.exit(1)
14 })
Alle anzeigen

Hardhat leistet hervorragende Arbeit bei der Erklärung, was jede dieser Codezeilen in ihrem Contracts-Tutorial (opens in a new tab) tut. Wir haben ihre Erklärungen hier übernommen.

1const HelloWorld = await ethers.getContractFactory("HelloWorld")

Eine ContractFactory in ethers.js ist eine Abstraktion, die zur Bereitstellung neuer Smart Contracts verwendet wird. HelloWorld ist hier also eine Factory (opens in a new tab) für Instanzen unseres Hello-World-Vertrags. Bei Verwendung des hardhat-ethers-Plugins sind ContractFactory- und Contract-Instanzen standardmäßig mit dem ersten Unterzeichner (Eigentümer) verbunden.

1const hello_world = await HelloWorld.deploy()

Der Aufruf von deploy() auf einer ContractFactory startet die Bereitstellung und gibt ein Promise zurück, das in ein Contract-Objekt aufgelöst wird. Dies ist das Objekt, das eine Methode für jede unserer Smart-Contract-Funktionen hat.

Schritt 16: Unseren Vertrag bereitstellen

Wir sind endlich bereit, unseren Smart Contract bereitzustellen! Navigieren Sie zur Kommandozeile und führen Sie Folgendes aus:

npx hardhat run scripts/deploy.js --network goerli

Sie sollten dann in etwa Folgendes sehen:

Contract deployed to address: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570

Bitte speichern Sie diese Adresse. Wir werden sie später im Tutorial verwenden.

Wenn wir zum Goerli Etherscan (opens in a new tab) gehen und nach unserer Vertragsadresse suchen, sollten wir sehen können, dass sie erfolgreich bereitgestellt wurde. Die Transaktion wird in etwa so aussehen:

Die From-Adresse sollte mit Ihrer MetaMask-Konto-Adresse übereinstimmen und die To-Adresse wird Contract Creation anzeigen. Wenn wir in die Transaktion klicken, sehen wir unsere Vertragsadresse im To-Feld.

Glückwunsch! Sie haben gerade einen Smart Contract in einem Ethereum-Testnet bereitgestellt.

Um zu verstehen, was unter der Haube passiert, navigieren wir zum Explorer-Tab in unserem Alchemy-Dashboard (opens in a new tab). Wenn Sie mehrere Alchemy-Apps haben, stellen Sie sicher, dass Sie nach App filtern und Hello World auswählen.

Hier sehen Sie eine Handvoll JSON-RPC-Methoden, die Hardhat/Ethers unter der Haube für uns ausgeführt haben, als wir die Funktion .deploy() aufgerufen haben. Zwei wichtige Methoden hierbei sind eth_sendRawTransaction (opens in a new tab), was die Anfrage ist, unseren Vertrag auf die Goerli-Chain zu schreiben, und eth_getTransactionByHash (opens in a new tab), was eine Anfrage ist, um Informationen über unsere Transaktion anhand des Hashs zu lesen. Um mehr über das Senden von Transaktionen zu erfahren, sehen Sie sich unser Tutorial zum Senden von Transaktionen mit Web3 an.

Teil 2: Interagieren Sie mit Ihrem Smart Contract

Nachdem wir nun erfolgreich einen Smart Contract im Goerli-Netzwerk bereitgestellt haben, wollen wir lernen, wie man mit ihm interagiert.

Erstellen Sie eine interact.js-Datei

Dies ist die Datei, in der wir unser Interaktionsskript schreiben werden. Wir werden die Ethers.js-Bibliothek verwenden, die Sie zuvor in Teil 1 installiert haben.

Erstellen Sie im Ordner scripts/ eine neue Datei namens interact.js und fügen Sie den folgenden Code hinzu:

1// interact.js
2
3const API_KEY = process.env.API_KEY
4const PRIVATE_KEY = process.env.PRIVATE_KEY
5const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS

Aktualisieren Sie Ihre .env-Datei

Wir werden neue Umgebungsvariablen verwenden, daher müssen wir sie in der .env-Datei definieren, die wir zuvor erstellt haben.

Wir müssen eine Definition für unseren Alchemy-API_KEY und die CONTRACT_ADDRESS hinzufügen, unter der Ihr Smart Contract bereitgestellt wurde.

Ihre .env-Datei sollte in etwa so aussehen:

# .env
API_URL = "https://eth-goerli.alchemyapi.io/v2/<your-api-key>"
API_KEY = "<your-api-key>"
PRIVATE_KEY = "<your-metamask-private-key>"
CONTRACT_ADDRESS = "0x<your contract address>"

Holen Sie sich Ihre Vertrags-ABI

Unsere Vertrags- ist die Schnittstelle zur Interaktion mit unserem Smart Contract. Hardhat generiert automatisch eine ABI und speichert sie in HelloWorld.json. Um die ABI zu verwenden, müssen wir den Inhalt parsen, indem wir die folgenden Codezeilen zu unserer Datei interact.js hinzufügen:

1// interact.js
2const contract = require("../artifacts/contracts/HelloWorld.sol/HelloWorld.json")

Wenn Sie die ABI sehen möchten, können Sie sie in Ihrer Konsole ausgeben:

1console.log(JSON.stringify(contract.abi))

Um Ihre ABI in der Konsole ausgeben zu lassen, navigieren Sie zu Ihrem Terminal und führen Sie Folgendes aus:

npx hardhat run scripts/interact.js

Erstellen Sie eine Instanz Ihres Vertrags

Um mit unserem Vertrag zu interagieren, müssen wir eine Vertragsinstanz in unserem Code erstellen. Um dies mit Ethers.js zu tun, müssen wir mit drei Konzepten arbeiten:

  1. Provider – ein Blockchain-Knoten-Anbieter, der Ihnen Lese- und Schreibzugriff auf die Blockchain gibt
  2. Signer – repräsentiert ein Ethereum-Konto, das Transaktionen signieren kann
  3. Contract – ein Ethers.js-Objekt, das einen bestimmten Vertrag repräsentiert, der auf der Blockchain bereitgestellt wurde

Wir verwenden die Vertrags-ABI aus dem vorherigen Schritt, um unsere Instanz des Vertrags zu erstellen:

1// interact.js
2
3// Provider
4const alchemyProvider = new ethers.providers.AlchemyProvider(
5 (network = "goerli"),
6 API_KEY
7)
8
9// Signer
10const signer = new ethers.Wallet(PRIVATE_KEY, alchemyProvider)
11
12// Contract
13const helloWorldContract = new ethers.Contract(
14 CONTRACT_ADDRESS,
15 contract.abi,
16 signer
17)
Alle anzeigen

Erfahren Sie mehr über Provider, Signer und Contracts in der ethers.js-Dokumentation (opens in a new tab).

Lesen Sie die Init-Nachricht

Erinnern Sie sich, als wir unseren Vertrag mit der initMessage = "Hello world!" bereitgestellt haben? Wir werden nun diese in unserem Smart Contract gespeicherte Nachricht lesen und in der Konsole ausgeben.

In JavaScript werden asynchrone Funktionen verwendet, wenn mit Netzwerken interagiert wird. Um mehr über asynchrone Funktionen zu erfahren, lesen Sie diesen Medium-Artikel (opens in a new tab).

Verwenden Sie den folgenden Code, um die Funktion message in unserem Smart Contract aufzurufen und die Init-Nachricht zu lesen:

1// interact.js
2
3// ...
4
5async function main() {
6 const message = await helloWorldContract.message()
7 console.log("The message is: " + message)
8}
9main()
Alle anzeigen

Nachdem wir die Datei mit npx hardhat run scripts/interact.js im Terminal ausgeführt haben, sollten wir diese Antwort sehen:

1The message is: Hello world!

Herzlichen Glückwunsch! Sie haben gerade erfolgreich Smart Contract-Daten aus der Ethereum-Blockchain gelesen, weiter so!

Aktualisieren Sie die Nachricht

Anstatt die Nachricht nur zu lesen, können wir die in unserem Smart Contract gespeicherte Nachricht auch mit der Funktion update aktualisieren! Ziemlich cool, oder?

Um die Nachricht zu aktualisieren, können wir die Funktion update direkt auf unserem instanziierten Contract-Objekt aufrufen:

1// interact.js
2
3// ...
4
5async function main() {
6 const message = await helloWorldContract.message()
7 console.log("The message is: " + message)
8
9 console.log("Updating the message...")
10 const tx = await helloWorldContract.update("This is the new message.")
11 await tx.wait()
12}
13main()
Alle anzeigen

Beachten Sie, dass wir in Zeile 11 einen Aufruf von .wait() auf dem zurückgegebenen Transaktionsobjekt durchführen. Dies stellt sicher, dass unser Skript darauf wartet, dass die Transaktion auf der Blockchain gemint wird, bevor die Funktion beendet wird. Wenn der Aufruf von .wait() nicht enthalten ist, sieht das Skript möglicherweise nicht den aktualisierten message-Wert im Vertrag.

Lesen Sie die neue Nachricht

Sie sollten in der Lage sein, den vorherigen Schritt zu wiederholen, um den aktualisierten message-Wert zu lesen. Nehmen Sie sich einen Moment Zeit und prüfen Sie, ob Sie die notwendigen Änderungen vornehmen können, um diesen neuen Wert auszugeben!

Wenn Sie einen Hinweis benötigen, sehen Sie hier, wie Ihre Datei interact.js zu diesem Zeitpunkt aussehen sollte:

1// interact.js
2
3const API_KEY = process.env.API_KEY
4const PRIVATE_KEY = process.env.PRIVATE_KEY
5const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS
6
7const contract = require("../artifacts/contracts/HelloWorld.sol/HelloWorld.json")
8
9// Provider - Alchemy
10const alchemyProvider = new ethers.providers.AlchemyProvider(
11 (network = "goerli"),
12 API_KEY
13)
14
15// Signer - du
16const signer = new ethers.Wallet(PRIVATE_KEY, alchemyProvider)
17
18// Vertragsinstanz
19const helloWorldContract = new ethers.Contract(
20 CONTRACT_ADDRESS,
21 contract.abi,
22 signer
23)
24
25async function main() {
26 const message = await helloWorldContract.message()
27 console.log("The message is: " + message)
28
29 console.log("Updating the message...")
30 const tx = await helloWorldContract.update("this is the new message")
31 await tx.wait()
32
33 const newMessage = await helloWorldContract.message()
34 console.log("The new message is: " + newMessage)
35}
36
37main()
Alle anzeigen

Führen Sie nun einfach das Skript aus und Sie sollten die alte Nachricht, den Aktualisierungsstatus und die neue Nachricht in Ihrem Terminal sehen können!

npx hardhat run scripts/interact.js --network goerli

1The message is: Hello World!
2Updating the message...
3The new message is: This is the new message.

Während Sie dieses Skript ausführen, werden Sie vielleicht bemerken, dass der Schritt Updating the message... eine Weile dauert, bevor die neue Nachricht geladen wird. Das liegt am Mining-Prozess; wenn Sie neugierig sind und Transaktionen verfolgen möchten, während sie gemint werden, besuchen Sie den Alchemy-Mempool (opens in a new tab), um den Status einer Transaktion zu sehen. Wenn die Transaktion verworfen wird, ist es auch hilfreich, Goerli Etherscan (opens in a new tab) zu überprüfen und nach Ihrem Transaktions-Hash zu suchen.

Teil 3: Veröffentlichen Sie Ihren Smart Contract auf Etherscan

Sie haben die ganze harte Arbeit geleistet, um Ihren Smart Contract zum Leben zu erwecken; jetzt ist es an der Zeit, ihn mit der Welt zu teilen!

Indem Sie Ihren Smart Contract auf Etherscan verifizieren, kann jeder Ihren Quellcode einsehen und mit Ihrem Smart Contract interagieren. Fangen wir an!

Schritt 1: Generieren Sie einen API-Schlüssel in Ihrem Etherscan-Konto

Ein Etherscan-API-Schlüssel ist erforderlich, um zu verifizieren, dass Sie der Eigentümer des Smart Contracts sind, den Sie veröffentlichen möchten.

Wenn Sie noch kein Etherscan-Konto haben, registrieren Sie sich für ein Konto (opens in a new tab).

Sobald Sie eingeloggt sind, suchen Sie Ihren Benutzernamen in der Navigationsleiste, fahren Sie mit der Maus darüber und wählen Sie die Schaltfläche My profile.

Auf Ihrer Profilseite sollten Sie eine seitliche Navigationsleiste sehen. Wählen Sie in der seitlichen Navigationsleiste API Keys. Klicken Sie anschließend auf die Schaltfläche „Add“, um einen neuen API-Schlüssel zu erstellen, nennen Sie Ihre App hello-world und klicken Sie auf die Schaltfläche Create New API Key.

Ihr neuer API-Schlüssel sollte in der API-Schlüssel-Tabelle erscheinen. Kopieren Sie den API-Schlüssel in Ihre Zwischenablage.

Als Nächstes müssen wir den Etherscan-API-Schlüssel zu unserer .env-Datei hinzufügen.

Nach dem Hinzufügen sollte Ihre .env-Datei wie folgt aussehen:

1API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key"
2PUBLIC_KEY = "your-public-account-address"
3PRIVATE_KEY = "your-private-account-address"
4CONTRACT_ADDRESS = "your-contract-address"
5ETHERSCAN_API_KEY = "your-etherscan-key"

Mit Hardhat bereitgestellte Smart Contracts

Installieren von hardhat-etherscan

Die Veröffentlichung Ihres Vertrags auf Etherscan mit Hardhat ist unkompliziert. Sie müssen zunächst das Plugin hardhat-etherscan installieren, um loszulegen. hardhat-etherscan wird den Quellcode und die ABI des Smart Contracts automatisch auf Etherscan verifizieren. Um dies hinzuzufügen, führen Sie im Verzeichnis hello-world Folgendes aus:

1npm install --save-dev @nomiclabs/hardhat-etherscan

Sobald es installiert ist, fügen Sie die folgende Anweisung oben in Ihrer hardhat.config.js ein und fügen Sie die Etherscan-Konfigurationsoptionen hinzu:

1// hardhat.config.js
2
3require("dotenv").config()
4require("@nomiclabs/hardhat-ethers")
5require("@nomiclabs/hardhat-etherscan")
6
7const { API_URL, PRIVATE_KEY, ETHERSCAN_API_KEY } = process.env
8
9module.exports = {
10 solidity: "0.7.3",
11 defaultNetwork: "goerli",
12 networks: {
13 hardhat: {},
14 goerli: {
15 url: API_URL,
16 accounts: [`0x${PRIVATE_KEY}`],
17 },
18 },
19 etherscan: {
20 // Dein API-Schlüssel für Etherscan
21 // Erhalte einen unter https://etherscan.io/
22 apiKey: ETHERSCAN_API_KEY,
23 },
24}
Alle anzeigen

Verifizieren Sie Ihren Smart Contract auf Etherscan

Stellen Sie sicher, dass alle Dateien gespeichert und alle .env-Variablen korrekt konfiguriert sind.

Führen Sie die Aufgabe verify aus und übergeben Sie die Vertragsadresse sowie das Netzwerk, in dem er bereitgestellt wurde:

1npx hardhat verify --network goerli DEPLOYED_CONTRACT_ADDRESS 'Hello World!'

Stellen Sie sicher, dass DEPLOYED_CONTRACT_ADDRESS die Adresse Ihres bereitgestellten Smart Contracts im Goerli-Testnet ist. Außerdem muss das letzte Argument ('Hello World!') derselbe Zeichenfolgenwert sein, der während des Bereitstellungsschritts in Teil 1 verwendet wurde.

Wenn alles gut geht, sehen Sie die folgende Nachricht in Ihrem Terminal:

1Successfully submitted source code for contract
2contracts/HelloWorld.sol:HelloWorld at 0xdeployed-contract-address
3for verification on Etherscan. Waiting for verification result...
4
5
6Successfully verified contract HelloWorld on Etherscan.
7https: // goerli.etherscan.io/address/<contract-address>#contracts

Herzlichen Glückwunsch! Ihr Smart Contract-Code ist auf Etherscan!

Sehen Sie sich Ihren Smart Contract auf Etherscan an!

Wenn Sie zu dem in Ihrem Terminal angegebenen Link navigieren, sollten Sie Ihren Smart Contract-Code und die auf Etherscan veröffentlichte ABI sehen können!

Wahooo – Sie haben es geschafft, Champion! Jetzt kann jeder Ihren Smart Contract aufrufen oder in ihn schreiben! Wir können es kaum erwarten zu sehen, was Sie als Nächstes bauen!

Teil 4 – Integration Ihres Smart Contracts in das Frontend

Am Ende dieses Tutorials werden Sie wissen, wie man:

  • Ein MetaMask-Wallet mit Ihrer Dapp verbindet
  • Daten aus Ihrem Smart Contract mithilfe der Alchemy Web3 (opens in a new tab)-API liest
  • Ethereum-Transaktionen mit MetaMask signiert

Für diese Dapp werden wir React (opens in a new tab) als unser Frontend-Framework verwenden. Es ist jedoch wichtig zu beachten, dass wir nicht viel Zeit darauf verwenden werden, die Grundlagen zu erklären, da wir uns hauptsächlich darauf konzentrieren, Web3-Funktionalität in unser Projekt zu integrieren.

Als Voraussetzung sollten Sie über grundlegende React-Kenntnisse verfügen. Falls nicht, empfehlen wir, das offizielle Intro to React-Tutorial (opens in a new tab) zu absolvieren.

Klonen der Startdateien

Gehen Sie zunächst zum hello-world-part-four GitHub-Repository (opens in a new tab), um die Startdateien für dieses Projekt zu erhalten, und klonen Sie dieses Repository auf Ihren lokalen Computer.

Öffnen Sie das geklonte Repository lokal. Beachten Sie, dass es zwei Ordner enthält: starter-files und completed.

  • starter-fileswir werden in diesem Verzeichnis arbeiten, wir werden die Benutzeroberfläche mit Ihrem Ethereum-Wallet und dem Smart Contract verbinden, den wir in Teil 3 auf Etherscan veröffentlicht haben.
  • completed enthält das gesamte abgeschlossene Tutorial und sollte nur als Referenz verwendet werden, falls Sie nicht weiterkommen.

Öffnen Sie als Nächstes Ihre Kopie von starter-files in Ihrem bevorzugten Code-Editor und navigieren Sie dann in den Ordner src.

Der gesamte Code, den wir schreiben werden, befindet sich im Ordner src. Wir werden die Komponente HelloWorld.js und die JavaScript-Dateien util/interact.js bearbeiten, um unserem Projekt Web3-Funktionalität zu verleihen.

Überprüfen der Startdateien

Bevor wir mit dem Programmieren beginnen, wollen wir uns ansehen, was uns in den Startdateien zur Verfügung gestellt wird.

Starten Sie Ihr React-Projekt

Beginnen wir damit, das React-Projekt in unserem Browser auszuführen. Das Schöne an React ist, dass alle Änderungen, die wir speichern, live in unserem Browser aktualisiert werden, sobald unser Projekt im Browser läuft.

Um das Projekt zum Laufen zu bringen, navigieren Sie zum Stammverzeichnis des Ordners starter-files und führen Sie npm install in Ihrem Terminal aus, um die Abhängigkeiten des Projekts zu installieren:

cd starter-files
npm install

Sobald die Installation abgeschlossen ist, führen Sie npm start in Ihrem Terminal aus:

npm start

Dadurch sollte sich http://localhost:3000/ (opens in a new tab) in Ihrem Browser öffnen, wo Sie das Frontend für unser Projekt sehen. Es sollte aus einem Feld (einem Ort zum Aktualisieren der in Ihrem Smart Contract gespeicherten Nachricht), einer Schaltfläche „Connect Wallet“ und einer Schaltfläche „Update“ bestehen.

Wenn Sie versuchen, auf eine der Schaltflächen zu klicken, werden Sie feststellen, dass sie nicht funktionieren – das liegt daran, dass wir ihre Funktionalität erst noch programmieren müssen.

Die Komponente HelloWorld.js

Gehen wir in unserem Editor zurück in den Ordner src und öffnen die Datei HelloWorld.js. Es ist extrem wichtig, dass wir alles in dieser Datei verstehen, da es sich um die primäre React-Komponente handelt, an der wir arbeiten werden.

Oben in dieser Datei werden Sie feststellen, dass wir mehrere Importanweisungen haben, die erforderlich sind, um unser Projekt zum Laufen zu bringen, einschließlich der React-Bibliothek, der Hooks useEffect und useState, einiger Elemente aus ./util/interact.js (wir werden sie bald genauer beschreiben!) und des Alchemy-Logos.

1// HelloWorld.js
2
3import React from "react"
4import { useEffect, useState } from "react"
5import {
6 helloWorldContract,
7 connectWallet,
8 updateMessage,
9 loadCurrentMessage,
10 getCurrentWalletConnected,
11} from "./util/interact.js"
12
13import alchemylogo from "./alchemylogo.svg"
Alle anzeigen

Als Nächstes haben wir unsere Zustandsvariablen, die wir nach bestimmten Ereignissen aktualisieren werden.

1// HelloWorld.js
2
3// Zustandsvariablen
4const [walletAddress, setWallet] = useState("")
5const [status, setStatus] = useState("")
6const [message, setMessage] = useState("No connection to the network.")
7const [newMessage, setNewMessage] = useState("")

Hier ist, was jede der Variablen darstellt:

  • walletAddress – ein String, der die Wallet-Adresse des Benutzers speichert
  • status – ein String, der eine hilfreiche Nachricht speichert, die den Benutzer bei der Interaktion mit der Dapp anleitet
  • message – ein String, der die aktuelle Nachricht im Smart Contract speichert
  • newMessage – ein String, der die neue Nachricht speichert, die in den Smart Contract geschrieben wird

Nach den Zustandsvariablen sehen Sie fünf nicht implementierte Funktionen: useEffect, addSmartContractListener, addWalletListener, connectWalletPressed und onUpdatePressed. Wir erklären unten, was sie tun:

1// HelloWorld.js
2
3// wird nur einmal aufgerufen
4useEffect(async () => {
5 // TODO: implementieren
6}, [])
7
8function addSmartContractListener() {
9 // TODO: implementieren
10}
11
12function addWalletListener() {
13 // TODO: implementieren
14}
15
16const connectWalletPressed = async () => {
17 // TODO: implementieren
18}
19
20const onUpdatePressed = async () => {
21 // TODO: implementieren
22}
Alle anzeigen
  • useEffect (opens in a new tab) – dies ist ein React-Hook, der aufgerufen wird, nachdem Ihre Komponente gerendert wurde. Da ihm ein leeres Array [] als Prop übergeben wird (siehe Zeile 4), wird er nur beim ersten Rendern der Komponente aufgerufen. Hier laden wir die aktuelle in unserem Smart Contract gespeicherte Nachricht, rufen unsere Smart Contract- und Wallet-Listener auf und aktualisieren unsere Benutzeroberfläche, um widerzuspiegeln, ob bereits ein Wallet verbunden ist.
  • addSmartContractListener – diese Funktion richtet einen Listener ein, der auf das Ereignis UpdatedMessages unseres HelloWorld-Vertrags achtet und unsere Benutzeroberfläche aktualisiert, wenn die Nachricht in unserem Smart Contract geändert wird.
  • addWalletListener – diese Funktion richtet einen Listener ein, der Änderungen im Status des MetaMask-Wallets des Benutzers erkennt, z. B. wenn der Benutzer sein Wallet trennt oder die Adresse wechselt.
  • connectWalletPressed – diese Funktion wird aufgerufen, um das MetaMask-Wallet des Benutzers mit unserer Dapp zu verbinden.
  • onUpdatePressed – diese Funktion wird aufgerufen, wenn der Benutzer die im Smart Contract gespeicherte Nachricht aktualisieren möchte.

Gegen Ende dieser Datei haben wir die Benutzeroberfläche unserer Komponente.

1// HelloWorld.js
2
3// die UI unserer Komponente
4return (
5 <div id="container">
6 <img id="logo" src={alchemylogo}></img>
7 <button id="walletButton" onClick={connectWalletPressed}>
8 {walletAddress.length > 0 ? (
9 "Connected: " +
10 String(walletAddress).substring(0, 6) +
11 "..." +
12 String(walletAddress).substring(38)
13 ) : (
14 <span>Connect Wallet</span>
15 )}
16 </button>
17
18 <h2 style={{ paddingTop: "50px" }}>Current Message:</h2>
19 <p>{message}</p>
20
21 <h2 style={{ paddingTop: "18px" }}>New Message:</h2>
22
23 <div>
24 <input
25 type="text"
26 placeholder="Update the message in your smart contract."
27 onChange={(e) => setNewMessage(e.target.value)}
28 value={newMessage}
29 />
30 <p id="status">{status}</p>
31
32 <button id="publishButton" onClick={onUpdatePressed}>
33 Update
34 </button>
35
36</div>
37
38</div>
39)
Alle anzeigen

Wenn Sie diesen Code sorgfältig prüfen, werden Sie feststellen, wo wir unsere verschiedenen Zustandsvariablen in unserer Benutzeroberfläche verwenden:

  • In den Zeilen 6-12 zeigen wir, wenn das Wallet des Benutzers verbunden ist (d. h. walletAddress.length > 0), eine gekürzte Version der walletAddress des Benutzers in der Schaltfläche mit der ID „walletButton“ an; andernfalls steht dort einfach „Connect Wallet“.
  • In Zeile 17 zeigen wir die aktuelle im Smart Contract gespeicherte Nachricht an, die im String message erfasst ist.
  • In den Zeilen 23-26 verwenden wir eine gesteuerte Komponente (opens in a new tab), um unsere Zustandsvariable newMessage zu aktualisieren, wenn sich die Eingabe im Textfeld ändert.

Zusätzlich zu unseren Zustandsvariablen werden Sie auch sehen, dass die Funktionen connectWalletPressed und onUpdatePressed aufgerufen werden, wenn auf die Schaltflächen mit den IDs publishButton bzw. walletButton geklickt wird.

Lassen Sie uns abschließend klären, wo diese Komponente HelloWorld.js hinzugefügt wird.

Wenn Sie zur Datei App.js gehen, der Hauptkomponente in React, die als Container für alle anderen Komponenten fungiert, werden Sie sehen, dass unsere Komponente HelloWorld.js in Zeile 7 eingefügt wird.

Zu guter Letzt schauen wir uns noch eine weitere Datei an, die Ihnen zur Verfügung gestellt wird: die Datei interact.js.

Die Datei interact.js

Da wir uns an das M-V-C (opens in a new tab)-Paradigma halten wollen, benötigen wir eine separate Datei, die alle unsere Funktionen zur Verwaltung der Logik, Daten und Regeln unserer Dapp enthält, um diese Funktionen dann in unser Frontend (unsere Komponente HelloWorld.js) exportieren zu können.

👆🏽Genau das ist der Zweck unserer Datei interact.js!

Navigieren Sie zum Ordner util in Ihrem Verzeichnis src, und Sie werden feststellen, dass wir eine Datei namens interact.js eingefügt haben, die alle unsere Smart Contract-Interaktions- und Wallet-Funktionen sowie Variablen enthalten wird.

1// interact.js
2
3// export const helloWorldContract;
4
5export const loadCurrentMessage = async () => {}
6
7export const connectWallet = async () => {}
8
9const getCurrentWalletConnected = async () => {}
10
11export const updateMessage = async (message) => {}
Alle anzeigen

Sie werden oben in der Datei feststellen, dass wir das Objekt helloWorldContract auskommentiert haben. Später in diesem Tutorial werden wir dieses Objekt einkommentieren und unseren Smart Contract in dieser Variablen instanziieren, die wir dann in unsere Komponente HelloWorld.js exportieren werden.

Die vier nicht implementierten Funktionen nach unserem Objekt helloWorldContract tun Folgendes:

  • loadCurrentMessage – diese Funktion übernimmt die Logik zum Laden der aktuellen im Smart Contract gespeicherten Nachricht. Sie führt einen Lese-Aufruf an den Hello World Smart Contract mithilfe der Alchemy Web3-API (opens in a new tab) durch.
  • connectWallet – diese Funktion verbindet das MetaMask des Benutzers mit unserer Dapp.
  • getCurrentWalletConnected – diese Funktion prüft beim Laden der Seite, ob bereits ein Ethereum-Konto mit unserer Dapp verbunden ist, und aktualisiert unsere Benutzeroberfläche entsprechend.
  • updateMessage – diese Funktion aktualisiert die im Smart Contract gespeicherte Nachricht. Sie führt einen Schreib-Aufruf an den Hello World Smart Contract durch, sodass das MetaMask-Wallet des Benutzers eine Ethereum-Transaktion signieren muss, um die Nachricht zu aktualisieren.

Da wir nun verstehen, womit wir arbeiten, wollen wir herausfinden, wie wir aus unserem Smart Contract lesen können!

Schritt 3: Lesen aus Ihrem Smart Contract

Um aus Ihrem Smart Contract zu lesen, müssen Sie Folgendes erfolgreich einrichten:

  • Eine API-Verbindung zur Ethereum-Chain
  • Eine geladene Instanz Ihres Smart Contracts
  • Eine Funktion zum Aufrufen Ihrer Smart Contract-Funktion
  • Einen Listener, der auf Aktualisierungen achtet, wenn sich die Daten ändern, die Sie aus dem Smart Contract lesen

Das mag nach vielen Schritten klingen, aber keine Sorge! Wir werden Sie Schritt für Schritt durch jeden einzelnen führen! :)

Herstellen einer API-Verbindung zur Ethereum-Chain

Erinnern Sie sich daran, wie wir in Teil 2 dieses Tutorials unseren Alchemy Web3-Schlüssel verwendet haben, um aus unserem Smart Contract zu lesen (opens in a new tab)? Sie benötigen auch in Ihrer Dapp einen Alchemy Web3-Schlüssel, um von der Chain zu lesen.

Falls Sie es noch nicht haben, installieren Sie zunächst Alchemy Web3 (opens in a new tab), indem Sie zum Stammverzeichnis Ihrer starter-files navigieren und Folgendes in Ihrem Terminal ausführen:

1npm install @alch/alchemy-web3

Alchemy Web3 (opens in a new tab) ist ein Wrapper um Web3.js (opens in a new tab), der erweiterte API-Methoden und andere entscheidende Vorteile bietet, um Ihnen das Leben als Web3-Entwickler zu erleichtern. Es ist so konzipiert, dass es nur minimale Konfiguration erfordert, sodass Sie es sofort in Ihrer App verwenden können!

Installieren Sie dann das Paket dotenv (opens in a new tab) in Ihrem Projektverzeichnis, damit wir einen sicheren Ort haben, um unseren API-Schlüssel zu speichern, nachdem wir ihn abgerufen haben.

1npm install dotenv --save

Für unsere Dapp werden wir unseren Websockets-API-Schlüssel verwenden anstelle unseres HTTP-API-Schlüssels, da er es uns ermöglicht, einen Listener einzurichten, der erkennt, wenn sich die im Smart Contract gespeicherte Nachricht ändert.

Sobald Sie Ihren API-Schlüssel haben, erstellen Sie eine .env-Datei in Ihrem Stammverzeichnis und fügen Sie Ihre Alchemy Websockets-URL hinzu. Danach sollte Ihre .env-Datei wie folgt aussehen:

1REACT_APP_ALCHEMY_KEY = wss: // eth-goerli.ws.alchemyapi.io/v2/<key>

Jetzt sind wir bereit, unseren Alchemy Web3-Endpunkt in unserer Dapp einzurichten! Gehen wir zurück zu unserer interact.js, die sich in unserem Ordner util befindet, und fügen den folgenden Code oben in der Datei hinzu:

1// interact.js
2
3require("dotenv").config()
4const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY
5const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
6const web3 = createAlchemyWeb3(alchemyKey)
7
8// export const helloWorldContract;

Oben haben wir zuerst den Alchemy-Schlüssel aus unserer .env-Datei importiert und dann unseren alchemyKey an createAlchemyWeb3 übergeben, um unseren Alchemy Web3-Endpunkt einzurichten.

Da dieser Endpunkt nun bereit ist, ist es an der Zeit, unseren Smart Contract zu laden!

Laden Ihres Hello World Smart Contracts

Um Ihren Hello World Smart Contract zu laden, benötigen Sie dessen Vertragsadresse und ABI, die beide auf Etherscan zu finden sind, wenn Sie Teil 3 dieses Tutorials abgeschlossen haben.

So erhalten Sie Ihre Vertrags-ABI von Etherscan

Wenn Sie Teil 3 dieses Tutorials übersprungen haben, können Sie den HelloWorld-Vertrag mit der Adresse 0x6f3f635A9762B47954229Ea479b4541eAF402A6A (opens in a new tab) verwenden. Seine ABI finden Sie hier (opens in a new tab).

Eine Vertrags-ABI ist erforderlich, um anzugeben, welche Funktion ein Vertrag aufrufen wird, und um sicherzustellen, dass die Funktion Daten in dem von Ihnen erwarteten Format zurückgibt. Sobald wir unsere Vertrags-ABI kopiert haben, speichern wir sie als JSON-Datei namens contract-abi.json in Ihrem Verzeichnis src.

Ihre contract-abi.json sollte in Ihrem src-Ordner gespeichert werden.

Ausgestattet mit unserer Vertragsadresse, ABI und dem Alchemy Web3-Endpunkt können wir die contract-Methode (opens in a new tab) verwenden, um eine Instanz unseres Smart Contracts zu laden. Importieren Sie Ihre Vertrags-ABI in die Datei interact.js und fügen Sie Ihre Vertragsadresse hinzu.

1// interact.js
2
3const contractABI = require("../contract-abi.json")
4const contractAddress = "0x6f3f635A9762B47954229Ea479b4541eAF402A6A"

Wir können nun endlich unsere Variable helloWorldContract einkommentieren und den Smart Contract über unseren AlchemyWeb3-Endpunkt laden:

1// interact.js
2export const helloWorldContract = new web3.eth.Contract(
3 contractABI,
4 contractAddress
5)

Zusammenfassend sollten die ersten 12 Zeilen Ihrer interact.js nun so aussehen:

1// interact.js
2
3require("dotenv").config()
4const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY
5const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
6const web3 = createAlchemyWeb3(alchemyKey)
7
8const contractABI = require("../contract-abi.json")
9const contractAddress = "0x6f3f635A9762B47954229Ea479b4541eAF402A6A"
10
11export const helloWorldContract = new web3.eth.Contract(
12 contractABI,
13 contractAddress
14)
Alle anzeigen

Da wir unseren Vertrag nun geladen haben, können wir unsere Funktion loadCurrentMessage implementieren!

Implementierung von loadCurrentMessage in Ihrer Datei interact.js

Diese Funktion ist super einfach. Wir werden einen einfachen asynchronen Web3-Aufruf durchführen, um aus unserem Vertrag zu lesen. Unsere Funktion wird die im Smart Contract gespeicherte Nachricht zurückgeben:

Aktualisieren Sie die loadCurrentMessage in Ihrer Datei interact.js wie folgt:

1// interact.js
2
3export const loadCurrentMessage = async () => {
4 const message = await helloWorldContract.methods.message().call()
5 return message
6}

Da wir diesen Smart Contract in unserer Benutzeroberfläche anzeigen möchten, aktualisieren wir die Funktion useEffect in unserer Komponente HelloWorld.js wie folgt:

1// HelloWorld.js
2
3// wird nur einmal aufgerufen
4useEffect(async () => {
5 const message = await loadCurrentMessage()
6 setMessage(message)
7}, [])

Beachten Sie, dass unsere loadCurrentMessage nur einmal während des ersten Renderns der Komponente aufgerufen werden soll. Wir werden bald addSmartContractListener implementieren, um die Benutzeroberfläche automatisch zu aktualisieren, nachdem sich die Nachricht im Smart Contract geändert hat.

Bevor wir uns in unseren Listener stürzen, schauen wir uns an, was wir bisher haben! Speichern Sie Ihre Dateien HelloWorld.js und interact.js und gehen Sie dann zu http://localhost:3000/ (opens in a new tab)

Sie werden feststellen, dass die aktuelle Nachricht nicht mehr „No connection to the network.“ lautet. Stattdessen spiegelt sie die im Smart Contract gespeicherte Nachricht wider. Genial!

Ihre Benutzeroberfläche sollte nun die im Smart Contract gespeicherte Nachricht widerspiegeln

Apropos Listener...

Implementierung von addSmartContractListener

Wenn Sie an die Datei HelloWorld.sol zurückdenken, die wir in Teil 1 dieser Tutorial-Reihe (opens in a new tab) geschrieben haben, werden Sie sich erinnern, dass es ein Smart Contract-Ereignis namens UpdatedMessages gibt, das ausgegeben wird, nachdem die Funktion update unseres Smart Contracts aufgerufen wurde (siehe Zeilen 9 und 27):

1// HelloWorld.sol
2
3// Gibt die Version von Solidity unter Verwendung der semantischen Versionierung an.
4// Erfahre mehr: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma
5pragma solidity ^0.7.3;
6
7// Definiert einen Vertrag namens `HelloWorld`.
8// Ein Vertrag ist eine Sammlung von Funktionen und Daten (seinem Zustand). Sobald er bereitgestellt ist, befindet sich ein Vertrag an einer bestimmten Adresse auf der Ethereum-Blockchain. Erfahre mehr: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html
9contract HelloWorld {
10
11 // Wird emittiert, wenn die update-Funktion aufgerufen wird
12 // Smart-Contract-Events sind eine Möglichkeit für deinen Vertrag, dem Frontend deiner App mitzuteilen, dass etwas auf der Blockchain passiert ist. Das Frontend kann auf bestimmte Events 'hören' und Maßnahmen ergreifen, wenn sie eintreten.
13 event UpdatedMessages(string oldStr, string newStr);
14
15 // Deklariert eine Zustandsvariable `message` vom Typ `string`.
16 // Zustandsvariablen sind Variablen, deren Werte dauerhaft im Vertragsspeicher gespeichert werden. Das Schlüsselwort `public` macht Variablen von außerhalb eines Vertrags zugänglich und erstellt eine Funktion, die andere Verträge oder Clients aufrufen können, um auf den Wert zuzugreifen.
17 string public message;
18
19 // Ähnlich wie in vielen klassenbasierten objektorientierten Sprachen ist ein Konstruktor eine spezielle Funktion, die nur bei der Vertragserstellung ausgeführt wird.
20 // Konstruktoren werden verwendet, um die Daten des Vertrags zu initialisieren. Erfahre mehr:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors
21 constructor(string memory initMessage) {
22
23 // Akzeptiert ein String-Argument `initMessage` und setzt den Wert in die Speichervariable `message` des Vertrags).
24 message = initMessage;
25 }
26
27 // Eine öffentliche Funktion, die ein String-Argument akzeptiert und die Speichervariable `message` aktualisiert.
28 function update(string memory newMessage) public {
29 string memory oldMsg = message;
30 message = newMessage;
31 emit UpdatedMessages(oldMsg, newMessage);
32 }
33}
Alle anzeigen

Smart Contract-Ereignisse sind eine Möglichkeit für Ihren Vertrag, Ihrer Frontend-Anwendung mitzuteilen, dass etwas auf der Blockchain passiert ist (d. h. es gab ein Ereignis). Die Anwendung kann auf bestimmte Ereignisse „hören“ und Maßnahmen ergreifen, wenn sie eintreten.

Die Funktion addSmartContractListener wird speziell auf das Ereignis UpdatedMessages unseres Hello World Smart Contracts hören und unsere Benutzeroberfläche aktualisieren, um die neue Nachricht anzuzeigen.

Ändern Sie addSmartContractListener wie folgt:

1// HelloWorld.js
2
3function addSmartContractListener() {
4 helloWorldContract.events.UpdatedMessages({}, (error, data) => {
5 if (error) {
6 setStatus("😥 " + error.message)
7 } else {
8 setMessage(data.returnValues[1])
9 setNewMessage("")
10 setStatus("🎉 Your message has been updated!")
11 }
12 })
13}
Alle anzeigen

Lassen Sie uns aufschlüsseln, was passiert, wenn der Listener ein Ereignis erkennt:

  • Wenn bei der Ausgabe des Ereignisses ein Fehler auftritt, wird dies in der Benutzeroberfläche über unsere Zustandsvariable status widergespiegelt.
  • Andernfalls verwenden wir das zurückgegebene data-Objekt. data.returnValues ist ein bei null indiziertes Array, bei dem das erste Element im Array die vorherige Nachricht und das zweite Element die aktualisierte Nachricht speichert. Insgesamt setzen wir bei einem erfolgreichen Ereignis unseren String message auf die aktualisierte Nachricht, leeren den String newMessage und aktualisieren unsere Zustandsvariable status, um widerzuspiegeln, dass eine neue Nachricht in unserem Smart Contract veröffentlicht wurde.

Lassen Sie uns abschließend unseren Listener in unserer Funktion useEffect aufrufen, damit er beim ersten Rendern der Komponente HelloWorld.js initialisiert wird. Insgesamt sollte Ihre Funktion useEffect so aussehen:

1// HelloWorld.js
2
3useEffect(async () => {
4 const message = await loadCurrentMessage()
5 setMessage(message)
6 addSmartContractListener()
7}, [])

Da wir nun aus unserem Smart Contract lesen können, wäre es großartig herauszufinden, wie wir auch in ihn schreiben können! Um jedoch in unsere Dapp zu schreiben, muss zunächst ein Ethereum-Wallet damit verbunden sein.

Als Nächstes werden wir also die Einrichtung unseres Ethereum-Wallets (MetaMask) in Angriff nehmen und es dann mit unserer Dapp verbinden!

Schritt 4: Einrichten Ihres Ethereum-Wallets

Um etwas in die Ethereum-Chain zu schreiben, müssen Benutzer Transaktionen mit den Private-Keys ihres virtuellen Wallets signieren. Für dieses Tutorial verwenden wir MetaMask (opens in a new tab), ein virtuelles Wallet im Browser, das zur Verwaltung Ihrer Ethereum-Kontoadresse verwendet wird, da es das Signieren von Transaktionen für den Endbenutzer extrem einfach macht.

Wenn Sie mehr darüber erfahren möchten, wie Transaktionen auf Ethereum funktionieren, sehen Sie sich diese Seite der Ethereum Foundation an.

MetaMask herunterladen

Sie können hier (opens in a new tab) kostenlos ein MetaMask-Konto herunterladen und erstellen. Wenn Sie ein Konto erstellen oder bereits eines haben, stellen Sie sicher, dass Sie oben rechts zum „Goerli Test Network“ wechseln (damit wir nicht mit echtem Geld hantieren).

Ether von einem Faucet hinzufügen

Um eine Transaktion auf der Ethereum-Blockchain zu signieren, benötigen wir etwas Fake-ETH. Um ETH zu erhalten, können Sie zu FaucETH (opens in a new tab) gehen und Ihre Goerli-Kontoadresse eingeben, auf „Request funds“ klicken, dann im Dropdown-Menü „Ethereum Testnet Goerli“ auswählen und schließlich erneut auf die Schaltfläche „Request funds“ klicken. Sie sollten kurz darauf ETH in Ihrem MetaMask-Konto sehen!

Überprüfen Sie Ihr Guthaben

Um sicherzustellen, dass unser Guthaben vorhanden ist, führen wir eine eth_getBalance (opens in a new tab)-Anfrage mit dem Composer-Tool von Alchemy (opens in a new tab) durch. Dies gibt die Menge an ETH in unserem Wallet zurück. Nachdem Sie Ihre MetaMask-Kontoadresse eingegeben und auf „Send Request“ geklickt haben, sollten Sie eine Antwort wie diese sehen:

1{"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"}

HINWEIS: Dieses Ergebnis ist in Wei, nicht in ETH. Wei wird als kleinste Stückelung von Ether verwendet. Die Umrechnung von Wei in ETH lautet: 1 ETH = 10¹⁸ Wei. Wenn wir also 0xde0b6b3a7640000 in eine Dezimalzahl umwandeln, erhalten wir 1*10¹⁸, was 1 ETH entspricht.

Puh! Unser Fake-Geld ist komplett da! 🤑

Schritt 5: Verbinden Sie MetaMask mit Ihrer Benutzeroberfläche

Da unser MetaMask-Wallet nun eingerichtet ist, verbinden wir unsere Dapp damit!

Die Funktion connectWallet

Lassen Sie uns in unserer Datei interact.js die Funktion connectWallet implementieren, die wir dann in unserer Komponente HelloWorld.js aufrufen können.

Ändern wir connectWallet wie folgt:

1// interact.js
2
3export const connectWallet = async () => {
4 if (window.ethereum) {
5 try {
6 const addressArray = await window.ethereum.request({
7 method: "eth_requestAccounts",
8 })
9 const obj = {
10 status: "👆🏽 Write a message in the text-field above.",
11 address: addressArray[0],
12 }
13 return obj
14 } catch (err) {
15 return {
16 address: "",
17 status: "😥 " + err.message,
18 }
19 }
20 } else {
21 return {
22 address: "",
23 status: (
24 <span>
25 <p>
26 {" "}
27 🦊 <a target="_blank" href={`https://metamask.io/download`}>
28 You must install MetaMask, a virtual Ethereum wallet, in your
29 browser.
30 </a>
31 </p>
32 </span>
33 ),
34 }
35 }
36}
Alle anzeigen

Was genau macht dieser riesige Codeblock also?

Nun, zuerst wird geprüft, ob window.ethereum in Ihrem Browser aktiviert ist.

window.ethereum ist eine globale API, die von MetaMask und anderen Wallet-Anbietern injiziert wird und es Websites ermöglicht, die Ethereum-Konten der Benutzer anzufordern. Wenn dies genehmigt wird, kann sie Daten aus den Blockchains lesen, mit denen der Benutzer verbunden ist, und vorschlagen, dass der Benutzer Nachrichten und Transaktionen signiert. Weitere Informationen finden Sie in der MetaMask-Dokumentation (opens in a new tab)!

Wenn window.ethereum nicht vorhanden ist, bedeutet das, dass MetaMask nicht installiert ist. Dies führt dazu, dass ein JSON-Objekt zurückgegeben wird, bei dem die zurückgegebene address ein leerer String ist und das JSX-Objekt status meldet, dass der Benutzer MetaMask installieren muss.

Wenn window.ethereum vorhanden ist, wird es interessant.

Mithilfe einer try/catch-Schleife versuchen wir, eine Verbindung zu MetaMask herzustellen, indem wir window.ethereum.request({ method: "eth_requestAccounts" }); (opens in a new tab) aufrufen. Der Aufruf dieser Funktion öffnet MetaMask im Browser, wobei der Benutzer aufgefordert wird, sein Wallet mit Ihrer Dapp zu verbinden.

  • Wenn der Benutzer sich für eine Verbindung entscheidet, gibt method: "eth_requestAccounts" ein Array zurück, das alle Kontoadressen des Benutzers enthält, die mit der Dapp verbunden sind. Insgesamt gibt unsere Funktion connectWallet ein JSON-Objekt zurück, das die erste address in diesem Array (siehe Zeile 9) und eine status-Nachricht enthält, die den Benutzer auffordert, eine Nachricht in den Smart Contract zu schreiben.
  • Wenn der Benutzer die Verbindung ablehnt, enthält das JSON-Objekt einen leeren String für die zurückgegebene address und eine status-Nachricht, die widerspiegelt, dass der Benutzer die Verbindung abgelehnt hat.

Nachdem wir nun diese Funktion connectWallet geschrieben haben, besteht der nächste Schritt darin, sie in unserer Komponente HelloWorld.js aufzurufen.

Fügen Sie die Funktion connectWallet zu Ihrer UI-Komponente HelloWorld.js hinzu

Navigieren Sie zur Funktion connectWalletPressed in HelloWorld.js und aktualisieren Sie sie wie folgt:

1// HelloWorld.js
2
3const connectWalletPressed = async () => {
4 const walletResponse = await connectWallet()
5 setStatus(walletResponse.status)
6 setWallet(walletResponse.address)
7}

Fällt Ihnen auf, wie der Großteil unserer Funktionalität aus der Datei interact.js von unserer Komponente HelloWorld.js abstrahiert wird? Dies geschieht, damit wir das M-V-C-Paradigma einhalten!

In connectWalletPressed führen wir einfach einen await-Aufruf an unsere importierte Funktion connectWallet durch und aktualisieren anhand ihrer Antwort unsere Variablen status und walletAddress über ihre State-Hooks.

Speichern wir nun beide Dateien (HelloWorld.js und interact.js) und testen unsere bisherige Benutzeroberfläche.

Öffnen Sie Ihren Browser auf der Seite http://localhost:3000/ (opens in a new tab) und klicken Sie oben rechts auf der Seite auf die Schaltfläche „Connect Wallet“.

Wenn Sie MetaMask installiert haben, sollten Sie aufgefordert werden, Ihr Wallet mit Ihrer Dapp zu verbinden. Akzeptieren Sie die Einladung zur Verbindung.

Sie sollten sehen, dass die Wallet-Schaltfläche nun anzeigt, dass Ihre Adresse verbunden ist! Jaaaaaa 🔥

Versuchen Sie als Nächstes, die Seite zu aktualisieren... das ist seltsam. Unsere Wallet-Schaltfläche fordert uns auf, MetaMask zu verbinden, obwohl es bereits verbunden ist...

Aber keine Angst! Wir können das leicht beheben, indem wir getCurrentWalletConnected implementieren, was prüft, ob bereits eine Adresse mit unserer Dapp verbunden ist, und unsere Benutzeroberfläche entsprechend aktualisiert!

Die Funktion getCurrentWalletConnected

Aktualisieren Sie Ihre Funktion getCurrentWalletConnected in der Datei interact.js wie folgt:

1// interact.js
2
3export const getCurrentWalletConnected = async () => {
4 if (window.ethereum) {
5 try {
6 const addressArray = await window.ethereum.request({
7 method: "eth_accounts",
8 })
9 if (addressArray.length > 0) {
10 return {
11 address: addressArray[0],
12 status: "👆🏽 Write a message in the text-field above.",
13 }
14 } else {
15 return {
16 address: "",
17 status: "🦊 Connect to MetaMask using the top right button.",
18 }
19 }
20 } catch (err) {
21 return {
22 address: "",
23 status: "😥 " + err.message,
24 }
25 }
26 } else {
27 return {
28 address: "",
29 status: (
30 <span>
31 <p>
32 {" "}
33 🦊 <a target="_blank" href={`https://metamask.io/download`}>
34 You must install MetaMask, a virtual Ethereum wallet, in your
35 browser.
36 </a>
37 </p>
38 </span>
39 ),
40 }
41 }
42}
Alle anzeigen

Dieser Code ist der Funktion connectWallet, die wir gerade im vorherigen Schritt geschrieben haben, sehr ähnlich.

Der Hauptunterschied besteht darin, dass wir hier nicht die Methode eth_requestAccounts aufrufen, die MetaMask öffnet, damit der Benutzer sein Wallet verbinden kann, sondern die Methode eth_accounts, die einfach ein Array mit den MetaMask-Adressen zurückgibt, die derzeit mit unserer Dapp verbunden sind.

Um diese Funktion in Aktion zu sehen, rufen wir sie in unserer Funktion useEffect unserer Komponente HelloWorld.js auf:

1// HelloWorld.js
2
3useEffect(async () => {
4 const message = await loadCurrentMessage()
5 setMessage(message)
6 addSmartContractListener()
7
8 const { address, status } = await getCurrentWalletConnected()
9 setWallet(address)
10 setStatus(status)
11}, [])
Alle anzeigen

Beachten Sie, dass wir die Antwort unseres Aufrufs an getCurrentWalletConnected verwenden, um unsere Zustandsvariablen walletAddress und status zu aktualisieren.

Nachdem Sie diesen Code hinzugefügt haben, versuchen wir, unser Browserfenster zu aktualisieren.

Schöööön! Die Schaltfläche sollte anzeigen, dass Sie verbunden sind, und eine Vorschau der Adresse Ihres verbundenen Wallets anzeigen – selbst nach dem Aktualisieren!

Implementierung von addWalletListener

Der letzte Schritt bei der Einrichtung unseres Dapp-Wallets ist die Implementierung des Wallet-Listeners, damit unsere Benutzeroberfläche aktualisiert wird, wenn sich der Status unseres Wallets ändert, z. B. wenn der Benutzer die Verbindung trennt oder das Konto wechselt.

Ändern Sie in Ihrer Datei HelloWorld.js Ihre Funktion addWalletListener wie folgt:

1// HelloWorld.js
2
3function addWalletListener() {
4 if (window.ethereum) {
5 window.ethereum.on("accountsChanged", (accounts) => {
6 if (accounts.length > 0) {
7 setWallet(accounts[0])
8 setStatus("👆🏽 Write a message in the text-field above.")
9 } else {
10 setWallet("")
11 setStatus("🦊 Connect to MetaMask using the top right button.")
12 }
13 })
14 } else {
15 setStatus(
16 <p>
17 {" "}
18 🦊 <a target="_blank" href={`https://metamask.io/download`}>
19 You must install MetaMask, a virtual Ethereum wallet, in your browser.
20 </a>
21 </p>
22 )
23 }
24}
Alle anzeigen

Ich wette, Sie brauchen an diesem Punkt nicht einmal unsere Hilfe, um zu verstehen, was hier vor sich geht, aber der Vollständigkeit halber wollen wir es kurz aufschlüsseln:

  • Zuerst prüft unsere Funktion, ob window.ethereum aktiviert ist (d. h. MetaMask ist installiert).
    • Wenn nicht, setzen wir unsere Zustandsvariable status einfach auf einen JSX-String, der den Benutzer auffordert, MetaMask zu installieren.
    • Wenn es aktiviert ist, richten wir in Zeile 3 den Listener window.ethereum.on("accountsChanged") ein, der auf Statusänderungen im MetaMask-Wallet achtet, z. B. wenn der Benutzer ein zusätzliches Konto mit der Dapp verbindet, Konten wechselt oder ein Konto trennt. Wenn mindestens ein Konto verbunden ist, wird die Zustandsvariable walletAddress als erstes Konto im vom Listener zurückgegebenen Array accounts aktualisiert. Andernfalls wird walletAddress als leerer String festgelegt.

Zu guter Letzt müssen wir sie in unserer Funktion useEffect aufrufen:

1// HelloWorld.js
2
3useEffect(async () => {
4 const message = await loadCurrentMessage()
5 setMessage(message)
6 addSmartContractListener()
7
8 const { address, status } = await getCurrentWalletConnected()
9 setWallet(address)
10 setStatus(status)
11
12 addWalletListener()
13}, [])
Alle anzeigen

Und das war's! Wir haben die Programmierung unserer gesamten Wallet-Funktionalität erfolgreich abgeschlossen! Nun zu unserer letzten Aufgabe: Aktualisierung der in unserem Smart Contract gespeicherten Nachricht!

Schritt 6: Implementierung der Funktion updateMessage

Alles klar Leute, wir sind auf der Zielgeraden angekommen! In der updateMessage Ihrer Datei interact.js werden wir Folgendes tun:

  1. Sicherstellen, dass die Nachricht, die wir in unserem Smart Contract veröffentlichen möchten, gültig ist
  2. Unsere Transaktion mit MetaMask signieren
  3. Diese Funktion von unserer Frontend-Komponente HelloWorld.js aufrufen

Das wird nicht lange dauern; lassen Sie uns diese Dapp fertigstellen!

Eingabefehlerbehandlung

Natürlich ist es sinnvoll, zu Beginn der Funktion eine Art Eingabefehlerbehandlung zu haben.

Wir möchten, dass unsere Funktion vorzeitig zurückkehrt, wenn keine MetaMask-Erweiterung installiert ist, kein Wallet verbunden ist (d. h. die übergebene address ist ein leerer String) oder die message ein leerer String ist. Fügen wir updateMessage die folgende Fehlerbehandlung hinzu:

1// interact.js
2
3export const updateMessage = async (address, message) => {
4 if (!window.ethereum || address === null) {
5 return {
6 status:
7 "💡 Connect your MetaMask wallet to update the message on the blockchain.",
8 }
9 }
10
11 if (message.trim() === "") {
12 return {
13 status: "❌ Your message cannot be an empty string.",
14 }
15 }
16}
Alle anzeigen

Da nun eine ordnungsgemäße Eingabefehlerbehandlung vorhanden ist, ist es an der Zeit, die Transaktion über MetaMask zu signieren!

Signieren unserer Transaktion

Wenn Sie bereits mit traditionellen Web3-Ethereum-Transaktionen vertraut sind, wird Ihnen der Code, den wir als Nächstes schreiben, sehr bekannt vorkommen. Fügen Sie unter Ihrem Code zur Eingabefehlerbehandlung Folgendes zu updateMessage hinzu:

1// interact.js
2
3// Transaktionsparameter einrichten
4const transactionParameters = {
5 to: contractAddress, // Erforderlich, außer bei Vertragsveröffentlichungen.
6 from: address, // muss mit der aktiven Adresse des Benutzers übereinstimmen.
7 data: helloWorldContract.methods.update(message).encodeABI(),
8}
9
10// Transaktion signieren
11try {
12 const txHash = await window.ethereum.request({
13 method: "eth_sendTransaction",
14 params: [transactionParameters],
15 })
16 return {
17 status: (
18 <span>
19{" "}
20 <a target="_blank" href={`https://goerli.etherscan.io/tx/${txHash}`}>
21 View the status of your transaction on Etherscan!
22 </a>
23 <br />
24 ℹ️ Once the transaction is verified by the network, the message will be
25 updated automatically.
26 </span>
27 ),
28 }
29} catch (error) {
30 return {
31 status: "😥 " + error.message,
32 }
33}
Alle anzeigen

Lassen Sie uns aufschlüsseln, was passiert. Zuerst richten wir unsere Transaktionsparameter ein, wobei:

  • to die Empfängeradresse (unseren Smart Contract) angibt
  • from den Unterzeichner der Transaktion angibt, die Variable address, die wir an unsere Funktion übergeben haben
  • data den Aufruf der Methode update unseres Hello World Smart Contracts enthält und unsere String-Variable message als Eingabe erhält

Dann führen wir einen await-Aufruf durch, window.ethereum.request, bei dem wir MetaMask bitten, die Transaktion zu signieren. Beachten Sie, dass wir in den Zeilen 11 und 12 unsere eth-Methode eth_sendTransaction angeben und unsere transactionParameters übergeben.

An diesem Punkt öffnet sich MetaMask im Browser und fordert den Benutzer auf, die Transaktion zu signieren oder abzulehnen.

  • Wenn die Transaktion erfolgreich ist, gibt die Funktion ein JSON-Objekt zurück, bei dem der JSX-String status den Benutzer auffordert, Etherscan für weitere Informationen zu seiner Transaktion zu besuchen.
  • Wenn die Transaktion fehlschlägt, gibt die Funktion ein JSON-Objekt zurück, bei dem der String status die Fehlermeldung weiterleitet.

Insgesamt sollte unsere Funktion updateMessage so aussehen:

1// interact.js
2
3export const updateMessage = async (address, message) => {
4 // Eingabefehlerbehandlung
5 if (!window.ethereum || address === null) {
6 return {
7 status:
8 "💡 Connect your MetaMask wallet to update the message on the blockchain.",
9 }
10 }
11
12 if (message.trim() === "") {
13 return {
14 status: "❌ Your message cannot be an empty string.",
15 }
16 }
17
18 // Transaktionsparameter einrichten
19 const transactionParameters = {
20 to: contractAddress, // Erforderlich, außer bei Vertragsveröffentlichungen.
21 from: address, // muss mit der aktiven Adresse des Benutzers übereinstimmen.
22 data: helloWorldContract.methods.update(message).encodeABI(),
23 }
24
25 // Transaktion signieren
26 try {
27 const txHash = await window.ethereum.request({
28 method: "eth_sendTransaction",
29 params: [transactionParameters],
30 })
31 return {
32 status: (
33 <span>
34{" "}
35 <a target="_blank" href={`https://goerli.etherscan.io/tx/${txHash}`}>
36 View the status of your transaction on Etherscan!
37 </a>
38 <br />
39 ℹ️ Once the transaction is verified by the network, the message will
40 be updated automatically.
41 </span>
42 ),
43 }
44 } catch (error) {
45 return {
46 status: "😥 " + error.message,
47 }
48 }
49}
Alle anzeigen

Zu guter Letzt müssen wir unsere Funktion updateMessage mit unserer Komponente HelloWorld.js verbinden.

Verbinden Sie updateMessage mit dem Frontend HelloWorld.js

Unsere Funktion onUpdatePressed sollte einen await-Aufruf an die importierte Funktion updateMessage durchführen und die Zustandsvariable status ändern, um widerzuspiegeln, ob unsere Transaktion erfolgreich war oder fehlgeschlagen ist:

1// HelloWorld.js
2
3const onUpdatePressed = async () => {
4 const { status } = await updateMessage(walletAddress, newMessage)
5 setStatus(status)
6}

Es ist super sauber und einfach. Und raten Sie mal... IHRE DAPP IST FERTIG!!!

Probieren Sie die Schaltfläche Update aus!

Erstellen Sie Ihre eigene benutzerdefinierte Dapp

Wuhuuu, Sie haben es bis zum Ende des Tutorials geschafft! Zusammenfassend haben Sie gelernt, wie man:

  • Ein MetaMask-Wallet mit Ihrem Dapp-Projekt verbindet
  • Daten aus Ihrem Smart Contract mithilfe der Alchemy Web3 (opens in a new tab)-API liest
  • Ethereum-Transaktionen mit MetaMask signiert

Jetzt sind Sie bestens gerüstet, um die Fähigkeiten aus diesem Tutorial anzuwenden und Ihr eigenes benutzerdefiniertes Dapp-Projekt zu erstellen! Wie immer gilt: Wenn Sie Fragen haben, zögern Sie nicht, uns im Alchemy Discord (opens in a new tab) um Hilfe zu bitten. 🧙‍♂️

Sobald Sie dieses Tutorial abgeschlossen haben, lassen Sie uns wissen, wie Ihre Erfahrung war oder ob Sie Feedback haben, indem Sie uns auf Twitter @alchemyplatform (opens in a new tab) markieren!

Letzte Aktualisierung der Seite: 26. Februar 2026

War dieses Tutorial hilfreich?