Почему запуск метода отправки по контракту работает, а вызов — нет?

Я все еще новичок в веб-разработке и солидности, так что исправьте мои недоразумения. Я работал с web3 на внешнем интерфейсе, но теперь я пытаюсь настроить интеграцию web3 на стороне сервера с помощью NodeJS. Web3, похоже, правильно подключен к моему локальному тестовому узлу Ganache, и, на самом деле, методы изменения состояния работают правильно, но значение не получено всякий раз, когда я пытаюсь получить значение из метода контракта, помеченного как «просмотр».

Имейте в виду, что мои модульные тесты Truffle JS доказывают, что код контракта успешно развертывается, изменяет состояние и извлекает данные. К сожалению, я не могу заставить работать трюфельное соединение в моей среде NodeJS (думаю, какая-то проблема с версиями в web3), поэтому я не могу просто скопировать и вставить код модульного теста. Я вынужден отказаться от работы с truffle-connect и использовать руководство ff: web3.eth.Contract

Код:

Вызываемые методы Solidity Contract:

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];
    }
    ...
}

Успешный модульный тест Truffle:

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 в веб-3 + вызовы метода контракта:

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

        });

    }
});

Любые идеи о том, что я могу делать неправильно? Я застрял на этом несколько дней.

Ответы (1)

Проблема здесь:

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

Второй параметр должен быть адресом развернутого контракта, но вместо этого вы передаете адрес своей учетной записи.

Спасибо за совет, я изменил его, но return contractInstance.methods.getTokenUri(tokenId) .call({from:accounts[0]}) по-прежнему не возвращает никакого значения
О, извините, похоже, вы все равно развертываете новый экземпляр при каждом запуске.
Кстати, извините за опечатку. getEntityUri — это getTokenUri