使用web3.js .deploy()部署合约报错sender account not recognized,如何解决?
问题描述
使用web3.eth.accounts.create()生成的账户调用合约部署方法时,执行contract.deploy().send()报错:
Uncaught Error Error: Returned error: sender account not recognized
相关代码
exports.deployContract = async function (account, contractData) { var contract = new web3.eth.Contract(contractData.abi); const randomID = getUUID(); toReturn = { contractAddress: "", }; const mainAccount = { address: account.address, privateKey: account.privateKey, }; // Deploy contract const executed = await contract .deploy({ data: contractData.evm.bytecode.object, arguments: [randomID] }) .send({ gas: 900000, from: mainAccount.address }); console.log("Contract deployed to", executed.options.address); var storedId = ""; await executed.methods .id() .call() .then((result) => { storedId = result; console.log("ID: ", result); }); return { address: executed.options.address, someid: storedId, }; };
解决方案
错误核心是web3.eth.accounts.create()生成的账户未在当前连接的区块链节点注册/解锁,节点无法识别该账户的交易发起身份。以下是具体解决方法:
测试环境下解锁账户
若连接Ganache、Hardhat等测试节点,可调用节点API解锁账户:// 解锁账户,第三个参数为解锁时长(单位秒),仅适用于测试环境 await web3.eth.personal.unlockAccount(mainAccount.address, '', 3600);注意:生产环境禁止使用此方法,存在极高安全风险。
使用私钥签名交易(通用安全方案)
无需在节点注册账户,直接用私钥签名交易后发送,修改部署代码如下:exports.deployContract = async function (account, contractData) { var contract = new web3.eth.Contract(contractData.abi); const randomID = getUUID(); const mainAccount = { address: account.address, privateKey: account.privateKey, }; // 构建部署交易对象 const deployTx = contract.deploy({ data: contractData.evm.bytecode.object, arguments: [randomID] }); // 估算gas(可选,避免gas设置不足) const gasEstimate = await deployTx.estimateGas({ from: mainAccount.address }); // 签名交易,chainId需匹配当前网络(Ganache默认1337,以太坊主网1) const signedTx = await web3.eth.accounts.signTransaction({ from: mainAccount.address, data: deployTx.encodeABI(), gas: gasEstimate || 900000, chainId: 1337 }, mainAccount.privateKey); // 发送签名后的交易并获取回执 const txReceipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction); // 初始化部署后的合约实例 const executed = new web3.eth.Contract(contractData.abi, txReceipt.contractAddress); // 获取存储的ID const storedId = await executed.methods.id().call(); console.log("Contract deployed to", txReceipt.contractAddress); console.log("ID: ", storedId); return { address: txReceipt.contractAddress, someid: storedId, }; };检查账户余额
确认新创建的账户在当前区块链网络中有足够的原生代币(如ETH)支付gas费用,余额不足也可能导致交易失败。
内容的提问来源于stack exchange,提问作者Muthu Arumugam
相关产品推荐
相关产品推荐

