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!
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");
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 PublishService
das 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 compile
Und vergessen Sie nicht , und truffle migrate
in Ihrer Konsole anzurufen .
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.initContact
Funktion, um Ihren Vertrag hervorzuheben, und ersetzen Sie deren Funktionsaufrufe durch Ihre Funktion.App.contracts.Adoption.deployed()
, aber sie können das tun, weil der Vertrag über JSON abi ordnungsgemäß instanziiert wurde.
K Kolluru
TypeError: PublishServiceContract.addEntry is not a function