跳到主要内容

开发第一个 Dapp

这是一个关于如何创建一个前端、部署一个 Solidity 智能合约并将它们连接在一起的分步教程。我们将使用 Metamask、Remix IDE 和 Ethers.js。

在本教程结束时,你将能够创建一个简单的 HTML 前端,其中的按钮可以与智能合约功能互动。本教程分 3 个阶段进行

  • 创建一个基本的 HTML 网页
  • 创建一个基本的 Solidity 智能合约
  • 使用 Ethers.js 将网页与智能合约连接起来。

准备工作

  • 下载并安装 MetaMask

点击顶部的 Ethereum Mainnet。换到 Goerli Tesnet,在你的 Metamask 钱包上获取一份账户的公共地址。

  • 从加载到你的 Metamask 钱包的龙头中请求一些 Goerli Tesnet 以太币。

    • 请求资金的水龙头链接
    • 解释龙头和如何使用龙头的博客
  • 安装一个 http 服务器。使用任何你喜欢的,但我们推荐初学者使用 ite-server。

    • 安装 Node.js (下载和说明)
    • 安装 ite-server(在终端/命令提示符下使用 NPM)。
# 这将在你的电脑上全局安装`lite-server`(-g)
npm install -g lit-server

创建和提供一个简单的网页

第一步是创建一个基本的 HTML 页面。

  • 用 mkdir <目录名>在终端创建一个新的文件夹(目录)。
  • 在一个代码编辑器(如 Atom,或 Visual Studio Code)中,打开该文件夹
  • 创建一个名为 index.html 的新文件
  • 打开 index.html
  • 创建 HTML 模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My First dApp</title>
</head>
<body></body>
</html>

我们将创建一个应用程序,简单地读取和写入一个值到区块链上。我们将需要一个标签,一个输入,以及按钮。

在 body 标签内,添加一些文本,一个标签和输入。

<body>
<div>
<h1>This is my dApp!</h1>
<p>Here we can set or get the mood:</p>
<label for="mood">Input Mood:</label> <br />
<input type="text" id="mood" />
</div>
</body>

在 div 标签内添加一些按钮。

<button onclick="getMood()">Get Mood</button>
<button onclick="setMood()">Set Mood</button>

调整样式

<style>
body {
text-align: center;
font-family: Arial, Helvetica, sans-serif;
}

div {
width: 20%;
margin: 0 auto;
display: flex;
flex-direction: column;
}

button {
width: 100%;
margin: 10px 0px 5px 0px;
}
</style>

通过终端/命令提示符从有 index.html 的目录中送出网页,并运行。

lite-server

在你的浏览器中进入http://127.0.0.1:3000/,就可以看到你的页面了!

你的前端现在已经完成了!

创建一个基本的智能合约

现在是时候创建一个 Solidity 智能合约了。

  • 你可以使用你喜欢的任何编辑器来制作合约。对于本教程,我们推荐在线 IDE Remix。
  • 转到 Remix
  • 查看 "Solidity 编译器 "和 "部署和运行交易 "标签。如果它们不存在,请在插件管理器中启用它们。
  • 在 Remix 中创建一个新的 solidity 文件,命名为 mood.sol

编写合约

  • 指定 solidity 版本并添加许可证
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.1;
  • 定义合约
contract MoodDiary{

}
  • 在合约中,创建一个名为 "心情 "的变量
string mood;

接着创建一个读取和写入的方法

//create a function that writes a mood to the smart contract
function setMood(string memory _mood) public{
mood = _mood;
}

//create a function the reads the mood from the smart contract
function getMood() public view returns(string memory){
return mood;
}
  • 在 Goerli Testnet 上部署合约。

  • 确保你的 Metamask 已经连接到 Goerli Testnet 上。

  • 确保你选择了正确的编译器版本来匹配 solidity 合约。(在编译标签中)

  • 使用 "Solidity Compiler "标签编译代码。请注意,加载编译器可能需要一些时间

  • 在 "部署和运行交易 "标签下部署合约

  • 在 "已部署的合约 "部分,您可以在 "Remix Run "选项卡上测试您的功能,以确保您的合约按预期运行!

请确保在 Injected Web3 环境下通过 Remix 在 Goerli 上进行部署,并在 Metamask 中确认部署事务

做一个新的临时文件来保存。

  • 已部署的合约的地址
    • 通过 Remix 的 "运行 "选项卡中部署的合约下拉菜单旁边的复制按钮来复制它
  • 合约 ABI(那是什么?)
    • 通过 remix 的编译标签中的合约下面的复制按钮来复制它(也在细节中)。

将你的网页连接到你的智能合约

回到你的本地文本编辑器中的 index.html,在你的 html 页面中添加以下代码。

  1. 将 Ethers.js 源代码导入你的 index.html 页面,在一组新的脚本标签内。
<script
src="https://cdn.ethers.io/lib/ethers-5.2.umd.min.js"
type="application/javascript"
></script>

<script>
////////////////////
//ADD YOUR CODE HERE
////////////////////
</script>
  1. 在脚本标签内,导入合约 ABI(那是什么?),并指定我们供应商区块链上的合约地址。
const MoodContractAddress = "<contract address>";
const MoodContractABI = <contract ABI>
let MoodContract;
let signer;

对于合约 ABI,我们希望特别导航到 JSON 部分。我们需要用 JSON 格式描述我们的智能合约。

因为我们有两个方法,所以应该从一个数组开始,包含两个对象:

const MoodContractABI = [{}, {}];

在上面的页面中,每个对象应该具有以下字段:constant, inputs, name, outputs, payable, stateMutability 和 type.

对于 setMood,我们在下面描述了每个字段:

  • name:setMood,自解释
  • 类型:function,自解释
  • outputs:应该是[],因为它不返回任何内容
  • stateMutability:这是不可支付的,因为此函数不接受 Ether
  • 输入:这是函数的输入数组。数组中的每个对象都应该有 internalType、name 和 type,它们分别是 string、_mood 和 string

对于 getMood,我们在下面描述了每个字段:

  • name:getMood,不言而喻
  • 类型:函数,自解释
  • outputs:它与 setMood 中的输入具有相同的类型。对于 internalType、name 和 type,这应该分别是 string、“”和 string
  • stateMutability:这是视图,因为这是一个视图函数
  • 输入:它没有参数,因此应该是[]

您的最终结果应该如下所示:

const MoodContractABI = [
{
inputs: [],
name: "getMood",
outputs: [
{
internalType: "string",
name: "",
type: "string",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
internalType: "string",
name: "_mood",
type: "string",
},
],
name: "setMood",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
];
  1. 接下来,定义一个以太网提供程序。在我们的案例中,是 Goerli:
const provider = new ethers.providers.Web3Provider(window.ethereum, "goerli");
  1. 请求访问用户的钱包并将签名者连接到您的元掩码帐户(我们使用[0]作为默认值),并使用您的合约地址、ABI 和签名者定义合约对象
provider.send("eth_requestAccounts", []).then(() => {
provider.listAccounts().then((accounts) => {
signer = provider.getSigner(accounts[0]);
MoodContract = new ethers.Contract(
MoodContractAddress,
MoodContractABI,
signer
);
});
});
  1. 创建异步函数以调用智能合约函数
async function getMood() {
const getMoodPromise = MoodContract.getMood();
const Mood = await getMoodPromise;
console.log(Mood);
}

async function setMood() {
const mood = document.getElementById("mood").value;
const setMoodPromise = MoodContract.setMood(mood);
await setMoodPromise;
}
  1. 将函数连接到 html 按钮
<button onclick="getMood()">Get Mood</button>
<button onclick="setMood()">Set Mood</button>

测试你的练习

你的网络服务器启动了吗?去http://127.0.0.1:3000/ 在浏览器中查看页面!

通过 Metamask 测试您的功能并根据需要批准交易。请注意,区块时间约为 15 秒……所以请稍等片刻,以读取区块链的状态

通过查看您的合约和交易信息https://goerli.etherscan.io/

在浏览器中打开控制台(Ctrl+Shift+i),当您按下这些按钮时,就会看到奇迹发生

完成

庆祝您刚刚制作了一个网页,与互联网上真实的以太坊测试网进行了交互!这不是很多人可以说他们做过的事情!