0

I want to execute the method1 of my contract from web3js. And I want to sign the transaction offline, I mean with web3js, and not to delegate that in the node. I've tried these 2 approaches.

Both sign locally, right? Is there any difference? Any benefits for each of them? Is there a better way to validate an event is in the response (approach 2)?

Approach 1: Build a raw transaction and sign it explicitly. Raises an "invalid type" error:

// Instantiate contract
const contract = new web3.eth.Contract(contractAbi, contractAddress, { gasPrice: gasPrice, gas: 4500000 });

// Import account from private kwy
var account = web3.eth.accounts.privateKeyToAccount(privateKey);

// Estimate gas
const estimatedGas = await contract.methods.method1().estimateGas({ from: account.address });

// Build transaction to call method1 in the contract
var txCount = await web3.eth.getTransactionCount(account.address);
var gasPrice = await web3.eth.getGasPrice();
var data = contract.methods.method1().encodeABI;
const txObject = {
    nonce:    web3.utils.toHex(txCount),
    to:       contractData.address,
    data:     data,
    gasLimit: web3.utils.toHex(800000),
    gasPrice: web3.utils.toHex(gasPrice),
    gas:      estimatedGas,
}

// Sign the transaction
const tx = new Tx(txObject);
tx.sign(Buffer.from(account.privateKey.slice(2), 'hex'));

// Serialize the transaction
const serializedTx = '0x' + tx.serialize().toString('hex');

// Broadcast the transaction
var TxHash = await web3.eth.sendSignedTransaction(serializedTx);

Approach 2: Add my account to a wallet, so the wallet sign it automatically. It works:

// Instantiate contract
const contract = new web3.eth.Contract(contractAbi, contractAddress, { gasPrice: gasPrice, gas: 4500000 });

// Import account from private kwy
var account = web3.eth.accounts.privateKeyToAccount(privateKey);

// Create wallet and add account
const wallet = web3.eth.accounts.wallet.create();
wallet.add(account);

// Estimate gas
const estimatedGas = await contract.methods.method1().estimateGas({ from: account.address });

// Call contract method
receipt = await contract.methods.method1().send({ from: account.address, gas: estimatedGas });

// Validate result looking for an event in the receipt
var eventName = "Event1";
var success = ((receipt != undefined) && (receipt.events != undefined) && (eventName in receipt.events) && (receipt.events[eventName].event !== undefined));

Your Answer

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

Browse other questions tagged or ask your own question.