Hey everyone! I’m trying to allow users to sign a transacation, which is meant to call a smart contract method, on the front-end, so Metamask would prompt the user to sign message/transaction which would be sent to the back-end in order to be propagated to the blockchain. This is what I currently have on the front-end in order to achieve this goal:
const chainId = 3 // Ropsten
const from = await signer.getAddress()
const nonce = await signer.getTransactionCount()
const contractInterface = new ethers.utils.Interface(Contract.abi)
const domain = {
name: 'Contract method call',
version: '1',
chainId,
}
const types = {
Transaction: [
{ name: 'from', type: 'address' },
{ name: 'to', type: 'address' },
{ name: 'nonce', type: 'uint256' },
{ name: 'chainId', type: 'uint16' },
{ name: 'gas', type: 'string' },
{ name: 'gasPrice', type: 'string' },
{ name: 'gasLimit', type: 'string' },
{ name: 'data', type: 'string' },
],
}
const txObj = {
from,
to,
nonce,
chainId,
gas: ethers.utils.hexlify(500000),
gasPrice: ethers.utils.hexlify(gasPrice),
gasLimit: ethers.utils.hexlify(500000),
data: contractInterface.encodeFunctionData('methodName', [arg1, arg2]),
}
const rawSignature = await signer._signTypedData(domain, types, txObj)
const signature = rawSignature.substring(2)
const r = '0x' + signature.substring(0, 64)
const s = '0x' + signature.substring(64, 128)
const v = parseInt(signature.substring(128, 130), 16)
const unsignedTx = { ...txObj }
delete unsignedTx.from
delete unsignedTx.gas
const signedTx = ethers.utils.serializeTransaction(unsignedTx, { r, s, v })
The signedTx is then sent to the back-end which will eventually sendRawTransaction
. Unfortunatly this approach isn’t working and I am getting insufficient funds for gas * price + value
even though I have more than enough in wallet. What’s the right way to go about this?
Any help would be much appreciated.
Thank you so much for your time!