Web3js

從 app.js 呼叫智能合約函式

  • February 12, 2022

我使用來自 account1 的 truffle 將智能合約部署到 ganache 網路。智能合約程式碼如下。

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

現在我創建了一個 app.js 文件,如下所示,我試圖在其中使用 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();

但這給出了一個錯誤

TypeError:無法讀取未定義的屬性“addEntry”

我遵循了許多教程,他們提出了相同的建議,但我不明白我的案例失敗的原因。

謝謝!

您正在對不存在的對象呼叫方法。

將您的程式碼修改為

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

現在我按照松露寵物店教程嘗試了這種方式

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

然後我收到以下錯誤。

TypeError:PublishServiceContract.deployed 不是函式

關於這個錯誤的原因的任何想法?

提前致謝

引用自:https://ethereum.stackexchange.com/questions/46054