javascript 函数正在返回一个 promise,并且 promise 用于 solidity 函数,它给出了无效参数的错误

The javascript function is returning a promise and the promise is used in the solidity function which gives the error of invalid arguments

我正在尝试制作一个维护各种交易版本的 Dapp(当我们更新交易数据时会创建新版本)。我正在使用 javascript we3.js api 通过 javascript 调用我的 solidity 函数。当我们使用名为 'client' 的字段进行搜索时,我有一个显示数据的函数。当我单击按钮以基于客户端进行搜索时,出现 returns 错误。我在 javascript 中使用 promise,但在我看来 javascript 函数正在返回一个未定义到 solidity 函数的 promise。但是在错误发生后,javascript 函数返回了预期值(我使用 console.log 进行了检查)。

我试过使用 async/await,但似乎没有用。

我的 Javascript 代码:-

getVersion:async function(i){

var returnedLatestVersion;

App.contracts.Trades.deployed().then(async function(instance){

    await instance.getLatestVersionOfTrade.call(i).then(function(a){      

      returnedLatestVersion = a;
      console.log("test:"+returnedLatestVersion+",a:"+a);

    }).catch(function(err){
    console.log(err)
    })
    console.log("test2="+returnedLatestVersion);
    return await returnedLatestVersion;    
  })    
},


searchByClient: function(){

var tradesInstance;

var client = $('#clientSearch').val();

var tradeResults = $("#tradesResult");
tradeResults.empty();

App.contracts.Trades.deployed().then(function(instance){
  tradesInstance = instance; 

  return tradesInstance.getClientData.call(client).then(async function(returnValues){      

    console.log("returnValues Array = "+returnValues);

    var returnValuesLength = returnValues.length;   

    for(var i=0;i<returnValuesLength;i++){     

      var a = returnValues[i];
      var c = returnValues[i];    
      var j;

      j = await App.getVersion(a);

      console.log("version ="+j);
      console.log("tradeId="+a);

      tradesInstance.trades(c,j).then(function(trade){

        var secId = trade[0];
        var notional = trade [1];
        var price = trade[2];
        var client = trade[3];

        var tradeTemplate = "<tr><td>" + secId + "</td><td>" + notional + "</td><td>" + price + "</td><td>" + client +"</td></tr>" 
        tradeResults.append(tradeTemplate);
      })
    }
  }).catch(function(err){
    console.log(err);
  })
}).catch(function(err){
  console.warn(err);
})

}

};

我的智能合约:-

pragma solidity 0.5.0;

contract Trades {
  struct Trade {
    string secId;
    uint notional;
    uint price;
    string client;
    uint version;
    uint index;       
    uint  tradeId;
  }

mapping(uint =>mapping(uint => Trade)) public trades;

uint public tradeId;
uint[] tradeIndex;
uint[] tradeID;
uint[] public totalNum;

function updateTrade(uint _tradeId, string memory _secId,uint _notional,uint _price,string memory _client) public{

    uint j;
    j= (getLatestVersionOfTrade(_tradeId)) + 1;
    trades[_tradeId][j].secId = _secId;
    trades[_tradeId][j].notional = _notional;
    trades[_tradeId][j].price = _price;
    trades[_tradeId][j].client = _client;
    trades[_tradeId][j].version = j;
    trades[_tradeId][j].index = tradeIndex.push(tradeIndex[tradeIndex.length-1]+1);
}

function setTrade(string memory _secId,uint _notional,uint _price,string memory _client) public {

    uint  version  = 0;
    tradeId++;

    trades[tradeId][version].secId = _secId;
    trades[tradeId][version].notional = _notional;
    trades[tradeId][version].price = _price;
    trades[tradeId][version].client = _client;
    trades[tradeId][version].version = version;
    trades[tradeId][version].index = tradeIndex.push(tradeId);
    tradeID.push(tradeId);
}

function getAllTradeData()view public returns(uint[] memory){
    return tradeIndex;
}

function getAllTradeDataId()view public returns(uint[] memory){
    return tradeID;
}

function getTradeById(uint _tradeId,uint version)view public returns(string memory, uint, uint, string memory, uint, uint){
    return (trades[_tradeId][version].secId, trades[_tradeId][version].notional, trades[_tradeId][version].price,
    trades[_tradeId][version].client,trades[_tradeId][version].version, trades[_tradeId][version].index);
}

   function getLatestVersionOfTrade(uint _tradeId) view public returns (uint) {
    uint max = 0;

    for (uint i = 0; i < tradeIndex.length; i++) {
        uint ver = trades[_tradeId][i].version;
        if (ver > max) {
            max = ver;
        }
    }
return max;
}

function getClientData(string memory _client) public returns (uint[] memory) {  

    if (totalNum.length > 0){
        delete totalNum;
    }
        for(uint i=1; i <= tradeID.length;i++){
        uint j;
        j= (getLatestVersionOfTrade(i));
        if(uint(keccak256(abi.encodePacked(trades[i][j].client))) == uint(keccak256(abi.encodePacked(_client)))){
            totalNum.push(i);
        }             
    }  
    return totalNum;
}

function getTotalNumLength() public returns (uint){
    return totalNum.length;
}
}

浏览器控制台上显示的错误:-

returnValues Array = 3,4,5
app.js:113 version =undefined
app.js:114 tradeId=3
app.js:113 version =undefined
app.js:114 tradeId=4
app.js:113 version =undefined
app.js:114 tradeId=5

3inpage.js:1 Uncaught (in promise) Error: Invalid number of arguments to 
Solidity function
at Object.InvalidNumberOfSolidityArgs (inpage.js:1)
at u.validateArgs (inpage.js:1)
at u.toPayload (inpage.js:1)
at u.call (inpage.js:1)
at u.execute (inpage.js:1)
at truffle-contract.js:136
at new Promise (<anonymous>)
at truffle-contract.js:127

app.js:77 test:0,a:0
app.js:82 test2=0
app.js:77 test:0,a:0
app.js:82 test2=0
app.js:77 test:1,a:1
app.js:82 test2=1

searchByClient 中的变量 'j' 在传入 'trades(c,j)' 时返回未定义的值。但是在函数 getVersion 中返回的值似乎没问题。请帮助我,因为我别无选择。另外,我是 javascript 的新手,所以如果我犯了任何错误,请告诉我。我能够在教程的帮助下编写这段代码。

尝试这样修改getVersion

getVersion:async function(i){

   var returnedLatestVersion;
   return new Promise((resolve, reject) => {
      App.contracts.Trades.deployed().then(async function(instance){
         await instance.getLatestVersionOfTrade.call(i).then(function(a){      
            returnedLatestVersion = a;
            console.log("test:"+returnedLatestVersion+",a:"+a);
            resolve(returnedLatestVersion); // here you return your result as a promise
         }).catch(function(err){
            console.log(err)
            reject(err); // here you reject the promise in case of error
         })
         console.log("test2="+returnedLatestVersion); 
      })
   })
}

您还可以 return instance.getLatestVersionOfTrade.call(i)` 的结果,这也将 return 一个承诺。但我认为使用 resolve 可以让你更清楚地知道你在 returning 是什么。