I tried this method to deploy a contract. It is described in the web3.eth.Contract documentation.

var contract = new web3.eth.Contract (JSON.parse (abi_json_string));
contract.deploy ({ data: contract_bytecode }).send ({ from: from_acct, gas: 160000, gasPrice: 8000000 });

However, it gives me the following error:

authentication needed: password or unlock

I can't find a way to sign the transaction using this method. All the examples, show it as a simple call to deploy and then send. What if you want to sign it first?

So I tried deploying a contract using the same method that I use to sign and send regular ether transactions.

var transaction_data =
    from: from_account,
    to: "0x0000000000000000000000000000000000000000",
    data: contract_bytecode,
    gas: 160000,
    gasPrice: 8000000,
    nonce: nonce

var common = eth_common_lib.forCustomChain ('ropsten', { networkId: 1994, chainId: 1994, name: 'geth' }, 'muirGlacier');
var transaction = new eth_tx_lib.Transaction (transaction_data, { "common": common });

var bytes = [];
for (var b = 0; b < private_key.length; b += 2)
    var hex_byte = private_key.substr (b, 2);
    var int_byte = parseInt (hex_byte, 16);
    bytes.push (int_byte);

transaction.sign (Buffer.from (bytes));

var serialized_transaction = transaction.serialize ();

web3.eth.sendSignedTransaction ("0x" + serialized_transaction.toString ("hex")).catch ((error) => { console.log (error); });

I get a receipt when I do it this way but it shows the contractAddress as null. I'm guessing that means the deployment failed.

contractAddress: null

Is web3.eth.Contract the only possible way to deploy a contract? If so, is there a way to do it from a locked account?

1 Answer 1


Try this (tested with web3.js v1.2.1):

const Web3 = require("web3");

const NODE_ADDRESS  = "YourNodeAddress";
const PRIVATE_KEY   = "YourPrivateKey";
const CONTRACT_ARGS = ["arg1", "arg2"];

async function send(web3, account, transaction) {
    const options = {
        data: transaction.encodeABI(),
        gas : await transaction.estimateGas({from: account.address})
    const signed  = await web3.eth.accounts.signTransaction(options, account.privateKey);
    const receipt = await web3.eth.sendSignedTransaction(signed.rawTransaction);
    return receipt;

async function run() {
    const web3        = new Web3(NODE_ADDRESS);
    const account     = web3.eth.accounts.privateKeyToAccount(PRIVATE_KEY);
    const contract    = new web3.eth.Contract(JSON.parse(abi_json_string));
    const options     = {data: contract_bytecode, arguments: CONTRACT_ARGS};
    const transaction = contract.deploy(options);
    const receipt     = await send(web3, account, transaction);
    if (web3.currentProvider.constructor.name == "WebsocketProvider")


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.