首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ERC1155的奇怪问题

ERC1155的奇怪问题
EN

Ethereum用户
提问于 2022-09-25 09:35:20
回答 1查看 160关注 0票数 1

我已经编写了一个简单的智能契约,ERC1155允许ppl去薄荷NFT,除了mint函数之外,一切都很好。事务是正常的,但是当我检查balanceOf时,它总是返回0,即使是在造币之后。

这是我的象征性合同代码

代码语言:javascript
复制
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";

contract TopSevenPlayer is Initializable, ERC1155Upgradeable, AccessControlUpgradeable, PausableUpgradeable, ERC1155BurnableUpgradeable, ERC1155SupplyUpgradeable, UUPSUpgradeable {
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant UPGRADER_ROLE = keccak256("UPGRADER_ROLE");

    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() {
        _disableInitializers();
    }

    function initialize() initializer public {
        __ERC1155_init("https://staging-topseven.web.app/meta/{id}");
        __AccessControl_init();
        __Pausable_init();
        __ERC1155Burnable_init();
        __ERC1155Supply_init();
        __UUPSUpgradeable_init();

        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _grantRole(PAUSER_ROLE, msg.sender);
        _grantRole(MINTER_ROLE, msg.sender);
        _grantRole(UPGRADER_ROLE, msg.sender);
    }

    function pause() public onlyRole(PAUSER_ROLE) {
        _pause();
    }

    function unpause() public onlyRole(PAUSER_ROLE) {
        _unpause();
    }

    function mint(address account, uint256 id, uint256 amount, bytes memory data)
        public
        onlyRole(MINTER_ROLE)
    {
        _mint(account, id, amount, data);
    }

    function mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data)
        public
        onlyRole(MINTER_ROLE)
    {
        _mintBatch(to, ids, amounts, data);
    }

    function _beforeTokenTransfer(address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data)
        internal
        whenNotPaused
        override(ERC1155Upgradeable, ERC1155SupplyUpgradeable)
    {
        super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
    }

    function _authorizeUpgrade(address newImplementation)
        internal
        onlyRole(UPGRADER_ROLE)
        override
    {}

    // The following functions are overrides required by Solidity.

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC1155Upgradeable, AccessControlUpgradeable)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}

明特合同

代码语言:javascript
复制
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import '@openzeppelin/contracts/access/Ownable.sol';

import './TopSevenPlayer.sol';

contract PublicMinter is Ownable {
  TopSevenPlayer private token;
  address private contractAddress;
  bool public IS_FREE_MINT = true;
  uint256 public BASE_PRICE = 500000000 gwei;

  event Log(uint256 amount, uint256 gas);
  event ResultsFromCall(bool success, bytes data);

  constructor() {}

  receive() external payable {}

  fallback() external payable {}

  /**
  ***************************
  Public
  ***************************
   */

  function mint(
    address to,
    uint256 tokenId
  ) public payable {
    if (!IS_FREE_MINT) {
      require(msg.value >= BASE_PRICE, "Need to send more MATIC");
    }
    token.mint(to, tokenId, 1, '');
    emit Log(msg.value, gasleft());
  }

  /**
  ***************************
  Customization for the contract
  ***************************
   */

  function setContractAddress(address payable _address) external onlyOwner {
    contractAddress = _address;
    token = TopSevenPlayer(_address);
  }

  function withdraw() external onlyOwner {
    uint256 balance = address(this).balance;
    require(balance > 0, 'No amount left to withdraw');

    (bool success, bytes memory data) = (msg.sender).call{value: balance}('');
    require(success, 'Withdrawal failed');
    emit ResultsFromCall(success, data);
  }

  function setIsFreeMint(bool _isFreeMint) public onlyOwner {
    IS_FREE_MINT = _isFreeMint;
  }

  function setBasePrice(uint256 _basePrice) public onlyOwner {
    BASE_PRICE = _basePrice;
  }
}

测试也运行正常:

令牌合同测试

代码语言:javascript
复制
const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers');
const { expect } = require('chai');

const { ethers, upgrades } = require('hardhat');

describe('TopSevenPlayer', function () {
  // We define a fixture to reuse the same setup in every test.
  // We use loadFixture to run this setup once, snapshot that state,
  // and reset Hardhat Network to that snapshopt in every test.
  async function deployTopSevenPlayerFixture() {
    const [owner, otherAccount] = await ethers.getSigners();
    const TopSevenPlayer = await ethers.getContractFactory('TopSevenPlayer');
    const token = await upgrades.deployProxy(TopSevenPlayer);
    await token.deployed();
    return { token, owner, otherAccount };
  }

  describe('Deployment', function () {
    it('Should set the right owner', async function () {
      const { token, owner } = await loadFixture(deployTopSevenPlayerFixture);

      const isAdmin = await token.hasRole(
        await token.DEFAULT_ADMIN_ROLE(),
        owner.address
      );

      expect(isAdmin).to.equal(true);
    });

    it('Should get correct balance', async function () {
      const { token } = await loadFixture(deployTopSevenPlayerFixture);
      expect(await ethers.provider.getBalance(token.address)).to.equal(0);
    });
  });
});

minter合同试验

代码语言:javascript
复制
const { assert } = require('chai');
require('chai').use(require('chai-as-promised')).should();

const { ethers, upgrades } = require('hardhat');

const BASE_PRICE = 1e18;

describe('PublicMinter', function () {
  let accounts, token, minter;
  beforeEach(async function () {
    accounts = await ethers.getSigners();
    const TopSevenPlayer = await ethers.getContractFactory('TopSevenPlayer');
    const PublicMinter = await ethers.getContractFactory('PublicMinter');

    token = await upgrades.deployProxy(TopSevenPlayer);
    minter = await PublicMinter.deploy();

    await minter.setContractAddress(token.address);
    await token.grantRole(await token.MINTER_ROLE(), minter.address);
  });

  describe('deployment', async () => {
    it('deploys successfully', async () => {
      const tokenAddress = token.address;
      assert.notEqual(tokenAddress, 0x0);
      assert.notEqual(tokenAddress, '');
      assert.notEqual(tokenAddress, null);
      assert.notEqual(tokenAddress, undefined);

      const minterAddress = minter.address;
      assert.notEqual(minterAddress, 0x0);
      assert.notEqual(minterAddress, '');
      assert.notEqual(minterAddress, null);
      assert.notEqual(minterAddress, undefined);
    });
  });

  describe('minting', async () => {
    it('free mint successfully', async () => {
      const account = accounts[0];

      await minter.mint(account.address, 1);

      const totalSupply = await token.totalSupply(1);
      assert.equal(totalSupply, 1);
      const balance = await token.balanceOf(account.address, 1);
      assert.equal(balance, 1);
    });

    it('free mint failed', async () => {
      const account = accounts[0];
      await minter.setIsFreeMint(false);
      minter
        .mint(account.address, 1)
        .should.be.rejectedWith('Need to send more MATIC');
    });

    it('mint successfully', async () => {
      const account = accounts[0];

      await minter.setIsFreeMint(false);

      const value = BASE_PRICE.toString();
      await minter.mint(account.address, 1, {
        from: account.address,
        value,
      });

      const totalSupply = await token.totalSupply(1);
      assert.equal(totalSupply, 1);
      const balance = await token.balanceOf(account.address, 1);
      assert.equal(balance, 1);
    });

    it('mint failed due to not enough matic', async () => {
      const account = accounts[0];

      await minter.setIsFreeMint(false);

      const value = (BASE_PRICE * 1e-3).toString(); // not enough
      minter
        .mint(account.address, 1, {
          from: account.address,
          value,
        })
        .should.be.rejectedWith('Need to send more MATIC');
    });
  });
});

这是我象征性的孟买扫描合同:https://mumbai.polygonscan.com/address/0xA64c09eAECC403b12D97852E3089a5F4670AB120#readProxyContract

和minter合同,您可以看到我的mint事务与tokenId =1 https://mumbai.polygonscan.com/address/0x200643AC0DD4D043AA0Cd9036770066517C8aaFC一致。

我在两天内为它挣扎,当测试正常运行时,它真的很奇怪,但是部署后的结果是不正常的。

感谢各位的建议和解释,谢谢

EN

回答 1

Ethereum用户

发布于 2022-09-27 19:57:05

如果我理解正确的话,我认为你是在使用代理合同。您应该使用代理地址来完成所有事情,而不是部署的契约地址。

票数 0
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/136328

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档