Aufruf von Smart-Contract-Funktionen aus app.js

Ich habe einen intelligenten Vertrag für das Ganache-Netzwerk mit Trüffel von Konto1 bereitgestellt. Der Code des Smart Contracts lautet wie folgt.

pragma solidity ^0.4.0;

import "./strings.sol";
import "./safemath.sol";
contract PublishService {

    using strings for *;
    using SafeMath for uint;
    struct ServiceListStruct {
        string cloudID;
        address gatewayID;
        string serviceProducerID;
        mapping (string => string) serviceProducerMetadata;
        string serviceConsumerMetaAttr;
        string accessControlModel;
    }

    ServiceListStruct[] public BCServiceList;

    uint BCServiceListIndex;

    function PublishService() {
        BCServiceListIndex = 0;
    }

    modifier onlyServiceProducerOwner(address _gatewayID) {
        require(msg.sender == _gatewayID);
        _;
    }

    ServiceListStruct sls;
    uint public maxParams = 0;


    function addEntry(string _cloudID, address _gatewayID, string _serviceProducerID, string _serviceProducerMetadata, string _serviceConsumerMetaAttr, string _accessControlModel) public onlyServiceProducerOwner(_gatewayID) returns (uint) {
        sls.cloudID = _cloudID;
        sls.gatewayID = _gatewayID;
        sls.serviceProducerID = _serviceProducerID;
        sls.serviceConsumerMetaAttr = _serviceConsumerMetaAttr;
        sls.accessControlModel = _accessControlModel;
        BCServiceList.push(sls);
        //
        string memory s1;
        string memory s2 = _serviceProducerMetadata;
        string memory s3;
        bytes memory s2bytes = bytes(_serviceProducerMetadata);
        uint paramCount = 0;
        while(s2bytes.length != 0) {
            (s1,s2) = splitString(s2,";");
            (s1,s3) = splitString(s1,":");
            BCServiceList[BCServiceListIndex].serviceProducerMetadata[s1] = s3;
            paramCount = paramCount.add(1);
            s2bytes = bytes(s2);
        }
        if(maxParams < paramCount) {
            maxParams = paramCount;
        }
        BCServiceListIndex = BCServiceListIndex.add(1);
        return 1;
    }

    function deleteEntry(string _cloudID, address _gatewayID, string _serviceProducerID) public onlyServiceProducerOwner(_gatewayID) returns (uint) {
        require(msg.sender == _gatewayID);
        int pos = -1;
        for(uint index = 0; index < BCServiceList.length; index++) {
            if(compareStringsbyBytes(_cloudID, BCServiceList[index].cloudID)) {
                if(_gatewayID == BCServiceList[index].gatewayID) {
                    if(compareStringsbyBytes(_serviceProducerID, BCServiceList[index].serviceProducerID)) {
                        pos = int(index);
                    }
                }
            }
        }
        if(pos > -1) {
             BCServiceList[index] = BCServiceList[BCServiceList.length -1];
             delete BCServiceList[BCServiceList.length - 1];
             BCServiceList.length--;
             return 1;
        }
        else
            return 0;
    }

    function compareStringsbyBytes(string s1, string s2) internal pure returns(bool) {
        bytes memory s1bytes = bytes(s1);
        bytes memory s2bytes = bytes(s2);
        if(s1bytes.length!=s2bytes.length) {
            return false;
        }
        else {
            for(uint i = 0; i < s1bytes.length; i++) {
                if(s1bytes[i] != s2bytes[i])
                return false;
            }
            return true;
        }
    }

    function splitString(string _s, string _seperator) internal returns(string, string) {
        var s_slice = _s.toSlice();
        var seperator_slice = _seperator.toSlice();
        string memory result = "";
        var result_slice = result.toSlice();
        result_slice = s_slice.split(seperator_slice);
        return (result_slice.toString(), s_slice.toString());
    }
}

Jetzt habe ich eine app.js-Datei wie unten erstellt, in der ich versuche, eine Funktion dieses intelligenten Vertrags mit PublishService.addEntry(...) aufzurufen.

var Web3 = require('web3');
var web3Provider = null;
var PublishService;
var contract = require('./PublishService_abi.js');

function init() {
  //initializing web3 to access blockchain
  initweb3();
}

function initweb3() {
  //To make sure not to overwrite the already set provider when in mist, check first if the web3 is available
  if (typeof web3 !== 'undefined') {
    web3 = new Web3(web3.currentProvider);
  } else {
    // create an instance of web3 using the HTTP provider
    web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:7545"));
  }
  web3.eth.defaultAccount = web3.eth.accounts[1];
  var PublishServiceContractAddress = "0x6c68d153b9709283e3900e944f1c6677273987c5";
  var PublishServiceContract = new web3.eth.Contract(contract,PublishServiceContractAddress ); 
  PublishService.addEntry("LC1", web3.eth.defaultAccount, "SP1", "location:inside;reading:degree", "scattr", "ngac");
}

init();

Aber das gibt einen Fehler

TypeError: Eigenschaft 'addEntry' von undefined kann nicht gelesen werden

Ich habe viele Tutorials befolgt und sie haben dasselbe vorgeschlagen, aber ich verstehe den Grund für das Scheitern in meinem Fall nicht.

Danke!

Antworten (3)

Sie rufen eine Methode für ein Objekt auf, das nicht existiert.

Ändern Sie Ihren Code in

PublishServiceContract.addEntry("LC1",web3.eth.defaultAccount,"SP1","location:inside;reading:degree","scattr","ngac");
Mein Fehler. aber jetzt bekomme ich diesen FehlerTypeError: PublishServiceContract.addEntry is not a function

Jetzt habe ich es auf diese Weise versucht, indem ich dem Trüffel-Petshop-Tutorial gefolgt bin

var Web3 = require('web3');
var web3Provider = null;
var contract = require('./PublishService_abi.js');
var PublishServiceContract;

function init() {
  //initializing web3 to access blockchain
  initweb3();
}

function initweb3() {
  //To make sure not to overwrite the already set provider when in mist, check first if the web3 is available
  if (typeof web3 !== 'undefined') {
    web3 = new Web3(web3.currentProvider);
  } else {
    // create an instance of web3 using the HTTP provider
    web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:7545"));
  }
  web3.eth.defaultAccount = web3.eth.accounts[1];
  var PublishServiceContractAddress = "0x6c68d153b9709283e3900e944f1c6677273987c5";
 PublishServiceContract = new web3.eth.Contract(contract,PublishServiceContractAddress); 
  addServiceProducer("LC1","SP1","location:inside;reading:degree","scattr","ngac");
}

function addServiceProducer(s1,s2,s3,s4,s5) {
    var psinstance;
    PublishServiceContract.deployed().then(function(instance) {
        psInstance = instance;
        psinstance.addEntry(s1,web3.eth.defaultAccount,s2,s3,s4,s5);
    }).then(function(print) {
        console.log("sp details added successfully")
    }).catch(function(err) {
        console.log(err.message);
    });
}

init();

dann bekomme ich den folgenden Fehler.

TypeError: PublishServiceContract.deployed ist keine Funktion

Irgendeine Idee über den Grund für diesen Fehler?

Vielen Dank im Voraus

Wenn PublishServicedas Ihr Vertrag ist, können Sie Funktionen nicht einfach so aufrufen. Sie müssen Ihren Vertrag instanziieren, und es handelt sich um eine asynchrone Funktion, sodass Sie auf den Rückruf warten müssen, oder Ihre Vertragsvariable lautet undefined.

Ich nehme an, Sie versuchen, einen Vertrag per Adresse zu erreichen. Dazu gibt es zwei Schritte.

  • init den Vertrag, wie im Trüffel-Tutorial. (Das sollte nicht in gemacht werden initWeb3(), Sie sollten eine initContract()Funktion haben.

  • Erstellen Sie eine Instanz des Vertrags. Im Tutorial verwenden sie, App.contracts.myContract.deployed()aber Sie können App.contracts.myContract.at("0x6c68d153b9709283e3900e944f1c6677273987c5").

Im Tutorial verwenden sie eine Init wie diese:

    initContract: function() {
        $.getJSON('Adoption.json', function(data) {
          // Get the necessary contract artifact file and instantiate it with truffle-contract
          var AdoptionArtifact = data;
          App.contracts.Adoption = TruffleContract(AdoptionArtifact);

          // Set the provider for our contract
          App.contracts.Adoption.setProvider(App.web3Provider);

          // Use our contract to retrieve and mark the adopted pets
          return App.markAdopted();
        });

        return App.bindEvents();
      },

Dasselbe sollten Sie für Ihren Vertrag tun. Frag mich, ob etwas nicht stimmt.

Deine sollte so aussehen:

  initContract: function() {
    $.getJSON('PublishService.json', function(data) {
      var PublishServiceArtifact = data;
      App.contracts.PublishService = TruffleContract(PublishServiceArtifact);

      App.contracts.PublishService.setProvider(App.web3Provider);

      // you don't need to return anything specific so that should work
      return true
    });

    return App.bindEvents();
  },

truffle compileUnd vergessen Sie nicht , und truffle migratein Ihrer Konsole anzurufen .

Hallo, die Schritte, die Sie unten gezeigt haben, bestehen im Wesentlichen darin, die JSON-Datei zu lesen und den Anbieter festzulegen, was ich im folgenden Codeabschnitt getan habe. var contract = require('./PublishService_abi.js');und ` var PublishServiceContractAddress = "0x6c68d153b9709283e3900e944f1c6677273987c5"; PublishServiceContract = new web3.eth.Contract(Vertrag,PublishServiceContractAddress); `, ich habe versucht, einen asynchronen Aufruf wie in der folgenden Antwort durchzuführen, aber ich erhalte die Fehlermeldung, dass Deployed keine Funktion ist.
@KKolluru Ich verstehe es nicht, warum beginnst du nicht mit dem Zoohandlungs-Tutorial und baust von hier aus? Ersetzen Sie die initContactFunktion, um Ihren Vertrag hervorzuheben, und ersetzen Sie deren Funktionsaufrufe durch Ihre Funktion.
@KKolluru Sie müssen Ihre Vertragserstellung auch asynchron gestalten. Im Tutorial verwenden sie App.contracts.Adoption.deployed(), aber sie können das tun, weil der Vertrag über JSON abi ordnungsgemäß instanziiert wurde.