I've got a contract method that checks the signer of a message using the solidity ecrecover function. In my truffle test file I now want to check if this is done correctly. Therefore I need to sign a message within the testfile using a private key.

Using this

let signedMessage = await web3.personal.sign("data", accounts[0])

does not work with error "Method personal_sign not supported."

Any idea how to do this? Thanks for you help!

3 Answers 3


I went through exactly the same problem a couple of days ago and it seems that the personal_sign method is rarely exposed for security reason.

I sorted this out using a random private key and a JavaScript library called ethereumjs-util

var EthUtil             = require('ethereumjs-util');

const messageToSign = "hello world";
const privateKey = "43f2ee33c522046e80b67e96ceb84a05b60b9434b0ee2e3ae4b1311b9f5dcc46";

var msgHash = EthUtil.hashPersonalMessage(new Buffer(messageToSign));
var signature = EthUtil.ecsign(msgHash, new Buffer(privateKey, 'hex')); 
var signatureRPC = EthUtil.toRpcSig(signature.v, signature.r, signature.s)


That returns:


Working Code is available on my github

  • Thanks! Worked for me! However, I replaced the random private key with the one generated by testrpc so that I can validate that the signer is actually accounts[0]. That is ok, but I need to do this every time I start a new testrpc process.
    – moinlars
    Apr 4, 2018 at 11:02
  • 1
    When you start testrpc, you can force it to use an account by default rather than autogenerate a new one all the time: testrpc --account="0x0F0F0F0F0F%PRIVATE KEY%,10000000000000000000000%INITIAL BALANCE IN WEI%" --secure -u 0 - more info Apr 4, 2018 at 11:06
  • @Greg Jeanmart Hi, I have a similar problem with web3.eth.personal.sign and web3.eth.sign here: ethereum.stackexchange.com/questions/52584/… But till now I could not solve this problem. Thank you
    – Questioner
    Jul 4, 2018 at 14:22
  • This works but curious as to why the hashes aren't the same when I use web.utils.sha3 - nor does it work without the hash function above?
    – evanjmg
    Feb 20, 2022 at 18:55

There is no need to hardcode a private key or import a dependency. The accounts supplied by truffle+ganache are accessible in the web3.eth provider.

You can use web3.eth.sign to sign arbitrary data. It will hash the data using keccak256 and sign the hash. It is async so you have to await it, and it returns the 65-byte signature.

const sig = await web3.eth.sign(data, fromAccount)
const txSig = await web3.eth.signTransaction(tx, fromAccount)

Since you cannot use the addresses available under the accounts to sign, the best way is to create one (or more) address(es) using web3.eth.accounts.wallet.create(x) (where x = number of accounts you want to generate).

Within your truffle test, you can create the wallet in the before(...) hook, and reference the newly created address(es) to some globally scoped variables.

contract("Your Contract", async (accounts) => {

    let firstAccount,

    before(async () => {
        await web3.eth.accounts.wallet.create(3) // create 3 accounts

        firstAccount = web3.eth.accounts.wallet[0]
        secondAccount = web3.eth.accounts.wallet[1]
        thirdAccount = web3.eth.accounts.wallet[2]

    // tests here...


Each newly created address will have both property and method attach to them (see web3 docs):

Both give you two ways to sign your message.

via web3.eth.accounts.wallet[...].sign(...)

let signature = web3.eth.accounts.wallet[firstAccount].sign("Message To Sign").signature

or alternatively

via web3.eth.accounts.sign(...), using privateKey

let signature = web3.eth.accounts.sign("Message To Sign", firstAccount.privateKey).signature

NB: you can also use object destructuring syntax to extract the signature (from the object returned by both signing methods). This also make the code shorter and a bit easier to read.

// first method
let { signature } = web3.eth.accounts.wallet[firstAccount].sign("Message To Sign")

// second method
let { signature } = web3.eth.accounts.sign("Message To Sign", firstAccount.privateKey)

Your Answer

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

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