So rufen Sie die Funktion meines Vertrags mit sendTransaction auf

Dies kann eine sehr grundlegende Frage sein, ich weiß nicht warum, aber ich kann keine richtige Lösung dafür finden, wie ich die Methode meines Vertrags mit aufrufen kann sendTransaction. Ich habe eine transfer(address, uint256)Funktion, die ich mit sendTransactionund aufrufen möchte callTransaction. Ich habe meinen Vertrag erstellt und ich habe seinen Abi und seine Adresse. Wie kann ich nun verschiedene Methoden des Vertrags mit aufrufen sendTransaction?
Ich habe die Frage Syntax zum Aufrufen von Methoden zum Ändern des Vertragsstatus gelesen und Erklärungen für die Funktion mit einem einzelnen Parameter erhalten, aber was ist, wenn sie mehr als einen Parameter verschiedener Typen hat, wie hier transfer()die Funktion 2 Parameter akzeptiert.

Antworten (5)

Posting-Lösung zu meiner eigenen Frage für alle, die sie brauchen. So rufen Sie eine Vertragsfunktion auf von 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 });

Hinweis : Sie können andere Felder sendTransactionwie Wert usw. hinzufügen. Ich habe dies der Einfachheit halber für neue Benutzer übersprungen.


An alle Benutzer, die mit dem Signieren von Daten mit dem privaten Schlüssel konfrontiert sind. Der Pseudocode zum Signieren und Senden einer Transaktion zum Vertrag mit dem privaten Schlüssel:

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})
      })
  })
}
das ist eine hervorragende Antwort! hat für mich funktioniert - denken Sie daran, die Adressen in Anführungszeichen zu setzen.
Es ist nicht klar, was die Methode getData() tut. Ist es eine eingebaute Methode oder muss sie von dem Entwickler erstellt werden, der den Vertrag geschrieben hat?
Sie müssen die Methode nicht implementieren getData. Sie wird verwendet, um den Wert der Daten im Zustandsspeicher abzurufen. Hier können Sie mehr lesen: solidity.readthedocs.io/en/develop/…
Müssen Sie die IP des Ethereum-Knotens angeben, an den Sie diese Transaktion senden?
Ja, das musst du angeben. Das ist, während die Verbindung zu web3 hergestellt wird. Denken Sie daran, nicht personalüber RPC verfügbar zu machen
@PrashantPrabhakarSingh getData()ist die Funktion, die eine inputVariable generiert, die an evm.Call() gesendet wird. getData()greift nicht auf den Speicher bei State zu, sondern verwendet die ABI des Vertrags, um die Eingabe zu generieren, insbesondere unter Verwendung von abi.Pack() in accounts/abi/abi.go . Aber im Transaktionsbereich wird dies inputaufgerufendata
Können Sie bitte eine ähnliche Lösung posten, aber Infura verwenden und die Ausgabe der Vertragsfunktion zurückgeben?
@kitsune Details zur Verwendung derselben Lösung mit Infura hinzugefügt. Die Ausgabe hängt von der Art des Ereignisses ab, das Sie auslösen möchten, z. B. transacationHash, Bestätigung, Quittung, Fehler usw. Siehe Beispiel hier
@PrashantPrabhakarSingh danke für deine Erklärung, mir ist nicht klar, woher die Daten kommen, ist es von den extraData?
Jawohl. Lassen Sie mich die Antwort auch aktualisieren :)
let contract = new web3.eth.Contract(require( ./contracts/abi.json), contractAddress); Let AbenteurerLogParameters = [2236813]; let getData = contract.methods.adventurers_log.getData (Funktion adventurersLogParameters); Es zeigt einen Syntaxfehler bei "adventurersLogParameters".
@emeraldhieu Sie müssen das Schlüsselwort "Funktion" nicht schreiben, bevor Sie Argumente übergeben. let data = contract.methods.adventurers_log.getData(adventurersLogParameters)sollte arbeiten.
Könnten Sie Ihre Antwort für web3 1.x aktualisieren? Es hat viele Breaking Changes. Wie emeraldhieu erwähnt, wird auf einen Vertrag zugegriffen über const contract = new web3.eth.Contract(abi, contractAddress); Es gibt kein getData, aber wir können tun const call = universeContract.methods[methodName](callParameters), aber ich bin mir nicht sicher, wie ich den Anruf signieren und korrekt senden soll.

Hast du es versucht:

// In Javascript
myContract.transfer(otherAddress, aNumber, { from: myAccount });
// Oder
myContract.transfer.sendTransaction(otherAddress, aNumber, { from: myAccount });
// Oder
myContract.transfer.call(otherAddress, aNumber, { from: myAccount });

Sehen Sie sich die gesamte Dokumentation an .

korrekt für web3.js, aber geben Sie bitte Verweise auf die Dokumentation an.

Verbesserung der Antwort von @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);
                }
        });

Sie können dann versuchen, eine Transaktionsquittung zu erhalten, indem Sie verwenden

var receipt=web3.eth.getTransactionReceipt(trHash);

- Wenn Sie eine Quittung als null erhalten, bedeutet dies, dass Ihre Transaktion nicht abgebaut wurde. Sie können es nach einiger Zeit weiter versuchen, bis Sie Quittungswerte erhalten. - Sie können in der Quittung überprüfen, ob das gesamte bereitgestellte Gas verbraucht ist oder nicht. Das gesamte verbrauchte Gas zeigt an, dass Ihre Transaktion fehlgeschlagen ist

Gibt es einen aktualisierten Code? Er funktioniert nicht auf dem neuesten Web3

Mit den Dienstprogrammen von Etherj können Daten wie folgt erstellt werden, die direkt an die sendTransaction-Funktion gesendet werden können.

//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)