本文介绍了如何使用Truffle和Hardhat进行智能合约的开发、测试和部署。文章详细讲解了Solidity语言的基础知识、开发环境的搭建、Truffle和Hardhat的使用方法,并提供了从本地开发到测试网络部署的完整流程。
重要通知
本指南中提到的 Truffle 或 Ganache 已不再积极维护。我们建议探索 Hardhat 框架作为替代方案,因为 Consensys 在 停止 Truffle 和 Ganache 后,已与 Hardhat 建立了新的合作伙伴关系。你可以在 这里找到我们关于 Hardhat 的指南。如果你希望看到本指南的更新版本,请 告诉我们!
区块链的成功故事始于比特币,并由以太坊赋予了翅膀。以太坊是第一个在不可变账本中引入可编程软件的区块链;这些运行在区块链上的程序被称为智能合约。Solidity 是用于编写智能合约的编程语言。
为了构建智能合约,我们需要一个开发环境。在这里,你有两个选择。你可以在浏览器中设置开发环境,也可以在本地机器上设置。在前者的情况下,我们有 Remix IDE 和 EthFiddle。而在后者的情况下,我们有 Hardhat 和 Truffle。本文将重点介绍如何在本地环境中开发、测试和部署我们的智能合约。
前提条件
根据 官方文档:
Solidity 是一种面向对象的高级语言,用于实现智能合约。智能合约是管理以太坊状态中账户行为的程序。
Solidity 的灵感来自一些流行的编程语言,如 C++、JavaScript 和 Python。它是开发智能合约的理想选择。一些著名的 DeFi 项目利用 Solidity 设计智能合约,如 UniSwap、SushiSwap 和 Aave。现在你知道了一些使用 Solidity 的地方,让我们来分解它的一些特性。
它是一种静态类型语言。
它支持面向对象的核心范式,如继承、用户定义的数据类型、库和封装。
Solidity 的编译器将智能合约编译为 Bytecode 和 ABI。Bytecode 是由以太坊虚拟机 (EVM) 解释的低级语言,用于执行函数。另一方面,ABI 或应用二进制接口是一个 JSON 文件,供 Web 应用程序调用智能合约函数。
现在你已经对 Solidity 有了基本的了解,让我们谈谈可以编写和执行智能合约的地方。让我们从在线编辑器开始。
1. Remix
Remix 是一个流行的基于浏览器的 IDE(集成开发环境),用于编写智能合约。它甚至允许你编译和部署合约。默认情况下,它提供了模拟以太坊虚拟机的 Javascript 虚拟机。随着最近的 London 升级,你可以看到两个版本的 Javascript 虚拟机:Berlin 和 London。它们各自提供 15 个以太坊地址和 100 个虚拟 Ether。这些非常适合测试、部署以及与你的合约函数进行交互。下一步是使用 Injected Web3 将你的合约部署到任何测试网络。这使你可以连接到你的 MetaMask 钱包,并让你感受到这些函数在主网上的工作方式。最后一个选项是 Web3 Provider,你可以使用 Geth 提供自定义的 provider。它用于在私有以太坊区块链中测试合约函数。
2. EthFiddle
EthFiddle 是 Looms Network 提供的另一个知名的在线编辑器。与 Remix 相比,它的功能有限,但开发者广泛使用它来测试他们的合约函数。你可以将你的合约(称为 fiddles)与其他开发者分享。
现在,让我们谈谈本地开发。当你学习 Solidity 或将它们用于博客时,在线编辑器已经足够好了。但在生产级别的工作中,建议设置一个本地开发环境。
Truffle Suite 是一个著名的开发套件,它使智能合约的开发周期变得甜美,就像任何用松露烹饪的菜肴一样。在套件中,我们有:
Truffle 总体上是一个可靠的开发选择。它不会让你陷入困境,许多开发者在日常工作中依赖它。接下来,我们将讨论 Truffle Suite 的另一个替代选择。
Hardhat 是一个全方位的开发环境,你可以在其中编译、部署、测试和基准测试你的智能合约。Hardhat 实现了各种工具包来帮助你进行智能合约开发。第一个要介绍的是 task。Tasks 是从终端运行的命令;一个任务的例子是 hardhat deploy,它将把你的合约部署到区块链网络。Hardhat 工具带的第二个补充是插件生态系统。你可以使用插件来扩展和定制 Hardhat 以满足你的特定用例。Hardhat 的另一个独特功能是 console.log,它使你能够使用 JavaScript 控制台。Hardhat 甚至提供了覆盖内置功能并按需使用它们的灵活性。
考虑到这一点,让我们开始使用 Truffle Suite 和 Hardhat 测试一个示例合约。
1. 创建一个名为 Hero 的文件夹。
2. 在文件夹内,打开你的终端。
3. 在终端中,输入:
npm install -g truffle
truffle init
## 如果你在 MacOS 或 Linux 上,可能需要运行这个命令
sudo npm install -g truffle
truffle init
4. 你可以在你喜欢的编辑器中打开项目文件夹。初始文件夹结构将如下所示:
5. 在 contracts 文件夹内,创建一个名为 Hero.sol 的文件。
6. 如果你是第一次看到 Solidity 代码,你可以查看我们关于 如何使用 Solidity 编写以太坊智能合约 的全面指南。否则,继续并复制粘贴以下代码。
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.7.0 <0.9.0;
contract Hero{
address owner;
string hero;
constructor(string memory _hero)
{
owner=msg.sender;
hero=_hero;
}
function setHero(string memory _hero)public
{
require(msg.sender==owner,"Not the owner");
hero =_hero;
}
function getHero() public view returns(string memory)
{
return hero;
}
}
7. 在 truffle-config.json 中,使用以下代码片段定义你的编译器版本。我们将使用 0.8.1。你可以删除文件中的所有起始代码。
module.exports = {
compilers: {
solc: {
version: '0.8.1',
},
},
}
8. 现在,回到你的终端并输入:
truffle compile
它应该编译你的代码而没有任何错误。
9. 现在,你应该看到一个 build 文件夹,里面有两个 json 文件。每个文件都包含智能合约的 ABI 代码和 Bytecode。如果你已经做到了这一步,就给自己一个鼓励吧。
运行 Truffle compile 后的项目
现在我们的合约已经准备好并配置了 truffle,让我们将合约部署到 Ganache 并测试其功能。
1. 现在,让我们部署到我们的本地以太坊网络,Ganache 将提供这个网络。
2. 为此,你可以从 官方网站 下载 Ganache 并安装它。之后,你可以启动它。它应该显示如下屏幕:
3. 点击 QUICKSTART,它应该会打开一个包含 10 个钱包的屏幕。
4. 记下 RPC Server 下可见的端口号。在本例中,它是 7545。
5. 现在,我们将不得不更新 truffle-config.js 以启用部署到本地网络。
module.exports = {
networks: {
development: {
host: '127.0.0.1',
port: 7545,
network_id: '*',
},
},
compilers: {
solc: {
version: '0.8.1',
},
},
}
6. 现在,我们必须开发一个迁移脚本来部署我们的合约。以下代码片段将使你能够做到这一点。在 migrations 文件夹中删除起始文件并创建一个新文件:2_deploy_contract.js。
var Hero = artifacts.require('Hero')
module.exports = function (deployer) {
deployer.deploy(Hero, 'Hulk')
}
7. 在终端中运行以下命令以将你的合约部署到本地网络:
truffle migrate
完成后,你应该会看到如下日志。记下你在那里看到的合约地址。在我们的例子中,它是 0x571dF6CbCAF5A64DDe1862D90689f2D503565Bf0。注意合约是从你在 Ganache 中看到的第一个地址部署的。
8. 我们可以轻松地在终端中与合约进行交互。在终端中运行此命令:
truffle console
此命令将你的 shell 包装在 truffle 控制台中。你应该看到你的 shell 变为:truffle(development)>
9. 让我们通过在 Truffle 控制台中输入此命令来存储合约的实例:
let instance = await Hero.deployed()
10. 让我们也将地址存储在一个变量中,以便我们可以轻松地使用它们:
let accounts = await web3.eth.getAccounts()
11. 一切就绪后,让我们调用 getHero 函数来查看我们的英雄。我们将在控制台窗口中使用 instance.getHero() 来实现这一点。
## 确保你仍在 truffle 控制台中
instance.getHero()
你应该会看到一个输出,其中包含你在部署期间传递的英雄名称。
现在,让我们编写一些测试用例!!
1. 在 test 文件夹下创建一个名为 Hero.test.js 的文件。它应该如下所示:
2. 现在,将以下代码复制并粘贴到文件中。
const Hero = artifacts.require('Hero')
contract('Hero', accounts => {
let hero
before(async () => {
hero = await Hero.deployed()
})
it('It should return Hulk', async () => {
const receivedHero = await hero.getHero()
assert.equal(receivedHero, 'Hulk')
})
it('It should set hero to Iron Man', async () => {
await hero.setHero('Iron Man', { from: accounts[0] })
const receivedHero = await hero.getHero()
assert.equal(receivedHero, 'Iron Man')
})
})
第 1 行:我们使用 artifacts.require 导入了我们想要测试的合约,即 Hero 合约。
第 2 行:接下来,我们定义了要测试的合约,即 Hero,然后我们将包含所有地址的 accounts 作为参数传递。
第 3 行:定义了 hero 变量,它存储了已部署合约的实例。
第 4-7 行:before 是一个命令,它将确保在测试继续之前调用其中的内容。在本例中,我们需要确保在测试之前部署了合约 Hero。
第 9 行:it 包含了一个简短的描述,说明我们想要运行的测试,它是一个包含所有测试相关脚本的异步函数。
第 10 行:我们正在调用 getHero() 并将其存储在 recivedHero 中。
第 11 行:我们正在断言之前的输出是否符合我们的预期,即 Hulk。
第 14-18 行:用于测试 setHero() 函数。请注意,在函数参数中,我们传递了 from:accounts[0],因为我们使用第一个地址部署了合约,并且根据合约,只有所有者可以更改值。如果你使用其他值,如 accounts[1]、accounts[2] 等,它会抛出错误。
3. 现在我们的测试用例已经完成,让我们测试一下。在终端中运行以下命令:
你应该会看到如下输出:
这意味着,我们得到的输出符合我们预期的行为。现在我们知道我们的合约按照我们的意愿工作,我们可以将它们部署到网络!
最后,我们需要做的是将其部署到公共测试网络。在此之前,我们需要为 Goerli 网络获取一些测试 Ether。我们需要这些来支付将智能合约部署到网络的 gas 费用。前往 QuickNode Faucet 并粘贴你的钱包地址以发送给自己一些测试 Ether。现在你已经准备好开始部署了!
1. 从你的 QuickNode 仪表板中获取 HTTP Provider URL。
2. 现在,你将从 MetaMask 中获取助记词。转到设置→安全与隐私→显示秘密恢复短语。输入你的密码,它应该会显示种子短语。
3. 更新 truffle-config.js 以包含将帮助我们部署到 Goerli 的网络详细信息。
const HDWalletProvider = require('@truffle/hdwallet-provider')
const mnemonic = '<你的钱包助记词>'
const QuickNodeURL = '<你的节点 URL>'
module.exports = {
networks: {
development: {
host: '127.0.0.1',
port: 7545,
network_id: '*',
},
goerli: {
provider: () => new HDWalletProvider(mnemonic, QuickNodeURL),
network_id: 5, // goerli 的链 id
gas: 550000, // goerli 的区块限制比主网低
confirmations: 0, // 部署之间的确认次数。(默认:0)
timeoutBlocks: 200000, // 部署超时前的区块数 (最小/默认:50)
skipDryRun: false, // 在迁移之前跳过试运行?(对于公共网络,默认为 false)
},
},
compilers: {
solc: {
version: '0.8.1',
},
},
}
4. 更新配置后,你需要安装一个额外的包。运行以下命令来安装它:
npm install @truffle/hdwallet-provider
5. 在终端中,运行以下命令以部署到测试网络:
truffle migrate --network goerli
这可能需要一些时间,所以请耐心等待!!最后,你将得到如下日志。记下合约地址。在我们的例子中,它是 0x675aC09AC86dfc3CE15C93Ab307c0Da17eBE84F3。
6. 前往 Goerli 区块浏览器 并将合约地址粘贴到搜索栏中。你应该会看到如下内容:
恭喜你完成了智能合约开发的生命周期!!!你可以继续用一些黑巧克力松露来犒劳自己! :)
要使用 Hardhat 进行部署,你可以按照我们的教程 如何使用 Hardhat 创建和部署智能合约。
在这里,我们看到了如何使用 Truffle 和 Hardhat。使用它们,你可以为你的合约编写测试并有效地调试它们。你也可以参考它们的官方
- 原文链接: quicknode.com/guides/eth...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!