如何在Hardhat投票脚本中切换使用命名用户账户
问题描述
我正在开发一个简单的治理协议,跟随教程编写的代码已能正常运行。
在Hardhat配置文件中,我已在accounts字段添加了两个私钥:
const config: HardhatUserConfig = { defaultNetwork: "hardhat", networks: { hardhat: { chainId: 31337, allowUnlimitedContractSize: true }, mumbai: { url: INFURA_RPC_URL, accounts: [PRIVATE_KEY, PRIVATE_KEY_2], chainId: 80001, }, }, //... }
我编写了部署脚本用于创建治理代币:
const deployGovernanceToken: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { // @ts-ignore const { getNamedAccounts, deployments, network } = hre const { deploy, log } = deployments const { deployer, user } = await getNamedAccounts() const governanceToken = await deploy("GovernanceToken", { from: deployer, args: [], log: true, waitConfirmations: networkConfig[network.name].blockConfirmations || 1, }) await delegate(governanceToken.address, deployer, user) //... } const delegate = async (governanceTokenAddress: string, delegatedAccount: string, userAccount: string) => { const governanceToken = await ethers.getContractAt("GovernanceToken", governanceTokenAddress) const transactionResponse = await governanceToken.mint(userAccount, "10000000000000000000000000"); await transactionResponse.wait(1) console.log(`Checkpoints: ${await governanceToken.numCheckpoints(delegatedAccount)}`) }
此外我还有一个用于提案投票的脚本:
export async function vote(proposalId: string, voteWay: number, reason: string) { console.log("Voting...") const signer = await ethers.getSigners() console.log('signers:' + signer); const governor = await ethers.getContract("GovernorContract") const voteTx = await governor.castVoteWithReason(proposalId, voteWay, reason) const voteTxReceipt = await voteTx.wait(1) console.log(voteTxReceipt.events[0].args.reason) const proposalState = await governor.state(proposalId) console.log(`Current Proposal State: ${proposalState}`) if (developmentChains.includes(network.name)) { await moveBlocks(VOTING_PERIOD + 1) } }
请问如何修改投票脚本,使其使用预先配置的命名user账户进行投票?
解决方案
要让投票脚本使用预先配置的user命名账户,核心是通过Hardhat的getNamedAccounts获取该账户地址,再拿到对应签名器,最后用这个签名器连接合约发起交易。
修改后的投票脚本
import { ethers, network } from "hardhat" import { developmentChains, moveBlocks } from "../helper-hardhat-config" // 确保导入项目依赖的工具函数 export async function vote(proposalId: string, voteWay: number, reason: string) { console.log("Voting...") // 获取预先配置的user命名账户地址 const { user } = await ethers.getNamedAccounts() // 通过user地址获取对应的签名器(用于发起交易) const userSigner = await ethers.getSigner(user) console.log(`Using user account: ${user}`) // 用user签名器连接Governor合约,确保交易由user账户发起 const governor = await ethers.getContract("GovernorContract", userSigner) const voteTx = await governor.castVoteWithReason(proposalId, voteWay, reason) const voteTxReceipt = await voteTx.wait(1) console.log(voteTxReceipt.events[0].args.reason) const proposalState = await governor.state(proposalId) console.log(`Current Proposal State: ${proposalState}`) if (developmentChains.includes(network.name)) { await moveBlocks(VOTING_PERIOD + 1) } }
关键修改说明
- 获取命名账户:通过
ethers.getNamedAccounts()拿到配置好的user账户地址,这要求你在Hardhat配置中提前定义namedAccounts映射。 - 获取对应签名器:用
ethers.getSigner(user)拿到user账户的签名实例,后续交易都会由该账户签名。 - 签名器连接合约:在获取
GovernorContract实例时传入userSigner,替代默认的部署者签名器,确保投票交易由user账户发起。
补充配置要求
如果你的Hardhat配置里还没定义namedAccounts,需要在hardhat.config.ts中添加如下配置,让user对应到你配置的第二个私钥:
// hardhat.config.ts中新增配置 namedAccounts: { deployer: { default: 0, // 对应accounts数组中的第一个私钥(PRIVATE_KEY) }, user: { default: 1, // 对应accounts数组中的第二个私钥(PRIVATE_KEY_2) }, }
内容的提问来源于stack exchange,提问作者Ritzy Dev
相关产品推荐
相关产品推荐

