Wie rufe ich eine Zustandsänderungsfunktion mit web3.js (Browser) und Remote-Knoten auf?

Soliditätsvertrag:

contract MyContract {
    bytes32 public product;
    uint public amount;

    function setOrder(bytes32 _product, uint _reorderAmount,) public returns (bool success);   
}

Javascript web3js (ohne node.js):

<script src="./web3.min.js"></script>
<script>
web3 = new Web3(new Web3.providers.HttpProvider("https://ropsten.infura.io/key"));
web3.eth.defaultAccount = "0x...address of my account...";
var myContract = web3.eth.contract([...abi...]);
var contractInstance = myContract.at('0x...contract address...');
contractInstance.setOrder(web3.toHex('ProductName'),3000);
</script>

Dies funktioniert, wenn ich ganache-cli laufen habe, aber nicht auf einem Testnet (z. B. Ropsten). In einem Testnetz kann ich nur Getter-Funktionen abrufen, aber wie rufe ich eine Setter-Funktion auf? Was fehlt mir hier?

was ist das siloContract? und welche version von web3 verwendest du?
Dies ist aus dem ursprünglichen Vertrag, geändert in MyContract. Ich verwende 0.20.6
Ihr JS-Code sieht gut aus, aber Ihre Vertragsmethode hat keinen Körper? Sie benötigen Ether in Ihrem Konto ( coinbase), um Transaktionen auf Ropsten aufrufen zu können.

Antworten (3)

Transaktionen müssen mit dem privaten Schlüssel des sendenden Kontos signiert werden.

Sie verwenden Infura als Ihren Web3-Anbieter und bitten ihn, eine Transaktion für Sie zu senden. Das kann es nicht, weil es den privaten Schlüssel für Ihr Konto nicht kennt.

Sie müssen entweder selbst Code schreiben, um die Transaktion zu signieren, oder (der typischere Ansatz) einen Web3-Anbieter wie MetaMask im Browser verwenden. MetaMask hält die privaten Schlüssel des Benutzers und signiert Transaktionen in seinem Namen (nach Aufforderung zur Genehmigung).

Danke für die Antwort. Ich möchte es unterschreiben, aber ich weiß nicht wie. Haben Sie einen Link mit Informationen oder können Sie Ihrer Antwort bitte weitere Details hinzufügen?

Laut dem Dokument müssen Sie die contractInstance.setOrder(web3.toHex('ProductName'),3000); Methode in ändern

Senden Sie eine Transaktion: (Ihr Fall)

contractInstance.setOrder.sendTransaction(web3.toHex('ProductName'),3000, { from: ethaddress }, function(err, result){ ... })

Wenn Sie nur eine Funktion aufrufen möchten, die den Status nicht aktualisiert (und nichts kostet):

contractInstance.product.call(param1, , function(err, result){ ... }) 
Danke schön. Aber mein web3 (v0.20.6) zeigt mir nicht an, methodsnachdem ich die Instanz in eine Browserkonsole geschrieben habe. Muss ich nicht auch irgendwie einen Schlüssel angeben, um eine Statusänderungstransaktion zu signieren? from: ethaddresskann nicht genug sein oder?
Oh, Entschuldigung, ich dachte, Sie verwenden web3 > 1, ich habe meinen Kommentar entsprechend Ihrer Version aktualisiert
Danke, aber wo unterschreibe ich die Transaktion? Ich verwende keine Metamaske, nur Infura und ich muss die Daten irgendwie signieren

Sie müssen Web3js verwenden , um Ihre Transaktion auf der Clientseite zu signieren, bevor Sie sie an Infura senden:

web3.eth.sendSignedTransaction(
  web3.eth.accounts.signTransaction(
    {
      to: contractInstance.address,
      data: contractInstance.methods.setOrder.encodeABI(
        web3.toHex('ProductName'),3000),
      gas: 100000
    }));

Weitere Details finden Sie in der Dokumentation