ethers.js (node.js) Ruft Solidity-Funktion auf, die zahlbar ist

Ich verstehe, dass Sie Ethereum an einen Smart Contract senden können, obwohl Sie, wenn Sie dies tun, sendTransactionanscheinend keine Funktion für den Smart Contract angeben, wenn Sie dies tun. Ich verstehe nicht ganz, wie das nützlich sein soll. Was ich jedoch nicht herausfinden kann, ist, Ethereum an eine Funktion zu senden, die als zahlbar festgelegt ist. Ich verwende ethers.js und kann einen Vertrag erstellen und Funktionen aufrufen, die sichtbar (schreibgeschützt) sind, kein Problem, aber ich kann nicht herausfinden, wie Ethereum mit der Transaktion an eine bestimmte Funktion gesendet wird

export const testContract = async (address, abi) => {
  const wei = Utils.parseEther("0.1")
  const url = "http://localhost:8545"
  const provider = new Providers.JsonRpcProvider(url)
    // Load the wallet to deploy the contract with
  const privateKey =
    "0x123"
  const wallet = new Wallet(privateKey, provider)

  var contract = new Contract(address, abi, wallet)

  const price = await contract.retrievePrice()
  console.log("price " + price) //logs the price set in the constructor when the contract was made (WORKS)
  const testAddress = await contract.isUser(
    "0x456"
  )
  console.log("testAddress ", testAddress) //checks if the given address is a user on the contract (WORKS)

  const gasPrice = await provider.getGasPrice()
  console.log("gas price: ", gasPrice.toString()) //returns the price of gas from the network (WORKS)
  try {
    const addToUsers = await contract.requestAccess({ //call function to request access, from the current wallet (REVERTS)
      value: wei
    })
    console.log("result of sending transaction ", addToUsers)
  } catch (error) {
    console.log("error.... ", error) //fires as the contract reverted the payment
  }
}

Irgendwelche Hilfe, warum der Anruf contract.requestAccessauf mich zurückfällt? Ich kann nicht ganz herausfinden, wie man eine bestimmte Funktion aufruft und Ether sendet. Danke!

Antwort auf Kommentar

Ok richtig, also sieht die Funktion im Soliditätskontrakt so aus:

  function requestAccess() payable {
    require(msg.value == price, "Incorrect sum sent to contract");
    _addUser(msg.sender);
  }

Ich habe das Erfordernis auskommentiert, um das zu versuchen, aber es wird immer noch zurückgesetzt. _addUser stammt von einem Vertrag, von dem mine erbt, und sieht so aus

  function _addUser(address account) internal {
    users.add(account);
    emit UserAdded(account);
  }

usersist Roles.Role private users;und sitzt im Muttervertrag

contract Users {
  using Roles for Roles.Role;

die aus openzeppelin "openzeppelin-solidity/contracts/access/Roles.sol" importiert

Da der EVM-Code zurückgesetzt wird, bedeutet dies, dass Sie mit dem Vertrag interagieren können und das Problem teilweise auf den Vertragscode zurückzuführen ist. Können Sie uns den Code der Funktion requestAccess mitteilen?
Hallo, danke für die Antwort, ich habe die Frage bearbeitet, um deine zu beantworten!
Nach dem Testen habe ich dem Vertrag eine anonyme Funktion hinzugefügt und versucht, 0,1 Ether von Metamask zu senden (dasselbe Konto wie das, das der Code verwendet), und es hat gut funktioniert. Es hat also etwas mit meiner Ether-Syntax zu tun ...
Könnten Sie versuchen, auch die users.add(account) zu kommentieren und nur das Emit-Ereignis beizubehalten? Auf diese Weise wissen wir sicher, dass das Problem nicht mit Solidity, sondern mit ethers.js zusammenhängt
Richtig, Ihr impliziter Hinweis, dass es der Soliditätscode war, hat mich dazu gebracht, weiter zu suchen. Ich kann mir eigentlich nicht sicher sein, was es gerade behoben hat, aber die Transaktion wird gerade durchgeführt. Ich weiß nicht warum. Es war wahrscheinlich das Ergebnis der Änderung sowohl des Solidity- als auch des Ether-Codes, seit ich die Frage gepostet habe. Wenn ich herausfinde, warum ich dich nicht hängen lasse! DANKE

Antworten (3)

Sie werden vielleicht in den Kommentaren bemerken, dass ich nicht herausfinden konnte, was bei mir nicht funktioniert hat, aber ich bin kein Fan von „es funktioniert, danke“-Antworten, die anderen nicht helfen. Also habe ich ein funktionierendes Beispiel für alle, die danach suchen, auf Gists gestellt. Sie müssen nur einige Änderungen vornehmen, die auf Ihre Situation zugeschnitten sind, sollten aber relativ einfach sein. https://gist.github.com/amlwwalker/89bc2c5a2b631527bb7def922b4c8306

Zitat von https://github.com/ethers-io/ethers.js/issues/563

let overrides = {
    // To convert Ether to Wei:
    value: ethers.utils.parseEther("1.0")     // ether in this case MUST be a string

    // Or you can use Wei directly if you have that:
    // value: someBigNumber
    // value: 1234   // Note that using JavaScript numbers requires they are less than Number.MAX_SAFE_INTEGER
    // value: "1234567890"
    // value: "0x1234"

    // Or, promises are also supported:
    // value: provider.getBalance(addr)
};

// Pass in the overrides as the 3rd parameter to your 2-parameter function:
let tx = await exchangeContract.ethToTokenSwapOutput(tokens_bought, deadline, overrides);

Ich habe den Code nicht ausprobiert, aber immer wenn Sie Ether zusammen mit einer Methode senden möchten, müssen Sie ihn "überschreiben".

Const overrides = {
      value: ethers.utils.parseEther("1.0"), //sending one ether  
      gasLimit: 30000 //optional

}

//call your payable method using and use the override as a parameter
await contract.requestAccess( overrides )

In das Overrides-Objekt können Sie verschiedene Dinge einfügen, z. B. gasLimit

overrides.from – der msg.sender (oder CALLER), der während der Ausführung des Codes verwendet werden soll

overrides.value – der msg.value (oder CALLVALUE), der während der Ausführung des Codes verwendet werden soll

overrides.gasPrice – der pro Gas zu zahlende Preis (theoretisch); Da es keine Transaktion gibt, wird keine Gebühr erhoben, aber die EVM benötigt immer noch einen Wert, der an tx.gasprice (oder GASPRICE) gemeldet werden muss; Die meisten Entwickler werden dies nicht benötigen

overrides.gasLimit – die Gasmenge (theoretisch), die ein Knoten während der Ausführung des Codes verwenden darf; Da es keine Transaktion gibt, wird keine Gebühr erhoben, aber das EVM verarbeitet weiterhin die Gaszählung, sodass Aufrufe wie Gasleft (oder GAS) aussagekräftige Werte melden

overrides.blockTag – ein Block-Tag zum Simulieren der Ausführung, das für hypothetische historische Analysen verwendet werden kann; Beachten Sie, dass viele Backends dies nicht unterstützen oder kostenpflichtige Pläne für den Zugriff erfordern, da die Speicher- und Verarbeitungsanforderungen der Knotendatenbank viel höher sind