Web3.js Account Creation – How to Create Account with Mnemonic or Private Key and Call Contracts

infurareactropstentrufflewallets

I have a simple React Project with web3@1.2.4 installed and I want to call a contract's method like this:

await maincontract.methods.CurrentMethod("arguments").send({ from: accounts[0]/*my account should go here*/, gas: 3000000 });

This code works well in localhost Ganache but instead of accounts[0] from localhost I want to use my own account that I have in Ropsten network and I guess that to use that account, I need an infura project that can connect me to the Ropsten network and I also need the mnemonic phrase or private key of that account in order to use that account to call contract methods.

So basically how can I use my account located in Ropsten network to call a contract located in the same, Ropsten network? Do I need to pass in mnemonic phrase? Do I need to pass private key? what do I need to do?

I have tried using truffle-wallet-provider but it doesn't install, don't even ask about the errors. There is another truffle-wallet-provider.

This is what I am trying locally on Ganache but it doesn't seem to work, the contract code is working great, tested using Ethereum Remix.

const web3 = new Web3("HTTP://127.0.0.1:7545"); //Ganache Local Host
    const maincontract = new web3.eth.Contract(ABI, CONTRACT_ADDRESS); //already deployed the contract using Ethereum Remix and copied the Contract address and ABI
    const privateKey = "c1937e53c13e500644f45d77e075ca0059dcbae204ef06aa08494a129d871fdc"; //took the account right below the first account and copy pasted its private key
    const account = web3.eth.accounts.privateKeyToAccount(privateKey); //creating account
    const transaction = maincontract.methods.CurrentMethod("arguments");
    const options = { //TransactionConfig I guess
      to: transaction._parent._address,
      data: transaction.encodeABI(),
      gas: await transaction.estimateGas({ from: account.address }),
      gasPrice: await web3.eth.getGasPrice()
    };
    await web3.eth.accounts.signTransaction(options, privateKey).then(tx => {
      //signed = tx.rawTransaction; 
      console.log(tx.rawTransaction.toString()) //this is showing random Hex but I see no transaction log in Ganache
    });

Best Answer

Your scheme relies on your account being unlocked on the node that you're connected to.

While this scheme is reasonable for testing your system on your local host via Ganache, it is not recommended for an operational system, because anyone hacking your node could exploit your (unlocked) account at will.

Instead of unlocking your account on the node that you're connected to, you may want to consider signing each transaction before sending it to the node, thus minimizing the number of "breach points" in your sysetm.

For example:

const account = web3.eth.accounts.privateKeyToAccount(privateKey);
const transaction = maincontract.methods.CurrentMethod("arguments");
const options = {
    to      : transaction._parent._address,
    data    : transaction.encodeABI(),
    gas     : await transaction.estimateGas({from: account.address}),
    gasPrice: await web3.eth.getGasPrice() // or use some predefined value
};
const signed  = await web3.eth.accounts.signTransaction(options, privateKey);
const receipt = await web3.eth.sendSignedTransaction(signed.rawTransaction);
Related Topic