6

I'm deploying contract using Truffle and got an error Error: authentication needed: password or unlock. I already checked related questions and found only ugly hacks like "unlock desired account directly on node using web3.personal.unlockAccount". But I do not want to connect to my node each time (I have 3 test networks in my truffle.js) when I want to deploy new version.

My question is: is there any way to specify password in truffle infrastructure to unlock account specified in field from under the network item? password or pass does not work.

6
  • 1
    With truffle you can use a providerengine like this truffleframework.com/tutorials/using-infura-custom-provider, but with your own node.
    – Ismael
    Aug 29, 2017 at 17:04
  • 1
    @Ismael thank you for reply, but Infura provides very poor set of RPC calls. For instance, with Infura you cannot use even subscription because each "subscribe" call preceded with "createFilter" one that does not supported with Infura. I already tried it.
    – Alex G.P.
    Aug 30, 2017 at 3:19
  • It should work the same if you use your own url to the geth instance instead of the infura one.
    – Ismael
    Aug 30, 2017 at 4:52
  • It checked this article twice. It looks like absolutely useless for my case. Could you please point me where exactly in your article specified account unlocking process? I see only wallet derivation, connection to remote node and... that's all.
    – Alex G.P.
    Aug 30, 2017 at 8:51
  • To use a UTC file instead of the HD wallet you should do something like const EthereumWallet = require('ethereumjs-wallet'); const jsonWallet = fs.readFileSync('<<path to UTC file>>'); const parsedWallet = JSON.parse(jsonWallet); const wallet = EthereumWallet.fromV3(parsedWallet, '<<YOUR_PASSWORD_GOES_HERE>>');
    – Ismael
    Aug 30, 2017 at 19:27

2 Answers 2

10

Ok, finally I added some code to unlock account on the fly. I do not want to store password in truffle.js (but it is possible), so doing next things:

Changed 1_initial_migration.js this way:

const Web3 = require('web3');

const TruffleConfig = require('../truffle');

var Migrations = artifacts.require("./Migrations.sol");


module.exports = function(deployer, network, addresses) {
  const config = TruffleConfig.networks[network];

  if (process.env.ACCOUNT_PASSWORD) {
    const web3 = new Web3(new Web3.providers.HttpProvider('http://' + config.host + ':' + config.port));

    console.log('>> Unlocking account ' + config.from);
    web3.personal.unlockAccount(config.from, process.env.ACCOUNT_PASSWORD, 36000);
  }

  console.log('>> Deploying migration');
  deployer.deploy(Migrations);
};

And instead of calling truffle deploy I am running it like:

ACCOUNT_PASSWORD=MySup4P@ssw0rd truffle deploy

As you can see node url and port are taken from config, so it is possible to add password fields there, then check in migration for "callability" i.e.:

...
password: function() { return process.env.ACCOUNT_PASSWORD }
...

-- same thing but password logic will be moved to truffle.js

3
  • 2
    You do not want to store the password in truffle.js, but are fine with having it in your environment and console command history?
    – WBT
    Jul 31, 2019 at 15:46
  • Works, but it needs to be web3.eth.personal.unlockAccount as of web3 1.0.
    – rook
    Oct 21, 2020 at 17:19
  • This doesn't work for me when deploying to a quorum chain. Receiving abort(Error: Invalid JSON RPC response: "") alongside with a 630kb error output. Any updates on that?
    – Ric Hard
    Feb 11, 2021 at 17:58
0

If you're using this for dev purposes, there could be another way which is to have a script which unlocks the accounts periodically. The advantage of this method is that the migration scripts need not be updated.

An example of this can be found in the trufflesuite/truffle geth-accounts.js. Although the method above is still highly inefficient, since it tries to unlock accounts in an infinite loop. A slightly remodified version looks like this


 function unlockAccounts () {
  eth.accounts.forEach(function (account) {
    console.log('Unlocking ' + account + '.');
    personal.unlockAccount(account, '', 86400);
  });
}


function createAccounts() {
  for (var i = 0; i < 10; i++) {
    acc = personal.newAccount("");
    eth.sendTransaction({
      from: eth.accounts[0], 
      to: acc, 
      value: web3.toWei(100, "ether")
    });
  }
  unlockAccounts();
  setInterval(unlockAccounts, 86000);
}

createAccounts();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.