Implementé un contrato inteligente en la red de ganache usando trufa de la cuenta 1. El código del contrato inteligente es el siguiente.
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());
}
}
Ahora creé un archivo app.js como se muestra a continuación, donde intento llamar a una función de ese contrato inteligente usando 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();
Pero esto da un error
TypeError: no se puede leer la propiedad 'addEntry' de undefined
Seguí muchos tutoriales y sugirieron lo mismo, pero no entiendo el motivo del fracaso en mi caso.
¡Gracias!
Está llamando a un método en un objeto que no existe.
Modifica tu código para
PublishServiceContract.addEntry("LC1",web3.eth.defaultAccount,"SP1","ubicación:dentro;lectura:grado","scattr","ngac");
Ahora lo probé de esta manera, siguiendo el tutorial de la tienda de mascotas de trufas
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();
entonces me sale el siguiente error.
TypeError: PublishServiceContract.deployed no es una función
¿Alguna idea sobre el motivo de este error?
gracias de antemano
Si PublishService
es su contrato, no puede llamar a funciones así. Debe instanciar su contrato, y es una función asíncrona, por lo que tendrá que esperar la devolución de la llamada o la variable del contrato será undefined
.
Supongo que está tratando de llegar a un contrato por dirección. Hay dos pasos para esto.
inicia el contrato, como en el tutorial de trufas. (Eso no debe hacerse en initWeb3()
, debe tener una initContract()
función.
Cree una instancia del contrato. En el tutorial usan App.contracts.myContract.deployed()
pero puedes usar App.contracts.myContract.at("0x6c68d153b9709283e3900e944f1c6677273987c5")
.
En el tutorial usan un init como este:
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();
},
Deberías hacer lo mismo con tu contrato. Pregúntame si hay algo mal.
El tuyo debería verse así:
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();
},
Y no olvides llamar truffle compile
y truffle migrate
en tu consola.
var contract = require('./PublishService_abi.js');
y ` var PublishServiceContractAddress = "0x6c68d153b9709283e3900e944f1c6677273987c5"; PublishServiceContract = new web3.eth.Contract(contrato,PublishServiceContractAddress); `, Traté de hacer una llamada asíncrona como en la respuesta a continuación, pero aparece un error que dice que la implementación no es una función.initContact
función para presentar su contrato y reemplace sus llamadas de función por su función.App.contracts.Adoption.deployed()
, pero pueden hacerlo porque el contrato se ha instanciado correctamente a través de JSON abi.
K Kolluru
TypeError: PublishServiceContract.addEntry is not a function