【问题标题】:The javascript function is returning a promise and the promise is used in the solidity function which gives the error of invalid argumentsjavascript函数返回一个promise,并且promise用于solidity函数,它给出了无效参数的错误
【发布时间】:2019-07-02 08:30:57
【问题描述】:

我正在尝试制作一个维护各种交易版本的 Dapp(当我们更新交易数据时会创建新版本)。我正在使用javascript we3.js api通过javascript调用我的solidity函数。当我们使用名为“客户端”的字段进行搜索时,我有一个显示数据的功能。当我单击按钮根据客户端进行搜索时,它会返回错误。我在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非常陌生,所以如果我犯了任何错误,请告诉我。我能够在教程的帮助下编写此代码。

【问题讨论】:

  • 看看这里调用函数的正确方法。 web3js.readthedocs.io/en/1.0/…。您的代码中有一些错误。此外,在发布此类代码时,请确保其格式正确。
  • 但是我调用我的智能合约函数没有任何问题。他们正在按预期工作。据我说,从函数“getVersion”获取输出存在问题。你能告诉我如何在函数'getVersion'中使用promise吗??

标签: javascript promise blockchain ethereum solidity


【解决方案1】:

尝试像这样修改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); 
      })
   })
}

您还可以返回 instance.getLatestVersionOfTrade.call(i)` 的结果,这也将返回一个承诺。但我认为使用 resolve 可以更清楚地了解您返回的具体内容。

【讨论】:

  • 感谢您的努力,但仍然是同样的错误。但不是显示 version= undefined,而是显示 version = [object promise](在浏览器控制台中)。
  • 调用getVersion时是否使用await?
  • 就是这样!!我早些时候在调用 getVersion 时删除了等待(只是检查一些东西),现在使用等待,一切似乎都工作正常。非常感谢@nikos fotiadis
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-20
  • 1970-01-01
  • 2022-11-14
  • 1970-01-01
  • 2017-09-13
  • 1970-01-01
相关资源
最近更新 更多