Esta puede ser una pregunta muy básica, no sé por qué, pero no puedo encontrar la solución correcta a cómo puedo llamar al método de mi contrato usando sendTransaction
. Tengo una transfer(address, uint256)
función a la que quiero llamar usando sendTransaction
y callTransaction
. Tengo mi contrato compilado y tengo su abi y dirección. Ahora, ¿cómo puedo llamar a diferentes métodos del contrato usando sendTransaction
?
Estaba leyendo la pregunta Sintaxis para llamar a los métodos de cambio de estado del contrato , y obtuve explicaciones para que la función tenga un solo parámetro, pero ¿qué pasa si tiene más de un parámetro de diferentes tipos, como aquí transfer()
la función acepta 2 parámetros?
Publicando la solución a mi propia pregunta para cualquiera que la necesite. Para llamar a una función de contrato desde 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 });
Nota : puede agregar otros campos en sendTransaction
valores similares, etcétera, lo he omitido por simplicidad para los usuarios nuevos.
A todos los usuarios que enfrentan desafíos con la firma de datos usando una clave privada. El pseudocódigo para firmar y enviar una transacción a contratar usando clave privada:
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})
})
})
}
Has probado:
// En JavaScript myContract.transfer(otherAddress, aNumber, { from: myAccount }); // O myContract.transfer.sendTransaction(otherAddress, aNumber, { from: myAccount }); // O myContract.transfer.call(otherAddress, aNumber, { from: myAccount });
Ver toda la documentación .
Mejorando la respuesta de @Prashant Prabhakar Singh:
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
}
});
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);
}
});
a continuación, puede intentar obtener el recibo de la transacción utilizando
var receipt=web3.eth.getTransactionReceipt(trHash);
-Si obtiene el recibo como nulo, eso significa que su transacción no está minada, puede seguir intentándolo después de un tiempo hasta que obtenga los valores del recibo. -Puede verificar en el recibo que todo el gas provisto se usó o no, todo el gas usado indicó que su transacción falló
Con las utilidades de Etherjs, los datos se pueden crear de la siguiente manera, que se pueden enviar directamente a la función sendTransaction.
//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)
smatthewenglish
Nulik
Prashant Prabhakar Singh
getData
el método. Se utiliza para recuperar el valor de los datos en el almacenamiento de estado. Puede leer más aquí: solidity.readthedocs.io/en/develop/…RagHaven
Prashant Prabhakar Singh
personal
sobre RPCNulik
getData()
es la función que genera lainput
variable que se envía a evm.Call().getData()
no accede al almacenamiento en State, usa la ABI del contrato para generar la entrada, en particular, usando abi.Pack() ubicado en accounts/abi/abi.go . Pero en el ámbito de la transacción, estoinput
se llamadata
kitsune
Prashant Prabhakar Singh
SIGITO
Prashant Prabhakar Singh
esmeraldahieu
./contracts/abi.json
), contractAddress); let aventurerosLogParameters = [2236813]; let getData = contract.methods.adventurers_log.getData(función adventurersLogParameters); Muestra un error de sintaxis en "adventurersLogParameters".Prashant Prabhakar Singh
let data = contract.methods.adventurers_log.getData(adventurersLogParameters)
Deberia trabajar.YakovL
const contract = new web3.eth.Contract(abi, contractAddress)
; no haygetData
, pero podemos hacerloconst call = universeContract.methods[methodName](callParameters)
, pero no estoy seguro de cómo firmar la llamada y enviarla correctamente.