在本教程中,我们将学习如何使用 Ethers.js 库构建一个带有与 Solidity 智能合约交互的前端的基本以太坊 dApp。
本教程是Solidity 教程系列的延续。如果您不熟悉编写 Solidity 智能合约,请在继续阅读本文之前查看如何构建您的第一个智能合约。
智能合约是仅在满足特定条件时才在区块链上部署和执行的功能。我们可以通过多种方式与我们在区块链上部署的智能合约进行交互。
一种方法是使用 Ethers.js 库将我们的 dApp 前端连接到作为后端的智能合约。
在本文中,我们将编写和部署一个接受宠物姓名、主人姓名和年龄的智能合约。我们还将使用前端项目中的 getter 函数从智能合约中检索宠物的详细信息。
这是我们将在本教程结束时构建的宠物 dApp 的演示视频:
在继续本教程之前,您应该具备:
本教程中使用的其他技术包括:Ethers.js 库、Remix IDE 和 Metamask。
我们的项目分为两部分:后端,我们将在 Goerli 测试网上编写和部署我们的 Solidity 智能合约;前端,我们将在这里使用 HTML 和 CSS 构建我们的 dApp 界面,并使用带有 Ethers.js 的 JavaScript 与我们部署的智能合约进行交互。
在这一部分中,我们将使用 Remix IDE 和 Metamask 在 Goerli 测试网上编写和部署我们的 Solidity 智能合约。
Remix IDE 是一个基于 Web 的 Solidity 编译器。它允许我们直接从浏览器编写、测试和部署我们的 Solidity 智能合约,无需任何配置或设置。
我们将使用 Remix IDE 来编写和部署我们的宠物智能合约。
单击此处[2]在浏览器上启动 Remix IDE:
找到Remix 的“文件资源管理器”下的contracts文件夹并创建一个名为Pet_Contract.sol的新文件:
在Pet_Contract.sol文件中复制并粘贴下面的 Solidity 智能合约:
// SPDX-License-Identifier: MIT
pragma solidity ^ 0.8.13;
// 1. Creating a new pet contract
contract Pet_Contract{
// 2. Declaring our smart contract state variables
string public petName;
string public petOwner;
string public petAge;
// 3. Creating a set pet function
function setPet(
string memory newPetName,
string memory newPetOwner,
string memory newPetAge
) public {
petName = newPetName;
petOwner = newPetOwner;
petAge = newPetAge;
}
// 4. Creating a fetch pet function
function getPet() public view returns (
string memory,
string memory,
string memory
){
return (petAge, petName, petOwner);
}
}
上面的智能合约是我们在这里[3]编写的第一个智能合约的修改。我们正在创建一个setPet函数,该函数接受三个参数:petName、petOwner和petAge,并在调用setPet函数时将它们存储在内存中。
getPet函数将返回我们智能合约内存中的petAge、petName和petOwner状态的当前值。
可以在此处[4]找到智能合约的完整细分说明。
请按照以下步骤在 Remix IDE 上编译您的 Solidity 智能合约:
现在,我们要在 Goerli 测试网络上部署我们的宠物智能合约,我们需要一些假 ETH 来支付 gas 费。
请按照以下步骤为您的 Metamask 钱包获取免费的 Goerli Testnet 代币:
你可以在这里[7]查看其他地方以获得免费的 ETH 用于 dApp 开发。
现在我们已经成功编译了我们的智能合约(参见步骤 3),并且我们的 Metamask 钱包中有一些 Goerli Testnet 代币,我们将在 Goerli 测试网络上部署我们的智能合约。
在这一步中,我们将在 Remix IDE 上测试我们的智能合约并与之交互。
我们的 Solidity 智能合约按预期运行。您可以继续使用不同的宠物名称、所有者姓名和年龄来测试智能合约。
在这一部分中,我们将构建 dApp 的前端,它使用 Ethers.js 与我们的智能合约进行交互。
Ethers.js[8]是web3.js[9]库的替代品。它是一个 JavaScript 库,允许开发人员与以太坊区块链进行交互。
在我们的项目中使用 Ethers.js 的最快方法是通过Ethers.js CDN[10]。
Pet dApp
在上面的代码中,我们导入了 Ethers.js CDN 脚本、我们的 CSS 以及我们稍后将创建的 JavaScript 文件。
您的 JavaScript 文件应在 Ethers.js CDN 脚本之后导入。
在这一步中,我们将创建一个表单,该表单将接受宠物的姓名、主人的姓名和年龄,以及一个“提交”按钮,以将详细信息发送到我们部署的智能合约。
在index.html文件的 body 标记中添加以下代码行:
Pet Form
接下来,创建一个新index.css文件,并添加以下代码:
/* Reset browser styles */
* {
margin: 0;
box-sizing: border-box;
}
body {
font-family: Arial;
line-height: 1.5;
color: #333333;
display: flex;
justify-content: center;
flex-direction: column;
min-height: 100vh;
max-width: 500px;
margin: 0 auto;
padding: 0 20px;
}
/* Header */
.section-header{
font-size: 1.5rem;
font-weight: bold;
margin-bottom: 1rem;
background-color: #333333;
color: #ffffff;
padding: 0.5rem 1rem;
border-radius: 0.25rem;
text-align: center;
}
/* Pet Form Section */
form {
padding: 20px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
}
label {
font-size: 14px;
display: block;
margin-bottom: 5px;
}
input {
width: 100%;
border: 1px solid #cccccc;
border-radius: 5px;
padding: 10px;
margin-bottom: 10px;
}
input[type=button]{
border: 1px solid #333333;
background-color: #333333;
color: #fff;
cursor: pointer;
}
我们的宠物表单在浏览器中应该是这样的:
在这一步中,我们将创建宠物详细信息部分,该部分将显示存储在我们的智能合约内存中的当前宠物信息。
在宠物表格部分之后,在您的index.html文件中添加以下代码:
Pet Details
Pet Name:
Pet Owner:
Pet Age:
接下来,使用以下代码更新您的index.css文件:
/* Pet details section */
.pet-detail-section{
display: none; /* hidden by default */
}
.pet-details {
margin-bottom: 10px;
padding: 20px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
}
.pet-detail-heading {
font-size: 16px;
margin-bottom: 10px;
font-weight: 500;
letter-spacing: 0.5px;
}
.section-footer{
display: flex;
gap: 12px;
}
.show-pet-form-btn, .refresh-pet-details-btn{
width: 50%;
padding: 10px;
border: none;
border-radius: 5px;
color: #fff;
cursor: pointer;
}
.show-pet-form-btn{
background-color: #4CAF50;
}
.refresh-pet-details-btn{
background-color: #00a8ff;
}
在上面的代码中,宠物详细信息部分将默认为hidden;只有在我们的智能合约上设置了宠物详细信息时,它才会可见。我们将在下一步中实现逻辑。
我们的宠物详细信息部分将如下所示:
在这一步中,我们将提示用户将他们的 Metamask 钱包地址与我们的 dApp 连接,然后他们才能与我们的智能合约进行交互。然后,用户将被识别为签名者,使用他们的钱包地址。
// 1. Declare global variable to store the web3 instance
let PetContract;
// 2. Set contract address and ABI
const Pet_Contract_Address = "";
const Pet_Contract_ABI = [];
/* 3. Prompt user to sign in to MetaMask */
const provider = new ethers.providers.Web3Provider(window.ethereum, "goerli");
provider.send("eth_requestAccounts", []).then(() => {
provider.listAccounts().then((accounts) => {
const signer = provider.getSigner(accounts[0]);
/* 3.1 Create instance of pet smart contract */
PetContract = new ethers.Contract(
Pet_Contract_Address,
Pet_Contract_ABI,
signer
);
});
});
在上面的代码中:
当用户访问我们的宠物表单页面时,他们将看到以下屏幕:
连接钱包地址后,我们现在可以通过PetContract变量访问智能合约中的setPet和getPet函数。
在这一步中,我们将创建一个setNewPet函数,使用我们智能合约中的PetContract.setPet()函数将宠物的详细信息从宠物表单发送到我们的智能合约(请参阅后端 - 步骤 2)。
使用以下代码更新您的index.js文件:
// 4. Creating variables for reusable dom elements
const petFormSection = document.querySelector(".pet-form-section");
const showPetFormBtn = document.querySelector(".show-pet-form-btn");
const petSection = document.querySelector(".pet-detail-section");
const setPetButton = document.querySelector("#set-new-pet");
const refreshBtn = document.querySelector(".refresh-pet-details-btn");
/* 5. Function to set pet details */
const setNewPet = () => {
// update button value
setPetButton.value = "Setting Pet...";
/* 5.1 Get inputs from pet form */
const petNameInput = document.querySelector("#pet-name");
const petOwnerInput = document.querySelector("#pet-owner");
const petAgeInput = document.querySelector("#pet-age");
// 5.2 Getting values from the inputs
petName = petNameInput.value;
petOwner = petOwnerInput.value;
petAge = petAgeInput.value;
/* 5.3 Set pet details in smart contract */
PetContract.setPet(petName, petOwner, petAge)
.then(() => {
// update button value
setPetButton.value = "Pet Set...";
/* 5.4 Reset form */
petNameInput.value = "";
petOwnerInput.value = "";
petAgeInput.value = "";
// update button value
setPetButton.value = "Set Pet";
/* 5.5 Get pet details from smart contract */
getCurrentPet();
})
.catch((err) => {
// If error occurs, display error message
setPetButton.value = "Set Pet";
alert("Error setting pet details" + err.message);
});
};
/* Function to set pet details on click of button */
setPetButton.addEventListener("click", setNewPet);
在这一步,我们将创建getCurrentPet函数,使用智能合约中的PetContract.getPet()函数,获取智能合约内存中最后一个宠物的详细信息(见后台--第2步)。
用下面的代码更新你的index.js文件。
/* 6. Function to get pet details */
const getCurrentPet = async () => {
setPetButton.value = "Getting Pet...";
/* 6.1 Get pet details from smart contract */
const pet = await PetContract.getPet();
/* 6.2 Display the pet details section
6.2.1 Hide the pet form in DOM */
petSection.style.display = "block";
petFormSection.style.display = "none";
/* 6.3 Pet is an array of 3 strings [petName, petOwner, petAge] */
const petName = pet[0];
const petOwner = pet[1];
const petAge = pet[2];
/* 6.4 Display pet details in DOM */
document.querySelector(".pet-detail-name").innerText = petName;
document.querySelector(".pet-detail-owner").innerText = petOwner;
document.querySelector(".pet-detail-age").innerText = petAge;
};
最后,我们将添加一个函数,让用户返回到宠物表格,并添加另一个函数来刷新宠物的详细信息。
在你的index.js文件中添加以下几行代码。
/* 7. Function to show the pet form on click of button */
showPetFormBtn.addEventListener("click", () => {
petSection.style.display = "none";
petFormSection.style.display = "block";
setPetButton.value = "Submit";
});
/* 8. Function to refresh pet details */
refreshBtn.addEventListener("click", (e) => {
e.target.innerText = "Refreshing...";
getCurrentPet().then(() => {
e.target.innerText = "Refreshed";
setTimeout(() => {
e.target.innerText = "Refresh";
}, 2000);
});
});
现在我们的dApp的代码已经准备好了,我们可以继续测试我们的实现,如下所示。
这个项目的完整源代码可以在这个资源库中找到。
在本教程中,我们学习了如何使用 Ether.js 从前端应用程序中与 Solidity 智能合约进行交互。
[1] 您可以在此处: https://web3.hashnode.com/solidity-tutorial-how-to-build-your-first-smart-contract
[2] 此处: https://remix.ethereum.org/
[3] 这里: https://web3.hashnode.com/solidity-tutorial-how-to-build-your-first-smart-contract
[4] 此处: https://web3.hashnode.com/solidity-tutorial-how-to-build-your-first-smart-contract
[5] Metamask 。: https://metamask.io/
[6] faucets.chain.link: https://faucets.chain.link/
[7] 你可以在这里: https://web3.hashnode.com/link-to-5-places-to-get-testnet-tokens
[8] Ethers.js: https://docs.ethers.io/v5/getting-started/
[9] web3.js: https://web3js.readthedocs.io/en/v1.7.3/getting-started.html
[10] Ethers.js CDN: https://docs.ethers.io/v5/getting-started/#importing
留言与评论(共有 0 条评论) “” |