2

I was trying to use Infura api to make an Ethereum web app. First I compiled a solidity contract and then deployed it using infura api on rinkeby network. Here is my deploy script which seems to be running successfully.

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

Then I created another script web3.js which creates a web3 provider using Infura api:

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;

but when I import this web3.js file somewhere and then try to use 'web3' object, it returns empty array of accounts. For example:

import web3 from '../../ethereum/web3';
...
const accounts = await web3.eth.getAccounts();
console.log("Account list: "+accounts); // returns empty array.

But ideally it should return the accounts list associated with my mnemonic. What is the problem?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Tarun Khare
  • 1,447
  • 6
  • 25
  • 43
  • What mnemonic? Nothing in your code uses a mnemonic to generate private keys. Infura doesn't know anyone's private keys, so you need to have your key client-side to sign transactions. – user94559 Aug 18 '18 at 15:53
  • Ah, I see that your deploy script _does_ use a provider that accepts a mnemonic. But you're not using that in the code that's failing. You need to. – user94559 Aug 18 '18 at 15:54
  • where exactly do I need to use mnemonic? I have already used it once to deploy the contract on blockchain in the first script. Can you tell the exact place and code I need to rectify – Tarun Khare Aug 18 '18 at 19:01
  • Every transaction needs to be signed with your private key. This includes both the transaction to deploy the contract as well as every transaction you use to interact with the contract. You need to use the same sort of `HDWalletProvider` wherever you want to use that private key. – user94559 Aug 18 '18 at 19:17
  • 1
    can you elaborate further? maybe in some sort of code in answer? Thanks. – Tarun Khare Aug 18 '18 at 19:32
  • I don't know what more to tell you. Your post already has the code you need. You're just not using it in your second code snippet. – user94559 Aug 18 '18 at 19:33

2 Answers2

2

A naive solution is to use the HDWalletProvider in your second script, instead of the HttpProvider.

What exactly do you want to do with the second script? I suspect that the second script is something that you want to deploy with a DApp, so including your mnemonic there is a good way to give away all your ether to the first user who knows how to "view source".

If so, in the first script, display the addresses associated with your mnemonic using: provider.getAddresses() and then hard-code those addresses into the second script, for later usage. Naturally, you won't be able to sign any transactions in the second script, but at least you can read data associated with those addresses.

carver
  • 2,229
  • 12
  • 28
  • In case I want to initialize provider in client side code, I don't think we should HDWallletProvider with mnemonic since it's a secret. Is that true ? – Brian Pham Jun 06 '19 at 03:14
0

Put await window.ethereum.enable() before web3.eth.getAccounts(),
Or use requestAccounts() instead of getAccounts() :

await web3.eth.requestAccounts();
Mohsen
  • 4,049
  • 1
  • 31
  • 31