[英]The javascript function is returning a promise and the promise is used in the solidity function which gives the error of invalid arguments
I am trying to make a Dapp which maintains the various versions of a trade(new versions are created when we update the data of trade). 我正在尝试制作一个Dapp来维护交易的各种版本(当我们更新交易数据时会创建新版本)。 I am using javascript we3.js api to call my solidity functions through javascript. 我正在使用javascript we3.js api通过javascript调用我的Solidity函数。 I have a function which displays the data when we search using a field called 'client'. 我有一个函数,当我们使用名为“ client”的字段进行搜索时会显示数据。 When I am clicking the button to search on basis of client, it returns an error. 当我单击按钮以基于客户端进行搜索时,它返回一个错误。 I am using promises in javascript, but it seems to me that the javascript function is returning a promise which is undefined to solidity function. 我在javascript中使用了Promise,但是在我看来,JavaScript函数正在返回未定义到Solidity函数的Promise。 But after the error the javascript function is returning the expected values(I checked using console.log). 但是在发生错误后,javascript函数返回了期望值(我使用console.log检查了)。
I have tried using async/await but that doesnt seems to do the trick. 我试过使用async / await,但这似乎并不能解决问题。
My Javascript code:- 我的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);
})
}
};
My Smart Contract :- 我的智能合约:
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;
}
}
The error shown on brower console : - 浏览器控制台上显示的错误:-
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
The variable 'j' in searchByClient is returning an undefined value when it is passed in 'trades(c,j)'. 当在“ trades(c,j)”中传递时,searchByClient中的变量“ j”将返回未定义的值。 But in the function getVersion the value returning seems to be fine. 但是在函数getVersion中,返回值似乎很好。 Please help me out as I have no other options left. 请帮我,因为我没有其他选择了。 Also I am extremly new to javascript, so please do tell me if I had make any mistakes. 另外,我对javascript非常陌生,所以请告诉我是否出错。 I was able to write this code with help of a tutorial. 我能够在教程的帮助下编写此代码。
Try to modify getVersion
like this: 尝试像这样修改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);
})
})
}
You can also return the result of instance.getLatestVersionOfTrade.call(i)` and this will return a promise as well. 您还可以返回instance.getLatestVersionOfTrade.call(i)`的结果,这还将返回一个promise。 But I think using resolve makes it a little more clear what exactly it is that you are returning. 但是我认为使用决心可以使您更清楚地知道返回的确切内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.