[Ethereum] calling smart contract functions from app.js

dappsnodejsweb3js

I deployed a smart contract to ganache network using truffle from account1. The code of smart contract is as follows.

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());
    }
}

Now i created an app.js file as below where I am trying to call a function of that smart contract using PublishService.addEntry(…).

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();

But this gives an error

TypeError: Cannot read property 'addEntry' of undefined

I followed many tutorials and they suggested the same, but I don't understand the reason for failure in my case.

Thanks!

Best Answer

You're calling a method on an object that does not exist.

Modify your code to

PublishServiceContract.addEntry("LC1",web3.eth.defaultAccount,"SP1","location:inside;reading:degree","scattr","ngac");