reactjs - 如何使用 ethers.js 在 React 前端提取 Solidity 应付交易的结果?
问题描述
我有一个 Solidity 智能合约函数,它在交易完成时返回 3 个变量、匹配数字、滚动、奖金。
function createTicket() external payable returns (uint _matchednumbers, uint[10] memory _generatednumbers, uint _winnings) {
generateNumbers();
uint[10] memory roll = getGenerateNumbers();
uint matchednumbers;
uint winnings;
for(uint i = 0; i < 10; i++) {
for (uint j = 0; j < 10; j++) {
if (arrays[msg.sender][i] == roll[j]) {
matchednumbers +=1;
}
}
if (matchednumbers == 5) {
winnings = msg.value * 5; // msg.value is amount of wei (ether / 1e18), winnings is returning wei, winnings is being saved to next roll after win, need to fix!
}
if (matchednumbers == 6) {
winnings = msg.value * 24;
}
if (matchednumbers == 7) {
winnings = msg.value * 142;
}
if (matchednumbers == 8) {
winnings = msg.value * 1000;
}
if (matchednumbers == 9) {
winnings = msg.value * 4500;
}
if (matchednumbers == 10) {
winnings = msg.value * 10000;
}
}
return (matchednumbers, roll, winnings);
}
交易完成后,我正在尝试在我的前端在 React 中呈现交易结果、matchednumbers(只是一个 int)、roll(一个数字数组)和奖金(另一个 int)。只需要确定如何做到这一点?或者,如果可以使用外部的、可支付的 Solidity 功能。在我的 App.js 中,我有这个:
async function roll() {
if (typeof window.ethereum !== "undefined") {
await requestAccount();
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
const contract = new ethers.Contract(keno3Address, Keno3.abi, signer);
// const transaction = await contract.deposit({ value: ethers.utils.parseEther("6") })
try {
const data = await contract.createTicket(); // createTicket()
await data.wait();
console.log("data: ", data);
const result = ethers.iface.decodeFunctionData("transferFrom", data);
return data
} catch (err) {
console.log("Error: ", err);
}
}
}
它在 console.log 中返回事务的数据,但我看不到这些变量的结果,如果我在那里运行它,我会在 Remix 中看到。还是我需要解码交易?我也试过了,但它没有像你看到的那样工作。
解决方案
从合约返回的单位是类型(在此处BigNumber
阅读有关 BigNumber的更多信息)
所以data
应该登录控制台是这样的:
(3) [BigNumber, Array(6), BigNumber]
也data[0] = BigNumber{_hex: "0xfe", _isBigNumber: true}
和也许data[1] = [1,2,3,...,9,10]
和data[3] = BigNumber{_hex: "0xfe", _isBigNumber: true}
。请注意,您的结果与我写的结果完全不同,它们只是示例。
要将 BigNumber 更改为 Number,您可以使用toNumber()
简单地添加到 BigNumber 的函数。
let matchedNumbers = data[0].toNumber();
let generatedNumbers = data[1]; //this is array type, not BigNumber!
let winnings = data[2]
推荐阅读
- objective-c - Objective-C int 作为 Int32 桥接到 Swift
- actions-on-google - 是否可以从项目中删除帐户关联?
- python - 如何生成 100 个网格地图?
- powershell - 将用户/计算机的 OU 添加到安全组
- c# - Eto.Forms StackLayout of Labels 在添加时刷新整个列表
- elm - ELM Custom Elements
- android - 通话结束后自动启动应用程序在 Redmi 中不起作用,但在 Moto 和诺基亚中起作用
- android - 当textview中有两行时如何在相对布局中对齐textview中心
- python - binascii.Error:无效的 base64 编码字符串:数据字符数(1957)不能是 1 大于 4 的倍数
- python - 我如何指定一个 json 路径来获取所有对象