Массив, возвращенный из солидности, присвоенный в качестве номера в Javascript

#javascript #arrays #overflow #solidity

Вопрос:

Я очень новичок в разработках Solidity и Javascript, и в последнее время я столкнулся с некоторыми проблемами.

Пример использования:

  1. Храните массив данных от Javascript до солидности.
  2. Верните сохраненный массив из Solidity обратно в код Javascript.

Код Javascript для получения массива:

     async loadBlockchain() {
    const web3 = window.web3
    const accounts = await web3.eth.getAccounts()
    console.log("Eth account: "   accounts)
    this.setState({account: accounts[0]})
    const networkID = await web3.eth.net.getId()
    console.log("Eth network ID: "   networkID)
    const networkData = storeHash.networks[networkID]
    
    if(networkData) {
        //Fetch the smart contract from the address
        const abi = storeHash.abi
        const address = networkData.address
        const contract = new web3.eth.Contract(abi, address)
        this.setState({ contract })
        console.log(contract)

        var fileHashList = await contract.methods.get().call()
        console.log(fileHashList)
    } 
    else 
    {
        window.alert('Smart contract not deployed to detected network')
    }
}
 

Код надежности для возврата массива:

 pragma solidity 0.5.16;
pragma experimental ABIEncoderV2;

contract storeHash {
//Upload stored file hash in blockchain

string[] public fileHash;
//uint256 public fileCount = 0;

//Store hash value
function set(string memory _fileHash) public {
    
    fileHash.push(_fileHash);
}


//Retrieve hash value
function get() public view returns (string[] memory) {

    return fileHash;

}
 

Вопрос:

  1. Возвращенный массив, по-видимому, считывается как BigNumber и показывает следующую ошибку:

    Необработанный отказ (null): переполнение (ошибка=»переполнение», операция=»Номер тона», значение=»36830543755683898667443985212771609229556685323236234700674529361303541601398″, код=NUMERIC_FAULT, версия=bignumber/5.3.0)

  2. Сообщение об ошибке в консоли:
 Uncaught (in promise) null: overflow (fault="overflow", operation="toNumber", value="36830543755683898667443985212771609229556685323236234700674529361303541601398", code=NUMERIC_FAULT, version=bignumber/5.3.0)
    at Logger.makeError (http://localhost:3000/static/js/vendors~main.chunk.js:6622:19)
    at Logger.throwError (http://localhost:3000/static/js/vendors~main.chunk.js:6633:18)
    at throwFault (http://localhost:3000/static/js/vendors~main.chunk.js:3782:17)
    at BigNumber.toNumber (http://localhost:3000/static/js/vendors~main.chunk.js:3584:9)
    at http://localhost:3000/static/js/vendors~main.chunk.js:666:54
    at Array.forEach (<anonymous>)
    at unpack (http://localhost:3000/static/js/vendors~main.chunk.js:661:10)
    at ArrayCoder.decode (http://localhost:3000/static/js/vendors~main.chunk.js:818:39)
    at http://localhost:3000/static/js/vendors~main.chunk.js:669:23
    at Array.forEach (<anonymous>)
    at unpack (http://localhost:3000/static/js/vendors~main.chunk.js:661:10)
    at TupleCoder.decode (http://localhost:3000/static/js/vendors~main.chunk.js:1275:92)
    at AbiCoder.decode (http://localhost:3000/static/js/vendors~main.chunk.js:185:20)
    at ABICoder.push../node_modules/web3-eth-abi/lib/index.js.ABICoder.decodeParametersWith (http://localhost:3000/static/js/vendors~main.chunk.js:308757:28)
    at ABICoder.push../node_modules/web3-eth-abi/lib/index.js.ABICoder.decodeParameters (http://localhost:3000/static/js/vendors~main.chunk.js:308739:15)
    at Contract.push../node_modules/web3-eth-contract/lib/index.js.Contract._decodeMethodReturn (http://localhost:3000/static/js/vendors~main.chunk.js:310221:20)
    at Method.outputFormatter (http://localhost:3000/static/js/vendors~main.chunk.js:310556:32)
    at Method.push../node_modules/web3-core-method/lib/index.js.Method.formatOutput (http://localhost:3000/static/js/vendors~main.chunk.js:306298:50)
    at sendTxCallback (http://localhost:3000/static/js/vendors~main.chunk.js:306848:25)
    at cb (http://localhost:3000/static/js/vendors~main.chunk.js:198169:22)
    at Item.push../node_modules/process/browser.js.Item.run (http://localhost:3000/static/js/vendors~main.chunk.js:242191:12)
    at drainQueue (http://localhost:3000/static/js/vendors~main.chunk.js:242155:34)
 

Могу я узнать, как я могу исправить эту проблему и получить массив, который я хотел, в моем приложении NodeJS?
Заранее благодарю вас!

Комментарии:

1. Вы уже разобрались с этим? Получил аналогичную ошибку в другом случае. AFAIK, solidity не принимает возвращаемые массивы для внешних вызовов (javascript).

2. @joaoavf Еще нет 🙁 отчаянно ищу альтернативу, так как приближается крайний срок моего проекта.

Ответ №1:

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

Изменение контракта в солидности

  • напишите метод для возврата длины массива:
     function getLength() public view returns(uint){
        return fileHash.length
     }
     
  • напишите метод для получения элемента из массива по индексу:
     function getFileHashByIndex(uint index) public view returns (string memory){
       return fileHash[index]
    }
     

Изменение кода в javascript

 let fileHashes,filesCount;
// dealing with contract is async. always use try/catch
try {
     filesCount = await contract.methods.getLength().call();
       
    fileHashes = await Promise.all(
      Array(parseInt(filesCount))
        .fill()
        .map((element, index) => {
          return contract.methods.getFileHashByIndex(index).call();
        })
    );
    
  } catch (e) {
    console.log("error in pulling file hashes", e);
  }