So erhalten Sie den Wert eines öffentlichen Vertragseigentums mit web3.eth

Wie erhalten Sie mit der Web3-Javascript-Bibliothek den aktuellen Wert einer öffentlichen Eigenschaft? z.B

contract MyContract {
    address public owner;
    ...
}

Hier ein Ausschnitt des Abi:

[{
  "constant": true,
  "inputs": [],
  "name": "owner",
  "outputs": [
    {
      "name": "",
      "type": "address"
    }
  ],
  "payable": false,
  "type": "function"
},
...
]

Ich habe mehrere Methoden ausprobiert, aber ohne Erfolg:

    var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
    var contract = new web3.eth.Contract([...], "0x1234...");

    // These don't work:
    var owner = contract.owner;
    console.log(owner); // "undefined"

    contract.methods.owner.call(function(error, result) {
        console.log("This doesn't get called");
    });

    contract.methods.owner(function(error, result) {
        // Displays an error to console:
        // Error: Invalid number of parameters for "owner". Got 1 expected 0!
    });

    var x = contract.methods.owner();
    console.log(x); // Displays the contract object below:

Die letzte Zeile zeigt den Vertragsgegenstand an. Hier ist ein Ausschnitt:

{ call: { [Function: bound _executeMethod] request: [Function: bound 
_executeMethod] },
  send: { [Function: bound _executeMethod] request: [Function: bound 
_executeMethod] },
  encodeABI: [Function: bound _encodeMethodABI],
  estimateGas: [Function: bound _executeMethod],
  _method:
  { constant: true,
     inputs: [],
     name: 'owner',
     outputs: [ [Object] ],
     payable: false,
     type: 'function',
     signature: '0x8da5cb5b' },
  _parent:
   Contract {
       // etc...

BEARBEITEN: Verwenden von Version 1.0.0-beta.4 (spätere Pakete werden mit Abhängigkeitslerna nicht richtig installiert). Dokumente: http://web3js.readthedocs.io/en/1.0/web3-eth-contract.html

Antworten (7)

Dieser Code ist korrekt: myContract.methods.owner().call().then(console.log);Der Fehler ist ein Fehler und wird in der nächsten Version behoben.

Ja, myContract.methods.owner().call().then(console.log); es funktioniert wie ein Zauber!
Können Sie erklären, wie der zurückgegebene Wert (von der Aufruffunktion) auf einer HTML-Seite angezeigt werden kann? Ihre Antwort protokolliert nur den Rückgabewert in der Konsole, der den Benutzern verborgen bleibt.

Gemäß der Web3-API-Dokumentation ist die Methode zum Abrufen einer Vertragsinstanz und zum Aufrufen einer Methode wie folgt:

1. Vertragsdefinition

var MyContract = web3.eth.contract(abi);

2. Holen Sie sich die Vertragsinstanz unter der Adresse

var myContractInstance = MyContract .at('0x**********');

3. Führen Sie einen Anruf aus

var owner = myContractInstance .owner.call();

Vollständiger Code:

var abi = [
    {
      "constant": true,
      "inputs": [],
      "name": "owner",
      "outputs": [
        {
          "name": "",
          "type": "address"
        }
      ],
      "payable": false,
      "type": "function"
    },
    {
      "inputs": [],
      "payable": false,
      "type": "constructor"
    }
  ];


var MyContract = web3.eth.contract(abi);

// initiate contract for an address
var myContractInstance = MyContract .at('0xa07ddaff6d8b7aabf91ac6f82bf89455eb9784f4');

// call constant function (synchronous way)
var owner = myContractInstance .owner.call();

console.log("owner="+owner);

Funktioniert gut:

Besitzer=0x13a0674c16f6a5789bff26188c63422a764d9a39

Entschuldigung, ich hätte die Version von web3 angeben sollen, die ich verwende: 1.0.0-beta.4 web3js.readthedocs.io/en/1.0/web3-eth-contract.html für einen neuen Vertrag tun Sie dies: new web3 .eth.Contract(jsonInterface[, Adresse][, Optionen])
Noch nicht angefasst. Aber laut Dokumentation sollte es so seinmyContract.methods.owner().call().then(console.log);
Ich habe auch noch nicht mit 1.0 gespielt, aber denken Sie bitte daran, dass es sich um BETA-Software handelt und zu diesem Zeitpunkt in der Produktion nicht gut getestet wurde.
myContract.methods.owner().call().then(console.log);zeigt eine Fehlermeldung an: TypeError: Cannot read property 'length' of undefinedund myContract.methods.owner.call().then(console.log);zeigt eine Fehlermeldung an: TypeError: myContract.methods.owner.call(...).then is not a functionIch nehme an, die Beta ist dafür noch nicht bereit.
Danke für die ausführliche Antwort! :) Könnten Sie hinzufügen, wie man es auf asynchrone Weise macht?

Ich habe nach dem Upgrade auf die Version 1.0.0-beta.11und dem Ändern des installierten Pakets hier eine Problemumgehung gefunden:

\node_modules\web3\packages\web3-eth-contract\src\index.js

Zeile 356 ändern von:

if(json.inputs.length !== args.length) {

zu:

if(args && json.inputs.length !== args.length) {

und änderte meinen Code oben zu:

var result = myContract.methods.owner.call().call((error, result) => {
    console.log(result);
});

Sie müssen `call() zweimal aufrufen. meh.

Ich wollte ein Problem auf Github protokollieren, habe aber hier ein ähnliches gefunden: github.com/ethereum/web3.js/issues/948
Das Problem wird in der Version behoben1.0.0-beta.12
Fehler existiert immer noch auf 1.0.0-beta.18
Der Fehler existiert auch heute noch (Version 1.0.0-beta.30 ) leider ... mkaj sagte, dass Sie call() zweimal aufrufen müssen, aber es sieht so aus, als könnten Sie es tatsächlich verwenden myContract.methods.owner().call().. für mich funktioniert es wie ein Zauber. ., die Sie tatsächlich verwenden könnenmethods.methodName(arg).call({from:fromAccount})

Keine der anderen Antworten funktioniert für mich. Das macht:

import Web3 from "web3";

const address = "0xe9e7...";
const abi = "[{...";

const web3 = new Web3(); // pass your endpoint here in case
const contract = new web3.eth.Contract(abi, address);

await contract.methods.name().call();
await contract.methods.symbol().call();
await contract.methods.decimals().call();

Dies ist web3 in Version 3.0.0-rc.5.

Das hat auch bei mir funktioniert. Ich denke, was gefehlt hat, waren die beiden Anrufe: 1. contract.methods.name()2.contract.methods.name().call()

@mkaj Wenn Sie Version 1.x verwenden, müssen Sie zunächst die Adresseigenschaften auf festlegen

var MyContract = web3.eth.contract(abi);
myContract.options.address = '0xa07ddaff6d8b7aabf91ac6f82bf89455eb9784f4';

var output = myContract.methods.owner.call((error, result) => {
    console.log(result); 
});

Überprüfen Sie Ihre JSON ABI, z. B.:

{
    "inputs": [],
    "name": "name",
    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }
    ],
    "name": "ownerOf",
    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
    "stateMutability": "view",
    "type": "function"
  },

Wenn der Typ ist function, sollten Sie ihn aufrufen können. ich benutzeweb3@1.6.1

contractInstance.methods.name().call();
contractInstance.methods.balanceOf(address).call();

Die Initialisierung Ihres Vertrags dauert einige Zeit. Sie können die Methode setTimeout() verwenden

setTimeout(function(){ 
   var owner = myContract.methods.owner.call()
   console.log('owner = ', owner)
}, 3000);