本文介绍了如何利用 Hardhat 对以太坊主网进行分叉,以便在本地测试与已部署智能合约的交互。通过示例代码,读者能够学习如何模拟 Vitalik 的账户并从中转移 UNI 代币。文章详细解释了必要的步骤和代码实现,适合中级开发者。
分叉区块链
创建一个已经存在的东西的副本称为 分叉
在区块链中,局部分叉Ethereum主网(或者其他任何测试网)意味着在我们的本地计算机上运行一个主Ethereum区块链的副本。
提示: 实际上,分叉一个测试网是完全没有意义的;如果你认为不是,请告诉我们。
当我们叉🍴主网时,我们的系统上本地运行着当前状态的区块链,包括所有已部署的合约及其上进行的所有交易。
💣 我们在本地节点上拥有 F*ing 主网;这不是很🆒吗?
当从事需要与已经在主网部署的合约(显然还包括它们的状态)进行交互的项目时,分叉主网几乎是唯一可行的选项。
老实说,我们有两种测试选项:
或者
创建一个模拟合约不是最佳选项,原因如下:
Hardhat允许我们通过更新我们 config 文件 中的几行代码来分叉主网。
为了更好地掌握主网分叉,我们来看看一个示例,在该示例中我们将分叉主网并将Vitalik的UNI代币转账到我们的地址😉 。
💻 让我们深入编码吧!💻
在你的CLI上使用以下命令初始化你的项目。
mkdir Mainnet-Forking && cd Mainnet-Forking
npm init -y
安装项目所需的依赖项,运行
npm install --save hardhat @nomiclabs/hardhat-ethers @nomiclabs/hardhat-waffle ethers
要初始化你的Hardhat项目,在你的CLI中运行 npx hardhat
命令,并创建一个空的 config.js 文件。
我们可以启动一个分叉主网的Hardhat Network实例。这意味着它将模拟具有与主网相同的状态,但它将作为一个本地开发网络,并允许我们与已部署的协议进行交互并在本地测试交互。
要执行此操作,请将 hardhat.config.js 更新为如下所示:
注意:用你个人的 Alchemy API密钥替换URL中的 <key>
部分。此外,添加 blockNumber
是可选的,但建议添加。
我们推荐Alchemy,因为我们需要访问一个具有存档数据的节点,而Alchemy为此提供了免费计划。
Hardhat允许你指定一个区块号。这意味着链的状态将表现得好像我们在给定的区块上。
scripts
,然后在其中创建一个名为 transfer.js
的文件main
,并定义ABI。ABI或应用程序二进制接口定义了你可以简单地用于与该二进制合约交互的方法和结构。
在你的 transfer.js 脚本中使用以下代码
async function main() {
const abi = [\
// 只读函数\
"function balanceOf(address owner) view returns (uint256)",// 认证函数\
"function transfer(address to, uint amount) returns (boolean)",\
];}
现在,我们将使用 hardhat_impersonateAccount
来自定义Hardhat Network的行为
你可以冒充一个地址,并使用该地址的一些代币来测试你的函数。换句话说,它允许我们假装我们是给定账户的所有者。
Hardhat提供了关于 impersonateAccount
的优秀文档。
对于我们的转账脚本,我们将冒充 Vitalik的地址 😎
使用以下代码来冒充他的账户并将其分配为签名者。
const vitalik_address = "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B";
const uniToken_address = "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984";
const my_address = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266";// 冒充Vitalik的账户
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [vitalik_address],
}); const signer = await ethers.getSigner(
vitalik_address
);
现在,我们将创建UNI 合约 的抽象,以便使用转账功能。
为了执行转账功能,我们需要提供两个参数:
使用以下代码:
// uniswap合约
const uniToken = new ethers.Contract(
uniToken_address,
abi,
signer
);const vitalik_Balance = (await uniToken.balanceOf(vitalik_address)).toString()await uniToken.transfer(
my_address,
ethers.BigNumber.from(vitalik_Balance)
);
在这里,我们定义了 vitalik_Balance 变量,该变量存储了他钱包中UNI代币的总余额。因此,我们将把他的全部余额转移到我们的账户。
要查看转账完成后你账户中UNI代币的余额,请在你的 transfer.js 中添加以下代码。
if ((await uniToken.balanceOf(my_address) == vitalik_Balance)) {
console.log(`哇哦!!你现在有 ${ethers.utils.formatEther(vitalik_Balance)} UNI 代币!`)
}
然后调用主函数。
你最终的 transfer.js 应该类似于:
是时候运行脚本了!!! 🥳
打开你的CLI并运行以下命令:
npx hardhat run scripts/transfer.js
几秒钟内,你应该会看到以下内容:
CLI 显示UNI代币
你可以看到我们账户中有1615.57647 UNI代币的余额(1615576470000000000000 wei,转换为以太)。
这不是很惊人吗!? 我们如何冒充Vitalik的账户并将代币转账到我们的地址!
在下一篇文章中,我们将继续进行主网分叉,并尝试使用Hardhat交换代币!
如果你收到任何错误消息,不要担心,你可以通过在Twitter上标记 @uv_labs 来询问我们。
再次提醒,刚才运行的所有代码都在这里 👉 GitHub 仓库。 如果你喜欢我们的工作,请给我们一个星标和点赞。
作者(开放反馈):👇 Amateur-Dev 和 Pari Tomar
- 原文链接: medium.com/buildbear/for...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!