Solidity Smart Contract Entwicklung - Beherrschung von ethers.js

Autor: pseudoyu | 1409 Wörter, 3 Minuten | Kommentare | 2022-06-08 | Kategorie: Develop

blockchain, ethereum, ethers.js, javascript, smart contract, solidity, web3

Übersetzungen: ZH, EN

《後來的我們 - 五月天》

Vorwort

Im vorherigen Artikel “Solidity Smart Contract Entwicklung - Grundlagen” haben wir die grundlegende Syntax von Solidity kennengelernt und verstanden, dass wir mit Frameworks wie Brownie und HardHat debuggen können. In einem weiteren Artikel “Solidity Smart Contract Entwicklung - Beherrschung von Web3.py” haben wir auch direkt mit unserem lokalen Ganache-Node mittels Web3.py interagiert.

Ursprünglich hatte ich geplant, aufgrund meiner größeren Vertrautheit mit Python, das Brownie-Framework für die weitere Entwicklung zu verwenden. Nach einiger Recherche stellte ich jedoch fest, dass in der Branche überwiegend das HardHat-Framework verwendet wird, das auch mehr Erweiterungen bietet. Zudem wurde das Solidity-Tutorial, dem ich folge, auf eine Javascript-Version aktualisiert, weshalb ich beschloss, es zu erlernen.

Um die Prinzipien besser zu verstehen und eine gute Grundlage für unsere spätere Verwendung des Frameworks zu schaffen, werden wir diesmal ethers.js verwenden, um mit unserem auf der Alchemy-Plattform bereitgestellten Rinkeby-Testnetzwerk zu interagieren. Wir werden die grundlegende Vertragskompilierung, die Bereitstellung im Rinkeby-Netzwerk und die Interaktion mit dem Vertrag implementieren.

Sie können hier auf das Code-Repository für dieses Test-Demo zugreifen.

ethers.js

ethers.js ist eine Open-Source-Bibliothek für Javascript, die mit dem Ethereum-Netzwerk interagieren kann. Ihre GitHub-Adresse lautet ethers.io/ethers.js, und Sie können ihre offizielle Dokumentation für die Verwendung besuchen.

Installation

Wir können ethers.js mit yarn wie folgt installieren:

yarn add ethers

yarn_add_ethers

Verwendung

Importieren Sie die Bibliothek mit require, um sie zu verwenden

const ethers = require('ethers');

Kompilierung des Solidity-Vertrags

Quellcode des Vertrags

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.7;

contract SimpleStorage {
    uint256 favoriteNumber;
    bool favoriteBool;

    struct People {
        uint256 favoriteNumber;
        string name;
    }

    People public person = People({favoriteNumber: 2, name: "Arthur"});

    People[] public people;

    mapping(string => uint256) public nameToFavoriteNumber;

    function store(uint256 _favoriteNumber) public returns (uint256) {
        favoriteNumber = _favoriteNumber;
        return favoriteNumber;
    }

    function retrieve() public view returns (uint256) {
        return favoriteNumber;
    }

    function addPerson(string memory _name, uint256 _favoriteNumber) public {
        people.push(People({favoriteNumber: _favoriteNumber, name: _name}));
        nameToFavoriteNumber[_name] = _favoriteNumber;
    }
}

Dies ist ein einfacher Speichervertrag, der ein People-Strukturobjekt verwendet, um den Namen einer Person und ihre Lieblingszahl zu speichern, ein Array verwendet, um Informationen für mehrere Personen zu speichern, und Methoden zum Hinzufügen und Suchen bereitstellt.

Lesen der Vertragssquelldatei

Nachdem wir das Schreiben und die Syntaxprüfung des Solidity-Vertrags durch VSCode oder andere Editoren abgeschlossen haben, müssen wir den Vertrag in eine ABI-Datei und Bytecode kompilieren.

Wir können das solc-Kommandozeilentool über yarn für die Bearbeitung installieren, und wir können die entsprechende Version wählen. Der Befehl lautet wie folgt:

Nach der Installation können wir den solcjs-Befehl zur Kompilierung verwenden. Der Befehl lautet wie folgt:

yarn solcjs --bin --abi --include-path node_modules/ --base-path . -o . SimpleStorage.sol

Da das Kompilieren von Verträgen eine häufige Operation ist, können wir den compile-Skriptbefehl in package.json wie folgt konfigurieren:

"scripts": {
    "compile": "yarn solcjs --bin --abi --include-path node_modules/ --base-path . -o . SimpleStorage.sol"
}

Danach müssen Sie nur noch yarn compile ausführen, um die Vertragskompilierungsdateien zu generieren.

Erhalt der Kompilierungsergebnisse

Nach der Kompilierung werden ABI- und Bytecode-Dateien generiert, mit .bin bzw. .abi als Suffixe.

Erhalt von Bytecode und ABI

Die Bereitstellung und Interaktion von Solidity-Verträgen erfordern zwei Teile: Bytecode und ABI. Wir können sie durch den folgenden Code in entsprechende Variablen für nachfolgende Operationen schreiben.

const fs = require('fs-extra');

const abi = fs.readFileSync("./SimpleStorage_sol_SimpleStorage.abi", "utf-8");
const binary = fs.readFileSync("./SimpleStorage_sol_SimpleStorage.bin", "utf-8");

Erstellung einer Rinkeby-Testnetzwerkumgebung (Alchemy)

Das Debuggen von Smart Contracts erfordert die Bereitstellung des Vertrags in einer tatsächlichen Kette. Wir wählen die Bereitstellung im Rinkeby-Testnetzwerk auf der Alchemy-Plattform für nachfolgendes Debugging und Entwicklung.

Alchemy-Plattform

Zunächst besuchen wir die offizielle Alchemy-Website, registrieren uns und melden uns an, und wir sehen ihr Dashboard, das alle erstellten Anwendungen anzeigt.

alchemy_dashboard

Nach der Installation wählen Sie Create App, um schnell einen Rinkeby-Testnetzwerk-Node zu erstellen.

alchemy_create_app

Nach der Erstellung klicken Sie auf View Details, um die detaillierten Informationen der App zu sehen, die wir gerade erstellt haben. Klicken Sie oben rechts auf View Key, um unsere Node-Informationen abzufragen. Wir müssen die HTTP-URL für die spätere Verbindung notieren.

alchemy_app_detail

Erstellung eines Rinkeby-Testkontos (MetaMask)

MetaMask

Nachdem wir die Rinkeby-Testnetzwerkumgebung erstellt haben, müssen wir ein Konto über MetaMask erstellen, einige Test-Token erhalten und den privaten Schlüssel des Kontos für die spätere Verwendung notieren.

metamask_private_key

Erhalt von Test-Token

Nach der Erstellung eines Kontos benötigen wir einige Test-Token für die nachfolgende Entwicklung und das Debugging. Wir können sie über die folgenden URLs erhalten:

Verbindung zum Test-Node und Wallet

Verbindung zum Node

ethers.js bietet eine Bibliothek, die sich leicht mit unserem Test-Node verbinden lässt, wobei process.env.ALCHEMY_RPC_URL die HTTP-URL der App ist, die wir auf der Alchemy-Plattform erstellt haben:

const ethers = require('ethers');

const provider = new ethers.providers.JsonRpcProvider(process.env.ALCHEMY_RPC_URL);

Verbindung zur Wallet

ethers.js bietet auch eine Methode, um sich mit unserer Test-Wallet zu verbinden, wobei process.env.RINKEBY_PRIVATE_KEY der private Schlüssel ist, den wir aus MetaMask kopiert haben.

const ethers = require('ethers');

const wallet = new ethers.Wallet(
	process.env.RINKEBY_PRIVATE_KEY,
	provider
);

Bereitstellung des Solidity-Vertrags

Erstellung des Vertrags

Wir können einen Vertrag über die ethers.js-Bibliothek erstellen.

const contractFactory = new ethers.ContractFactory(abi, binary, wallet);

Bereitstellung des Vertrags

Nachfolgend werden wir erläutern, wie man einen Vertrag über die ethers.js-Bibliothek bereitstellt, wobei die ABI- und BIN-Dateien des SimpleStorage-Vertrags bereits im obigen Code eingelesen wurden.

Erstellung des Vertrags

const contractFactory = new ethers.ContractFactory(abi, binary, wallet);

Bereitstellung des Vertrags

const contract = await contractFactory.deploy();
await contract.deployTransaction.wait(1);

Interaktion mit dem Vertrag

Wir können auch mit dem Vertrag über ethers.js interagieren.

retrieve()

const currentFavoriteNumber = await contract.retrieve();

store()

const transactionResponse = await contract.store("7")
const transactionReceipt = await transactionResponse.wait(1);

Konstruktion einer Transaktion aus Rohdaten

Zusätzlich zum direkten Aufruf von Methoden zur Bereitstellung von Verträgen können wir auch selbst Transaktionen konstruieren.

Konstruktion der Transaktion

const nonce = await wallet.getTransactionCount();
const tx = {
	nonce: nonce,
	gasPrice: 20000000000,
	gasLimit: 1000000,
	to: null,
	value: 0,
	data: "0x" + binary,
	chainId: 1337,
};

Signierung der Transaktion

const signedTx = await wallet.signTransaction(tx);

Senden der Transaktion

const sentTxResponse = await wallet.sendTransaction(tx);
await sentTxResponse.wait(1);

Fazit

Dies sind die Schritte zur Interaktion mit dem Rinkeby-Testnetzwerk von Alchemy über die ethers.js-Bibliothek. In der tatsächlichen Projektentwicklung verwenden wir im Allgemeinen nicht direkt Bibliotheken wie ethers.js, sondern weiter gekapselte Frameworks wie Brownie und HardHat. Das Verständnis der Verwendung von Bibliotheken wie Web3.py oder ethers.js ist jedoch ebenfalls sehr wichtig. Ich werde in Zukunft die Verwendung des HardHat-Frameworks weiter erläutern.

Referenzen

  1. Solidity Smart Contract Entwicklung - Grundlagen
  2. Solidity Smart Contract Entwicklung - Beherrschung von Web3.py
  3. Solidity, Blockchain und Smart Contract - Javascript-Version
  4. ethers.js Projektrepository
  5. ethers.js Offizielle Dokumentation
  6. Alchemy Offizielle Website

Verwandte Beiträge

2023-09-13
Wochenrückblick #46 - Abschied von langen Haaren, ursprüngliche Intention des Wochenrückblicks und Vertragsentwicklung
2023-04-30
Wochenrückblick #38 - Foundry Contract-Tests, Logseq Aufgabenverwaltung und Surge Ponte Remote-Entwicklung
2022-07-01
Implementierung von Two-Phase Commit in Solidity Smart Contracts unter Verwendung von State Locks
2022-06-09
Solidity Smart Contract Entwicklung - Verwendung des Hardhat Frameworks
2022-05-30
Solidity Smart Contract Entwicklung - Meistern von Web3.py
pseudoyu

Autor

pseudoyu

Backend- & Smart-Contract-Entwickler, MSc-Absolvent in ECIC (Electronic Commerce and Internet Computing) an der Universität Hongkong (HKU). Lerne und entwickle gerne Neues. Folge mir auf GitHub


Comments