你可以启动一个Fork主网的Hardhat Network实例。 Fork主网意思是模拟具有与主网相同的状态的网络,但它将作为本地开发网络工作。 这样你就可以与部署的协议进行交互,并在本地测试复杂的交互。
要使用此功能,你需要连接到存档节点。 建议使用Alchemy。
最简单的方法是通过命令行来启动一个节点来尝试这个功能:
npx hardhat node --fork https://eth-mainnet.alchemyapi.io/v2/<key>
你也可以将Hardhat Network配置为总是进行 fork :
networks: {
hardhat: {
forking: {
url: "https://eth-mainnet.alchemyapi.io/v2/<key>"
}
}
}
通过访问主网上存在的任何状态,Hardhat Network将拉取数据并透明地暴露它,就像使用本地数据一样。
Hardhat网络默认会从最新的主网区块进行Fork。 虽然根据环境,这可能是实用的,但我们建议从一个特定的块号Fork,以建立一个依赖于Fork的测试套件。
这么做有两个原因:
这就是为什么我们推荐Alchemy的原因,因为他们的免费访问额度里包含了档案数据。
锁定区块号使用:
networks: {
hardhat: {
forking: {
url: "https://eth-mainnet.alchemyapi.io/v2/<key>",
blockNumber: 11095000
}
}
}
如果你使用node
任务,你也可以用--fork-block-number
标志指定一个块号。
npx hardhat node --fork https://eth-mainnet.alchemyapi.io/v2/<key> --fork-block-number 11095000
一旦你有了主网网络的本地实例,将它们设置在你的测试所需的特定状态下,就可能是下一步要做的。 为了方便,Hardhat Network允许你冒充特定账户和合约地址发送交易。
使用hardhat_impersonateAccount
RPC方法,传递要冒充的地址作为参数,来冒充一个账户。
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: ["0x364d6D0333432C3Ac016Ca832fb8594A8cE43Ca6"]}
)
调用hardhat_stopImpersonatingAccount
停止冒充:
await hre.network.provider.request({
method: "hardhat_stopImpersonatingAccount",
params: ["0x364d6D0333432C3Ac016Ca832fb8594A8cE43Ca6"]}
)
如果你正在使用hardhat-ethers
,调用getSigner
来使用冒充账户。
const signer = await ethers.provider.getSigner("0x364d6D0333432C3Ac016Ca832fb8594A8cE43Ca6")
signer.sendTransaction(...)
你可以在运行时里操作Fork,如重置回全新的Fork状态、从另一个区块号Fork,或者通过调用hardhat_reset
禁用Fork:
await network.provider.request({
method: "hardhat_reset",
params: [{
forking: {
jsonRpcUrl: "https://eth-mainnet.alchemyapi.io/v2/<key>",
blockNumber: 11095000
}
}]
})
你可以通过传递空参数来禁用Fork:
await network.provider.request({
method: "hardhat_reset",
params: []
})
这将重置Hardhat Network,在这里描述的状态下启动一个新的实例。
This will reset Hardhat Network, starting a new instance in the state described here.
在没有存档插件的情况下使用Infura,你只能在最近的区块中访问区块链的状态。 为了避免这个问题,你可以使用本地归档节点,或者像Alchemy这样提供归档数据的服务。
← 编写脚本 使用Hardhat 控制台 →