javascriptethereumweb3jsgo-ethereum

How to authenticate and send contract method using web3.js 1.0


I am confused about how I should be executing a contract's method using the web3 1.0 library.

This code works (so long as I manually unlock the account first):

var contract = new web3.eth.Contract(contractJson, contractAddress);
contract.methods
  .transfer("0x0e0479bC23a96F6d701D003c5F004Bb0f28e773C", 1000)
  .send({
    from: "0x2EBd0A4729129b45b23aAd4656b98026cf67650A"
  })
  .on('confirmation', (confirmationNumber, receipt) => {
    io.emit('confirmation', confirmationNumber);
  });

I get this error (if I don't unlock manually first):

Returned error: authentication needed: password or unlock

The above code is an API endpoint in node.js, so I want it to unlock or authenticate programmatically.

There is no method in web3.js 1.0 to unlock the account.

I also don't think this is necessary (at least that's what I am confused about). Since I am managing accounts, I know what the private key is.

I am thinking the transaction needs to be signed with the private key?? Is this correct? Is this effectively the same thing as "unlocking the account"?

I tried doing this:

var contract = new web3.eth.Contract(contractJson, contractAddress);

var tx = {
  from: "...{fromAddress -- address that has the private key below}",
  to: "...",
  value: ...
};

var signed = web3.eth.accounts.signTransaction(tx, 
  "...{privateKey}");

console.log(signed);

var promise = web3.eth.sendSignedTransaction(signed);

I get this error:

Returned error: The method net_version does not exist/is not available

What is the easiest way to authenticate and submit a transaction?

Ideally, I want to use the first approach in my code sample, as it is the cleanest.


Solution

  • This code allows me to sign a transaction server-side (node.js) using the privateKey from the account I created (using web3.eth.accounts.create()), and send the signed transaction to the network without having to unlock the account.

    I am using Geth 1.7.1

      var contract = new web3.eth.Contract(contractJson, contractAddress);
      var transfer = contract.methods.transfer("0x...", 490);
      var encodedABI = transfer.encodeABI();
    
      var tx = {
        from: "0x...",
        to: contractAddress,
        gas: 2000000,
        data: encodedABI
      }; 
    
      web3.eth.accounts.signTransaction(tx, privateKey).then(signed => {
        var tran = web3.eth.sendSignedTransaction(signed.rawTransaction);
    
        tran.on('confirmation', (confirmationNumber, receipt) => {
          console.log('confirmation: ' + confirmationNumber);
        });
    
        tran.on('transactionHash', hash => {
          console.log('hash');
          console.log(hash);
        });
    
        tran.on('receipt', receipt => {
          console.log('reciept');
          console.log(receipt);
        });
    
        tran.on('error', console.error);
      });