web3.eth.getAccounts() returns 使用 Infura 提供程序时为空数组。为什么?
web3.eth.getAccounts() returns empty array when using Infura provider. Why?
我试图使用 Infura api 制作以太坊网络应用程序。首先,我编译了一个 solidity 合约,然后使用 infura api 在 rinkeby 网络上部署它。这是我的部署脚本,似乎 运行 成功。
const HDWalletProvider = require("truffle-hdwallet-provider");
const Web3 = require('Web3');
const compileFactory = require('./build/CampaignFactory.json');
const provider = new HDWalletProvider(
"MY_SECRET_MNEMONIC",
"https://rinkeby.infura.io/v3/363ea9633bcb40bc8a857d908ee27094"
);
const web3 = new Web3(provider);
console.log("provider info: " + provider);
const deploy = async () => {
const accounts = await web3.eth.getAccounts();
console.log("account used: " + accounts[0]);
result = await new web3.eth.Contract(JSON.parse(compileFactory.interface))
.deploy({data: "0x"+compileFactory.bytecode})
.send({from: accounts[0]});
console.log("deployed to address: " + result.options.address);
};
deploy();
然后我创建了另一个脚本 web3.js,它使用 Infura api:
创建了一个 web3 提供程序
import Web3 from 'web3';
let web3;
if (typeof window !== 'undefined' && typeof window.web3!=='undefined') {
// we are in the browser and metamask is running.
web3 = new Web3(window.web3.currentProvider);
console.log("using metamask");
}
else {
// we are in server OR user without metamask.
const provider = new Web3.providers.HttpProvider(
"https://rinkeby.infura.io/v3/363ea9633bcb40bc8a857d908ee27094"
);
web3 = new Web3(provider);
console.log("using infura");
}
export default web3;
但是当我将此 web3.js 文件导入某处然后尝试使用 'web3' 对象时,它 return 的帐户数组为空。例如:
import web3 from '../../ethereum/web3';
...
const accounts = await web3.eth.getAccounts();
console.log("Account list: "+accounts); // returns empty array.
但理想情况下,它应该 return 与我的助记符关联的帐户列表。问题是什么?
一个天真的解决方案是在第二个脚本中使用 HDWalletProvider
,而不是 HttpProvider
。
你究竟想用第二个脚本做什么?我 怀疑 第二个脚本是你想用 DApp 部署的东西,所以包括你的助记符是一个很好的方法,可以把你所有的以太币送给第一个知道如何做的用户"view source".
如果是这样,在第一个脚本中,使用以下方式显示与您的助记符关联的地址:provider.getAddresses()
,然后将这些地址硬编码到第二个脚本中,供以后使用。当然,您将无法在第二个脚本中签署任何交易,但至少您可以读取与这些地址关联的数据。
将await window.ethereum.enable()
放在web3.eth.getAccounts()
之前,
或者使用 requestAccounts()
而不是 getAccounts()
:
await web3.eth.requestAccounts();
我试图使用 Infura api 制作以太坊网络应用程序。首先,我编译了一个 solidity 合约,然后使用 infura api 在 rinkeby 网络上部署它。这是我的部署脚本,似乎 运行 成功。
const HDWalletProvider = require("truffle-hdwallet-provider");
const Web3 = require('Web3');
const compileFactory = require('./build/CampaignFactory.json');
const provider = new HDWalletProvider(
"MY_SECRET_MNEMONIC",
"https://rinkeby.infura.io/v3/363ea9633bcb40bc8a857d908ee27094"
);
const web3 = new Web3(provider);
console.log("provider info: " + provider);
const deploy = async () => {
const accounts = await web3.eth.getAccounts();
console.log("account used: " + accounts[0]);
result = await new web3.eth.Contract(JSON.parse(compileFactory.interface))
.deploy({data: "0x"+compileFactory.bytecode})
.send({from: accounts[0]});
console.log("deployed to address: " + result.options.address);
};
deploy();
然后我创建了另一个脚本 web3.js,它使用 Infura api:
创建了一个 web3 提供程序import Web3 from 'web3';
let web3;
if (typeof window !== 'undefined' && typeof window.web3!=='undefined') {
// we are in the browser and metamask is running.
web3 = new Web3(window.web3.currentProvider);
console.log("using metamask");
}
else {
// we are in server OR user without metamask.
const provider = new Web3.providers.HttpProvider(
"https://rinkeby.infura.io/v3/363ea9633bcb40bc8a857d908ee27094"
);
web3 = new Web3(provider);
console.log("using infura");
}
export default web3;
但是当我将此 web3.js 文件导入某处然后尝试使用 'web3' 对象时,它 return 的帐户数组为空。例如:
import web3 from '../../ethereum/web3';
...
const accounts = await web3.eth.getAccounts();
console.log("Account list: "+accounts); // returns empty array.
但理想情况下,它应该 return 与我的助记符关联的帐户列表。问题是什么?
一个天真的解决方案是在第二个脚本中使用 HDWalletProvider
,而不是 HttpProvider
。
你究竟想用第二个脚本做什么?我 怀疑 第二个脚本是你想用 DApp 部署的东西,所以包括你的助记符是一个很好的方法,可以把你所有的以太币送给第一个知道如何做的用户"view source".
如果是这样,在第一个脚本中,使用以下方式显示与您的助记符关联的地址:provider.getAddresses()
,然后将这些地址硬编码到第二个脚本中,供以后使用。当然,您将无法在第二个脚本中签署任何交易,但至少您可以读取与这些地址关联的数据。
将await window.ethereum.enable()
放在web3.eth.getAccounts()
之前,
或者使用 requestAccounts()
而不是 getAccounts()
:
await web3.eth.requestAccounts();