You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复ReferenceError: totalSupply未定义错误?

区块链开发错误修复:ReferenceError: totalSupply is not defined

错误信息

ReferenceError: totalSupply is not defined

问题代码

Truffle测试代码

const { assert } = require("chai");

const KryptoBird = artifacts.require("KryptoBird");

// check for chai
require('chai')
.use(require('chai-as-promised'))
.should()

contract('KryptoBird', (accounts) => {

    let contract
    before( async () => {
    contract = await KryptoBird.deployed()
    })
    
    
    
    describe('deployment', async() => {
        it("deploys successfully", async () => {
            const address = contract.address;
            assert.notEqual(address, '')
            assert.notEqual(address, null)
            assert.notEqual(address, undefined)
            assert.notEqual(address, 0x0)
        })
        it('has a name', async() => {
            const name = await contract.name()
            assert.equal(name, 'KryptoBird')
        }) 

        it('has a symbol', async() => {
            const symbol = await contract.symbol()
            assert.equal(symbol, 'KBIRDZ')
        })

    }) 

    describe('minting', async ()=> {
        it('creates a new token', async () => {
            const result = await contract.mint('https...1')
            const totalSupply = await contract.totalSupply();
            assert.equal(totalSupply, 1)
            const event = result.logs[0].args
            assert.equal(event._from, '0x0000000000000000000000000000000000000000', 'from is the contract')
            assert.equal(event._to, accounts[0], 'to is msg.sender')

            await contract.mint('https...1').should.be.rejected
        })
    })

    describe('indexing', async()=> {
        it('lists KryptoBirdz', async()=> {            
        // Mint three new tokens
        await contract.mint('https...2')
        await contract.mint('https...3')
        await contract.mint('https...4')
        const totalSupply = await contract.totalSupply()
        })

        let result = []
        let KryptoBird
        for(i = 1; i <= totalSupply; i++) {
            KryptoBird = await contract.kryptoBirdz(i)
            result.push(KryptoBird)
    }

    let expected = ['https...1','https...2','https...3','https...4']
    assert.equal(result.join(','), expected.join(','))

})

})

Solidity合约代码

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

import './ERC721Connecter.sol';

contract KryptoBird is ERC721Connecter {

    string[] public kryptoBirdz;

    mapping(string => bool) _kryptoBirdzExists;

    function mint(string memory _kryptoBird) public {
        
        require(!_kryptoBirdzExists[_kryptoBird],
        'Error - kryptoBird already exists');

        // this is deprecated - uint _id = KryptoBirdz.push(_kryptoBird);
        kryptoBirdz.push(_kryptoBird);
        uint _id = kryptoBirdz.length - 1;

        // .push no logner returns the length but a ref to the added element
        _mint(msg.sender, _id);
         _kryptoBirdzExists[_kryptoBird]=true;


    }
    

constructor() ERC721Connecter('KryptoBird','KBIRDZ')
{}

}

错误原因

  1. 变量作用域问题:在indexing测试块中,totalSupply变量是在it('lists KryptoBirdz', async()=> { ... })函数内部声明的,但后续的for循环和断言逻辑写在了it函数外部,超出了变量的作用域范围,导致JS无法找到该变量,抛出ReferenceError。
  2. 合约方法缺失(潜在问题):ERC721标准并未强制实现totalSupply()方法,如果你的ERC721Connecter父合约没有实现这个方法,调用contract.totalSupply()会触发合约层面的错误,需要额外处理。

修复方案

1. 修正测试代码的作用域问题

将indexing块中的for循环和断言逻辑全部移到it函数内部,确保totalSupply变量能被正确访问:

describe('indexing', async()=> {
    it('lists KryptoBirdz', async()=> {            
        // Mint three new tokens
        await contract.mint('https...2')
        await contract.mint('https...3')
        await contract.mint('https...4')
        const totalSupply = await contract.totalSupply()
        
        let result = []
        let KryptoBird
        for(let i = 1; i <= totalSupply; i++) { // 添加let声明i,避免全局变量污染
            KryptoBird = await contract.kryptoBirdz(i)
            result.push(KryptoBird)
        }

        let expected = ['https...1','https...2','https...3','https...4']
        assert.equal(result.join(','), expected.join(','))
    })
})

2. 实现合约的totalSupply()方法(如果父合约未提供)

在KryptoBird合约中添加totalSupply()方法,直接返回kryptoBirdz数组的长度:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

import './ERC721Connecter.sol';

contract KryptoBird is ERC721Connecter {

    string[] public kryptoBirdz;

    mapping(string => bool) _kryptoBirdzExists;

    function mint(string memory _kryptoBird) public {
        
        require(!_kryptoBirdzExists[_kryptoBird],
        'Error - kryptoBird already exists');

        kryptoBirdz.push(_kryptoBird);
        uint _id = kryptoBirdz.length - 1;

        _mint(msg.sender, _id);
         _kryptoBirdzExists[_kryptoBird]=true;
    }

    // 添加totalSupply方法
    function totalSupply() public view returns(uint256) {
        return kryptoBirdz.length;
    }

    constructor() ERC721Connecter('KryptoBird','KBIRDZ')
    {}
}

验证修复

  1. 重新编译合约:truffle compile
  2. 运行测试:truffle test

内容的提问来源于stack exchange,提问作者Koruma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 08:01:40