0

I'm still somewhat new to web development and solidity, so do correct any of my misunderstandings. I've been working with web3 on the front end, but now I'm trying to set up a server side web3 integration using NodeJS. Web3 seems to be properly connected to my local Ganache test node and afaik the state modifying methods are working properly, but no value is received whenever I try to fetch a value from a contract method marked 'view'.

Keep in mind that my Truffle JS unit tests prove that the contract code successfully deploys, changes state and fetches data. Unfortunately, I can't seem to make truffle-connect work in my NodeJS env (some versioning problem with web3 I think), so I can't simply copy paste the unit test code. I'm forced to forego working with truffle-connect and use the ff guide: web3.eth.Contract

Code:

Solidity Contract methods being called:

contract NFT is ERC721 {
    ...
    function createEntity(address _providerOwner, address _recipient, 
        uint256 _tokenId, string proof, uint64 tokenPoints, uint64 
        soldFor, uint64 soldAt) public {
        require(!exists(_tokenId));

        _mint(_providerOwner, _tokenId);

        ownerProviders[_tokenId] = _providerOwner;
        recipients[_tokenId] = _recipient;

        _setTokenURI(_tokenId, proof);
        setTokenPoints(_tokenId, tokenPoints);
        setSellPrice(_tokenId, soldFor);
        setSellDate(_tokenId, soldAt);
    }

    function getEntityUri(uint256 _tokenId) external view returns 
      (string) {
        require(exists(_tokenId));
        return tokenURIs[_tokenId];
    }
    ...
}

Successful Truffle Unit Test:

it("createEntity method test", function () {
    return entityContract.deployed().then(function(instance) {
        instance.createEntity(providerOwnerAddress, recipientAddress, tokenId, tokenUri, tokenPoints, soldFor, soldAt);
        return instance;
    }).then(function(instanceRes) {
        console.log("   createEntity called");
        return instanceRes.getTokenUri(tokenUri);
    }).then(function(uri) {
        //uri == tokenUri == "proof" (always successful)
        assert.equal(uri, tokenUri, "tokenUri result was not the same: " + uri);
    });
})

NodeJS backend web3 setup + contract method calls:

var Web3 = require('web3');
var web3 = new Web3('http://localhost:7545’);

var abi = [{…}]

web3.eth.getAccounts((error, accounts) => {
    if(error){
        // no errors here
        console.log("getAccounts error: ", error);
    } else {
        var entityContract = new web3.eth.Contract(abi, accounts[0], {
            from: accounts[0],
            gasPrice: '20000000000', 
        });

        var contractInstance;
        var contractAddress;

        entityContract.deploy({
            data: '0x12345',
            arguments: [“SomeObject”, “OBJ”]
        })
        .send({
            from: accounts[0],
            gas: 1500000,
            gasPrice: '30000000000000'
        }, function(error, transactionHash){

            // everything seems fine so far
            console.log("deploy: txHash: ", transactionHash)
            console.log("deploy: error: ", error)

        })
        .then(function(newContractInstance){

            contractInstance = newContractInstance;
            contractAddress = newContractInstance.options.address

            //always generates a new contract creation transaction on ganache - works afaik
            return contractInstance.methods.createEntity(providerOwnerAddress, recipientAddress, tokenId, tokenUri, tokenPoints, soldFor, soldAt)
            .send({from: accounts[0]})

        }).then(function(result){

            return contractInstance.methods.getTokenUri(tokenId)
                .call({from:accounts[0]})

        }).then(function(uri){

            //prints as "getTokenUri uri:" and no uri value returned
            console.log("getTokenUri uri: ", uri);

        }).catch(function(e) {

            //no error
            console.log("deploy err: ", e);

        });

    }
});

Any ideas on what I may be doing wrong? I've been stuck on this for a few days.

0

The problem is here:

new web3.eth.Contract(abi, accounts[0], ...

The second parameter needs to be the address of the deployed contract, but you're passing the address of your account instead.

  • Thanks for the tip and i've changed it, but return contractInstance.methods.getTokenUri(tokenId) .call({from:accounts[0]}) still doesn't return any value – Chris Aug 1 '18 at 13:12
  • Oh, sorry, looks like you're deploying a new instance every run anyway. – smarx Aug 1 '18 at 13:14
  • Btw, sorry about the typo. getEntityUri is getTokenUri – Chris Aug 1 '18 at 13:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.