繁体   English   中英

如何使用 nodejs 上的 Web3js 解码在以太坊上调用智能合约的响应

[英]How to decode response from calling smart contract on Ethereum using Web3js on nodejs

我的项目由 3 个部分组成

  1. Node.js 服务器使用 Web3js 连接以太坊网络。
  2. Truffle 项目由智能合约组成。
  3. Ganache 用于运行本地以太坊网络。

基本上,我需要从我的 Node.js 服务器调用以太坊网络以从区块链网络获取数据。

这是我的主要合同

// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract RewardToken is ERC20 {
    constructor(string memory name, string memory symbol) ERC20(name, symbol) {}
}

这是我的工厂合同

// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

import './RewardToken.sol';

contract RewardTokenFactory {
  address[] public deployedRewardTokens;
  mapping(address => RewardToken) ownerToTokens;

  function createToken(string calldata name, string calldata symbol) public {
    RewardToken newToken = new RewardToken(name, symbol);
    ownerToTokens[msg.sender] = newToken;
    deployedRewardTokens.push(address(newToken));
  }

  function getOwnerToken() public view returns(RewardToken) {
    return ownerToTokens[msg.sender];
  }
}

这是我的 Node.js 方法

const rewardTokenData = await rewardTokenContractInstance.getOwnerToken({
  from: address,
});

console.log(rewardTokenData, ' :rewardTokenData');

这是我在调用.getOwnerToken后从rewardTokenData得到的

0xcb22Ff93c8253224dBAF033376c762bC03024343

那么我应该假设new RewardToken获取实际的合同数据吗?

如果不是,那么我如何将响应解码为可读数据?

我假设您想从所有者的代币合约中提取数据。 为此,您必须在 Factory 合约中编写特定的 get 函数。 下面是一个示例,从 msg.sender 拥有的合约中获取代币的总供应量:

contract RewardTokenFactory {
  address[] public deployedRewardTokens;
  mapping(address => RewardToken) ownerToTokens;

  function createToken(string calldata name, string calldata symbol) public {
    RewardToken newToken = new RewardToken(name, symbol);
    ownerToTokens[msg.sender] = newToken;
    deployedRewardTokens.push(address(newToken));
  }

  function getTotalSupply() public view returns(uint256) {
    return ownerToTokens[msg.sender].totalSupply();
  }
}

在前端,您必须使用 .toNumber() 将其转换为更小的数字,以便它适用于 JavaScript。

在这里您可以看到记录在案的 erc20 totalSupply() 函数: https ://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20-totalSupply--

您还可以在那里查看可以使用的其他功能。 没有很多。 您可以创建的其他可能的“视图”类型函数是获取该令牌的特定地址的余额(getBalance()),

然而,你总是可以在你的代币合约中添加额外的函数,然后你可以在你的工厂合约中使用这些函数来编写获取函数:

// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract RewardToken is ERC20 {
    constructor(string memory name, string memory symbol) ERC20(name, symbol) {}
function getTokenName() public {
 return _name;
}
}

你可以在他们的 github 上找到 ERC20 的所有私有变量: https ://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol

然后您可以在工厂合约中使用getTokenName()来获取 msg.sender 拥有的令牌的名称:

contract RewardTokenFactory {
  address[] public deployedRewardTokens;
  mapping(address => RewardToken) ownerToTokens;

  function createToken(string calldata name, string calldata symbol) public {
    RewardToken newToken = new RewardToken(name, symbol);
    ownerToTokens[msg.sender] = newToken;
    deployedRewardTokens.push(address(newToken));
  }

  function getTokenNameOfMsgSender() public view returns(uint256) {
    return ownerToTokens[msg.sender].getTokenName();
  }
}

注意:我没有测试代码,可能有语法错误。

您必须编写特定的 get 函数的原因是因为发送到 web3.js 的合约太大了。 Solidity 自动将合约散列为 256 位散列,这使得它无法在前端使用(或者您显示的散列可能只是令牌合约的地址,我不确切知道,但这无关紧要)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM