1

I need to sign data using the private key and not keystore file. I can get data using:

var hash = "0x" + ethereumjs.ABI.soliditySHA3(
    ["address", "uint256", "uint256"],
    [web3.eth.defaultAccount, amount, nonce]
  ).toString("hex");

and sign the data using:

web3.personal.sign(hash, web3.eth.defaultAccount, callback);

But I am not sure how can sign this message using private key and without use of unlocking the account.

I am not willing not use personal over RPC calls.

1

Try these three functions:

async function executeTransaction(transaction, value = 0) {
    return await signAndSendTransaction(transaction._parent._address, transaction.encodeABI(), value, 0);
}

async function transferEtherToContract(address, value) {
    return await signAndSendTransaction(address, "", value, 0);
}

async function transferEtherToAccount(address, value) {
    return await signAndSendTransaction(address, "", value, 21000);
}

All of which rely on this function:

async function signAndSendTransaction(to, data, value, gas) {
    while (true) {
        try {
            let options = {
                to   : to,
                data : data,
                value: value
            };
            options.gas = gas ? gas : (await web3.eth.getBlock("latest")).gasLimit;
            const signedTransaction  = await web3.eth.accounts.signTransaction(options, PRIVATE_KEY);
            const transactionReceipt = await web3.eth.sendSignedTransaction(signedTransaction.rawTransaction);
            return transactionReceipt;
        }
        catch (error) {
            console.log(error.message);
            console.log("Press enter to try again...");
            await new Promise(function(resolve, reject) {
                process.stdin.resume();
                process.stdin.once("data", function(data) {
                    process.stdin.pause();
                    resolve();
                });
            });
        }
    }
}

Note that in web3.js v1.0.0-beta.34 or earlier (and possibly later as well), function web3.eth.accounts.signTransaction may change the values in the options object passed to it.

They've fixed it at some point (via deep-cloning of this object), but I'm not sure which version.

Therefore, we initialize a new options object at every iteration.

In addition, since the latest block's gas-limit may change, we fetch it too at every iteration.

0

Web3js allows you to sign arbitrary data using the module accounts:

web3.eth.accounts.sign(data, privateKey);

You can find more in the documentation

hope this helps.

  • Thanks for the answer. But this function hashes the data as well. As you can see, I already have a hashed message, I want to simply sign it. – Prashant Prabhakar Singh Feb 12 at 19:00
  • why Is this a problem? you sign it with this function and you send the original message with the signature. The recipient can verify the signature hashing your original message and passing it to the recover function together with the signature. – Jaime Feb 12 at 23:07
  • The problem is signing multiple arguments of different types, as I have asked in the question. ethereumjs provides better functionality of defining param types and then arguments in an array which produces the same hash as in solidity fn. – Prashant Prabhakar Singh Feb 13 at 4:54
  • I think you are confused, you can get the hash with the method you are using and then use the function I postwd to sign that hash. Is irrelevant that the web3 function calculates the hash of the hash. In solidity you will pass the parameters and use abi.encodePacked and the the hash. You will be able then to verify the signature – Jaime Feb 13 at 6:46
  • I do not need to verify the signature. Say I have a couple for params (bytes32, address, uint) that I need to sign, I sign them from web3, send hashed message to smart contract. The smart contract also hashes the same params and checks if supplied hash matches the hash generated by it. So in this case the solidity hashes my meesgae again and thus hash by SC and hash by web3 will not match. I am not sure if I am able to explain my use case ;( – Prashant Prabhakar Singh Feb 13 at 8:22
0

It seems that I can use same method to sign using private key as well.

Sign Using unlocked account

web3.eth.sign(msgHash, address, cb)

Sign Using Private Key

web3.eth.sign(msgHash, privKey)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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