This may be a very basic question, I don't know why but I am unable to find correct solution to how can I call my contract's method using sendTransaction. I have a transfer(address, uint256) function which I want to call using sendTransaction and callTransaction. I have my contract compiled and I have it's abi and address. Now, how can I call different metrhods of the contract using sendTransaction?
I was reading the question Syntax for calling contract state changing methods, and I got explanations for function having single parameter but what if it has more than a parameter of different types, like here transfer() function accepts 2 parameters.
- 8,026
- 5
- 40
- 79
5 Answers
Posting solution to my own question for anyone who needs it.
To call a contract function from geth:
const contractAbi = eth.contract(AbiOfContract);
const myContract = contractAbi.at(contractAddress);
// suppose you want to call a function named myFunction of myContract
const getData = myContract.myFunction.getData(function_parameters);
// finally pass this data parameter to send Transaction
web3.eth.sendTransaction({ to:Contractaddress, from:Accountaddress, data: getData });
Note: You can add other fields in sendTransaction like value etcetera, I have skipped that for simplicity to new use users.
To all the users who face challanges with signing data using private key. The pseudo code for signing and sending a transaction to contract using private key:
const Tx = require('ethereumjs-tx')
const web3 = new Web3()
web3.setProvider(new web3.providers.HttpProvider(web3RpcAddr))
const yourContract = new web3.eth.Contract(yourContract.abi, yourContract.address)
function sendCoin(toAddress, amount) {
const nonce = await web3.eth.getTransactionCount(fromAddress, 'pending')
const extraData = await yourContract.methods.transfer(toAddress, amount)
const data = extraData.encodeABI()
const txObj = {
from: adminAddress,
to: yourContractAddress,
data,
value: '0',
gas: gasSent, // calculation of gas and gas Price is skipped here
gasPrice: gasPriceSent,
privKey: adminPvtKey,
nonce
}
let signedTx = await signTx(txObj)
signedTx = "0x" + signedTx.serialize().toString('hex')
await submitSignedTx(signedTx)
}
async function signTx(payload) {
let { from, to, data, value, gas, gasPrice, privKey, nonce } = payload
let txParams = {
to,
data,
value: web3.utils.toHex(value),
gasPrice: web3.utils.toHex(gasPrice),
gas: web3.utils.toHex(gas),
nonce: web3.utils.toHex(nonce)
}
const tx = new Tx(txParams)
privKey = await _validatePrivKey(privKey)
privKey = new Buffer(privKey, 'hex')
tx.sign(privKey)
privKey = null
return tx
}
async function submitSignedTx(serializedTx) {
return new Promise((fullfill, reject) => {
web3.eth.sendSignedTransaction(serializedTx)
.on('transactionHash', txHash => {
l.info('transaction sent. hash =>', txHash)
return fullfill({success: true, txHash : txHash})
})
.on('error', e => {
// console.log('unable to send tx', e)
l.error(logmsg, e.message)
return fullfill({success: false, message: e})
})
})
}
- 123
- 7
- 8,026
- 5
- 40
- 79
Have you tried:
// In Javascript
myContract.transfer(otherAddress, aNumber, { from: myAccount });
// Or
myContract.transfer.sendTransaction(otherAddress, aNumber, { from: myAccount });
// Or
myContract.transfer.call(otherAddress, aNumber, { from: myAccount });
- 7,366
- 17
- 32
-
correct for web3.js, but please provide references to the documentation. – Paul S Sep 20 '16 at 18:19
Improving @Prashant Prabhakar Singh answer:
var contractAbi = eth.contract(AbiOfContract);
var myContract = contractAbi.at(contractAddress);
// suppose you want to call a function named myFunction of myContract
var getData = myContract.myFunction.getData("1","boy");//just parameters you pass to myFunction
// And that is where all the magic happens
web3.eth.sendTransaction({
to:ContractAddress,//contracts address
from:web3.eth.accounts[0],
data: getData,
value: web3.toWei(EtherAmount, 'ether')//EtherAmount=>how much ether you want to move
},function (error, result){
if(!error){
console.log(result);//transaction successful
} else{
console.log(error);//transaction failed
}
});
- 41
- 3
var abi=[//your abi array];
var contractAddress = "//your contract address";
var contract = web3.eth.contract(abi).at(contractAddress);
contract.functionName.sendTransaction(parameter_1,parameter_2,parameter_n,{
from:web3.eth.accounts[0],
gas:4000000},function (error, result){ //get callback from function which is your transaction key
if(!error){
console.log(result);
} else{
console.log(error);
}
});
you can then try to get transaction receipt by using
var receipt=web3.eth.getTransactionReceipt(trHash);
-if you get receipt as null that means your transaction is not mined, you can keep trying after some time until you get receipt values. -You can check in the receipt that all the provided gas is used or not, all gas used indicated your transaction is failed
- 763
- 1
- 11
- 31
With Etherjs utilities data can be created as follows which can be directly sent to sendTransaction function.
//ethereum provider instance creation
let ethereum = window.ethereum;
// Request account access if needed
await ethereum.enable();
let provider = new ethers.providers.Web3Provider(ethereum);
//Get method id (transfer function method id)
const METHOD_ID = "0x05555555"; //replace with actual transfer function method id
//creating encoded data
let encodedData = ethers.utils.hexConcat([
METHOD_ID,
ethers.utils.defaultAbiCoder.encode(
["address", "uint256"],
[receiverAddress, amount] //replace with receiver and amount to be transferred
),
]);
//Create raw transaction param
const param = {
from: sender, //replace with sender wallet address
to: ERC20_CONTRACT_ADDRESS, //replace with your contract address
data: encodedData
};
//Send Transaction using etherjs
const transactionHash = await provider.send('eth_sendTransaction', params)
- 45
- 6
getDatamethod.It is used to retrieve the value of data in state storage. You can read more here: http://solidity.readthedocs.io/en/develop/contracts.html#visibility-and-getters – Prashant Prabhakar Singh Oct 17 '17 at 04:09personalover RPC – Prashant Prabhakar Singh Jan 20 '18 at 06:43getData()is the function that generatesinputvariable that is being sent to evm.Call().getData()does not access the storage at State, it uses the ABI of the contract to generate the input, particulary, using abi.Pack() located in accounts/abi/abi.go . But in transaction scope , thisinputis calleddata– Nulik Jun 26 '18 at 14:48./contracts/abi.json), contractAddress);let adventurersLogParameters = [2236813];
let getData = contract.methods.adventurers_log.getData(funtion adventurersLogParameters);
It's showing syntax error at "adventurersLogParameters".
– emeraldhieu Sep 19 '21 at 17:35let data = contract.methods.adventurers_log.getData(adventurersLogParameters)should work. – Prashant Prabhakar Singh Sep 20 '21 at 12:52const contract = new web3.eth.Contract(abi, contractAddress); there's nogetData, but we can doconst call = universeContract.methods[methodName](callParameters), but I'm not sure how to sign the call and send it correctly. – YakovL May 11 '22 at 15:55