【问题标题】:totalsupply() is not a function openzeppelin contractstotalsupply() 不是 openzeppelin 合约的函数
【发布时间】:2021-10-18 23:00:34
【问题描述】:

我正在尝试从 open zeppelin 导入一些合约文件,以便我的solidity 智能合约可以继承它们的功能,当我尝试编写在编译时在我的智能合约上运行的 chai 测试时,我的 chai 测试出现错误。

  3 passing (2s)
  1 failing

  1) Contract: Color
       minting
         creates a new token:
     TypeError: contract.totalSupply is not a function

我的合约导入 openzeppelin 合约

pragma solidity 0.8.7;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; //import base functionality
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; //import totalsupply()

contract color is ERC721 {
    string[] public colors;
    mapping(string => bool) _colorExists; //mappings are like json objects where value a is searched and its value is returned
    constructor() ERC721("Color", "COLOR") {
    }

    function mint(string memory _color) public{
      colors.push(_color);
      uint _id = colors.length -1;

      _mint(msg.sender,_id);
      _colorExists[_color] = true;
 
    }
}

最后是我的测试文件(我已将其缩短以仅显示给我错误的测试)

const { assert } = require('chai')
const Color = artifacts.require('./Color.sol')

require('chai')
.use(require('chai-as-promised'))
.should()

contract('Color', (accounts) =>{
    let FormControlStatic

    before(async ()=>{
        contract = 
        await Color.deployed()
    })
    
    describe('minting', async ()=>{
        
        it('creates a new token', async ()=>{
            const result = await contract.mint('#EC058E')
            console.log(result)
            const totalSupply = await contract.totalSupply()

            assert.equal(totalSupply,1)
            console.log(result)
        })
    })
})

如果我们查看包含函数 totalSupply() 的文件,它是公共范围的,因此它应该通过导入在函数外部可见

我做了一些挖掘并从 openzeppelin 导入了实际函数所在的文件,但似乎我仍然遇到相同的错误,我尝试单独编译以查看更改后重新编译是否会解决,但它没有解决

不确定最近是否有其他人经历过此问题或可能有解决方案 我也在此处导入当前版本 https://www.npmjs.com/package/@openzeppelin/contracts

谢谢!

【问题讨论】:

    标签: ethereum solidity openzeppelin


    【解决方案1】:

    我们必须扩展IERC721Enumerable 合约,并实现它的虚函数。

    contract Color is ERC721, IERC721Enumerable { // We must extends IERC721Enumerable 
        string[] public colors;
        mapping(string => bool) _colorExists;
    
        constructor() ERC721("Color", "COLOR") {}
    
        function mint(string memory _color) public {
            colors.push(_color);
            uint256 _id = colors.length - 1;
    
            // _mint(msg.sender,_id);
            _colorExists[_color] = true;
        }
        
    
        // And must override below three functions
    
        function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {
            // You need update this logic.
            // ...
            return 3;
        }
    
        function totalSupply() external  view override returns (uint256) {
          // You need update this logic.
          // ...
          return 1;
        }
    
        function tokenByIndex(uint256 index) external view  override returns (uint256) {
          // You need update this logic.
          // ...
          return 5;
        }
    }
    

    然后,我们可以调用totalSupply()方法

    【讨论】:

    • 感谢在玩弄这个之后能够让它与这个方法一起工作:)
    • 嘿@lutherwardle 我也有同样的问题。关于如何修复它的更多细节?我已将这三个函数添加到 ERC721 构造函数下的 Color.test.js 文件中(假设您正在使用相同的示例 luther)。谢谢!
    【解决方案2】:

    下面是智能合约的完整实现。

    正如您在问题中提到的,它使用比tutorial 更新的版本:

    • 稳固性 (0.8.0)
    • 打开 Zeppelin (4.3.2)
    pragma solidity ^0.8.0; // Note that this is using a newer version than in 
    
    import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
    import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
    
    
    contract Color is ERC721, ERC721Enumerable {
        string[] public colors;
        mapping(string => bool) _colorExists;
    
        constructor() ERC721("Color", "COLOR") public {
        }
    
        function _beforeTokenTransfer(address from, address to, uint256 tokenId)
        internal
        override(ERC721, ERC721Enumerable)
        {
            super._beforeTokenTransfer(from, to, tokenId);
        }
    
        function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721Enumerable)
        returns (bool)
        {
            return super.supportsInterface(interfaceId);
        }
    
    
        function mint(string memory _color) public {
            colors.push(_color);
            uint _id = colors.length - 1;
            _mint(msg.sender, _id);
            _colorExists[_color] = true;
        }
    }
    
    
    

    您还可以查看 OpenZeppelin 关于 Extending Contracts 的部分,了解 overridessuper

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-24
      • 2023-01-29
      • 1970-01-01
      • 2022-07-07
      • 2021-11-14
      • 2019-04-20
      • 2021-08-14
      • 2021-10-08
      相关资源
      最近更新 更多