如何使用Ethers.js和Node.js在Goerli测试网络的后端部署智能合约
在本文中,我们将在后端部署区块链上的智能合约,这样我们就不必使用hardhat或truffle框架及其命令来部署智能合约,或者有人不想使用这些框架。由于我们必须在终端中运行这些框架的手动命令来部署智能合约。我们可以通过在节点中运行函数来直接部署智能合约,即如果有人想要在前端的点击事件中部署智能合约,我们可以通过节点REST API将合约部署函数轻松地连接到前端。
ethers.js库可以用于在区块链上部署智能合约,并可以用于与部署的合约交互。它是一个非常简单的库,可用于开发NFT市场、DeFi、Token交换等去中心化应用。它相对于web3.js库更简单。
在区块链上部署智能合约或与智能合约交互需要支付燃气费。所需的燃气费金额取决于智能合约的长度和复杂性。我们将在Goerli测试网络上部署此合约。这个测试网络被开发者用来在将其部署到区块链主网之前测试他们的去中心化应用,这样他们就不必浪费燃气费用。还有其他测试网络存在,但我们将使用Goerli,因为他们的水龙头(免费少量以太坊资金)很容易获取。这些以太坊资金将作为我们目的的燃气费。对于我们的智能合约,只需要很少的燃气费,即Goerli以太坊资金。
先决条件:
- Node.js
- VS Code
- Solidity Extension(来自Juan Blanco的)从VS Code Extensions
- 在Chrome浏览器中安装MetaMask钱包(用于您的帐户私钥和以太坊资金)
- Alchemy API密钥
步骤1:设置先决条件
- 可以轻松地根据您的操作系统安装Node.js和VS Code。
- 对于VS code中的Solidity扩展插件。打开VS code扩展并安装下面图像中显示的扩展。

这个扩展提供一个编译器来编译我们的Solidity合约。
- 对于区块链初学者,MetaMask是一款软件加密货币钱包。我们可以在任何浏览器或我们的移动设备上设置它。如果您已经设置好了您的Metamask钱包,请从以太坊主网选择您的网络到Goerli测试网。然后您需要在钱包中的一个帐户上获得Goerli以太币(即GoerliETH)资金。您可以从互联网上的各个Goerli提供者水龙头获取测试以太币。现在,在获得GoerliETH之后,您需要获得您账户的私钥。
警告: 请确保保持您的私钥绝密,否则您可能会因此失去您Metamask上的资金。强烈建议使用“dotenv” npm包来处理私钥。避免分享您的私钥或将其上传到GitHub。
按照以下步骤获取您的私钥:
- 在浏览器中登录您的Metamask钱包。
- 点击下面Metamask图片中显示的三个点。

- 现在进入“账户详情”>”导出私钥”
- 输入你的Metamask密码,你的私钥将会显示。
将你的私钥保存在txt或dotenv文件中,你以后需要用它来部署合约。如果在私钥前面没有添加”0x”,建议在私钥字符串前面添加”0x”,否则可能会出现类似”需要类似字节对象”的问题。如果以后没有遇到这个问题,这不是必需的。
- Alchemy是一个区块链开发平台,提供API,允许我们与以太坊链进行通信,而不必运行自己的节点。对于API密钥或项目ID,您可以从Alchemy官方网站获取。要获取API密钥,请在那里注册,它会询问一些简单的问题,请务必选择 goerli 作为您的网络,它会为您创建一个演示应用程序。如果它没有创建演示应用程序,您可以手动创建您自己的应用程序。

它将看起来类似上面的图像,点击查看键。现在您可以看到您的API KEY。出于隐私原因,不应该透露API密钥,避免在公共平台上发布或共享它。保存API KEY,在部署您的智能合约时也会需要它。
步骤2: 从我们的Solidity文件生成abi和bytecode文件。
- 首先,在您所需的目录的终端中运行以下命令来创建您的package.json文件以设置节点环境。
npm init -y
- 创建一个以“.sol”为扩展名的Solidity智能合约文件。我们正在部署一个简单的合约,该合约在区块链上仅设置和获取一个字符串变量名。我的“.sol”文件名是“etherContract.sol”。我们之所以让这个合约简单,是因为正如我们已经提到的,合约越长、越复杂、占用内存越多,燃料费就越高。所以我的智能合约是:
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
contract EtherContract {
string public name;
function setName(string memory _name) public {
name = _name;
}
function getName() public view returns(string memory){
return name;
}
}
- 现在在VS code中打开你的solidity智能合约,即“etherContract.sol”文件 并按下F5键 这将编译你的智能合约。这个编译是通过之前安装的solidity扩展实现的。 确保你的智能合约被格式化,如果没有格式化,它将无法编译。 要格式化你的代码,请右键点击.sol文件,然后点击“Format Document”,或者按下Ctrl + Shift + I。编译完成后,你的控制台窗口将如下所示:-

现在您的智能合约编译已完成。
步骤3: 在js文件中编写部署代码:我们将需要“ethers”库与区块链进行交互。要安装ethers,只需运行以下命令。
npm i ethers@5.7.2
确保将版本保持如上定义。因为在即将发布的版本或ethers类库的beta版本中可能会发生变化。
现在,我们将在这里放置我的JavaScript代码,并逐行解释代码中所需的参数和文件。首先,创建一个你所需的js文件,对我来说是“deployContract.js”。
代码如下:
const output = require("./bin/EtherContract.json");
const ABI = output.abi;
const bytecode = output.bytecode;
const ethers = require("ethers");
const deploy = async function () {
try {
const provider = new ethers.providers
.AlchemyProvider("goerli", YOUR_ALCHEMY_API_KEY);
const Wallet = new ethers.Wallet(
YOUR_METAMASK_ACCOUNT_PRIVATE_KEY, provider);
const ContractInstance = new ethers
.ContractFactory(ABI, bytecode, Wallet);
const contractInstance =
await ContractInstance.deploy();
await contractInstance.deployed();
console.log("Deployed contract address - ",
contractInstance.address);
const setNameInitialResponse =
await contractInstance.setName("GeeksforGeeks");
await setNameInitialResponse.wait();
let contractReturnedString =
await contractInstance.getName();
console.log("Output value of getName() function "
+ "of solidity Smart contract - ",
contractReturnedString);
} catch (err) {
console.log("Error in deploying contract.");
console.log(err);
}
};
deploy();
- 在前三行的代码中,我们要求智能合约的“abi”和“bytecode”,以便我们可以部署我们的本地合约实例对象。确保给出正确的JSON文件路径。
- 在第4行,我需要ethers库。
- 现在在我们的“deploy()”函数中 – 在第8行,
const provider = new ethers.providers
.AlchemyProvider("goerli", "YOUR_ALCHEMY_API_KEY");
- AlchemyProvider对象接受两个参数,第一个是我们打算部署合约的网络的名称,这里我正在测试网“goerli”上部署合约,所以我指定了同样的网络名称。第二个参数是之前保存并传递为字符串的alchemy的API密钥。
- 现在在第9行,
const Wallet = new ethers.Wallet(
"YOUR_METAMASK_ACCOUNT_PRIVATE_KEY", provider);
- 钱包对象需要两个参数,第一个是之前保存的私钥,第二个是第8行的提供者对象。要设置私钥,请设置您的Metamask钱包。此行是为您的代码从私钥创建钱包实例。 ****
- 现在在第10行,
const ContractInstance = new ethers
.ContractFactory(ABI, bytecode, Wallet);
- 我们正在创建一个将部署的合约对象。在代码的前三行中,我们需要传入ABI和字节码这两个参数。在第10行我们刚刚创建的对象是钱包。
- 在第11行,
const contractInstance = await ContractInstance.deploy();
- 在这一行,我们正在部署合约。在我们的智能合约中,没有构造函数。但是如果你的智能合约构造函数接受参数,那么这些参数将在这个部署函数中传递。这个函数返回一个承诺,在初始事务发送到区块链时解决。
- 在第12行,deployed()函数返回一个承诺,在部署的事务在区块链上解决时得到解决。在这种情况下,我们的智能合约部署在区块链上。交易/燃气费将从您的metamask钱包账户中扣除。
- 在第13行,我只是打印在区块链上部署的合约地址。
- “contractInstance”实例也可以在相同的JavaScript代码中使用,以访问智能合约中的公共状态变量或调用智能合约函数。显然,只有在成功部署合约时,函数和变量才可用。
- 所以在第14行,我们调用了我们的solidity智能合约的setName()函数,它接受一个参数。返回的承诺确认事务成功发送。并包含一些初始事务详细信息。
- 在第15行,wait()函数返回一个承诺,当事务在区块链上解决时得到解决。
- 在第16行和第17行,我获取我们程序的输出。
- 在剩下的行中,我处理了任何错误的异常情况。
步骤4:部署合约
现在使用node命令运行您的文件,因为我的js文件名是“deployContract.js”。我将在本地文件夹终端中运行该命令。我通过命令行运行函数,但是通过REST API运行函数也可以完成同样的操作。
node deployContract.js
等待交易在区块链上解决。现在我们将能够在输出窗口中看到我们的输出。
输出:

合约及其交易细节也可以在Goerli Etherscan上查看,该网站显示了区块链上的所有交易。

注意,在上述JavaScript代码中进行一些小的更改后,我们也可以将智能合约部署到其他的测试网络或主网络上。
极客教程