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();