You can use a private key directly with:
web3.eth.accounts.wallet.add(privateKey);
After this you can use deploy (provided enough funds are available in the account). Web3.js seem to recognize the fact that the private key is available. The from address in the deploy corresponds to the appropriate private key.
Here is a full example using 2 private keys (note very insecure!):
const Web3 = require('web3');
const solc = require('solc');
let web3 = new Web3();
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545'));
var input = {
language: 'Solidity',
sources: {'test.sol': {content: 'pragma solidity ^0.5.11;contract TestContract { function f() public { } }' }},
settings: {outputSelection: {'*': {'*': [ '*' ]}}}
}
var output = JSON.parse(solc.compile(JSON.stringify(input))).contracts['test.sol'].TestContract;
let abi = output.abi;
let code = '0x' + output.evm.bytecode.object;
const privateKey1 = web3.utils.keccak256('Test1');
const address1 = web3.eth.accounts.privateKeyToAccount(privateKey1).address;
web3.eth.accounts.wallet.add(privateKey1);
const privateKey2 = web3.utils.keccak256('Test2');
const address2 = web3.eth.accounts.privateKeyToAccount(privateKey2).address;
web3.eth.accounts.wallet.add(privateKey2);
async function f() {
let coinbase = await web3.eth.getCoinbase();
web3.eth.sendTransaction({
from: coinbase,
to: address1,
value: '20000000000000000'
}).on('transactionHash', async () => {
await new web3.eth.Contract(abi).deploy({ data: code }).send({ gas: '1000000', from: address1});
});
web3.eth.sendTransaction({
from: coinbase,
to: address2,
value: '20000000000000000'
}).on('transactionHash', async () => {
await new web3.eth.Contract(abi).deploy({ data: code }).send({ gas: '1000000', from: address2});
});
}
f();