Web3js
從 app.js 呼叫智能合約函式
我使用來自 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 不是函式
關於這個錯誤的原因的任何想法?
提前致謝