Solidity
ERC20 totalSupply 沒有返回正確的值
我正在測試基於 Openzeppelin-solidity 模板的 ERC20 合約。但是我在讀取全域變數時觀察到了一種奇怪的行為。這是契約:
pragma solidity ^0.4.24; import "../node_modules/openzeppelin-solidity/contracts/token/ERC20/ERC20.sol"; contract FunnyToken is ERC20 { string public constant name = "FunnyToken"; string public constant symbol = "FYT"; uint8 public constant decimals = 18; uint256 private _totalSupply = 10000 * (10 ** uint256(decimals)); address private owner; constructor() public { owner = msg.sender; } }
然後我
truffle migrate
到 ganache-cli 並在 truffle 控制台上執行以下命令:FunnyToken.deployed().then(inst=> tok=inst); tok.totalSupply();
返回值是:
BigNumber { s: 1, e: 0, c: [ 0 ] }
。所以我得出的結論是 _totalSupply 全域變數沒有被正確初始化,因為函式totalSupply
是這樣實現的:function totalSupply() public view returns (uint256) { return _totalSupply; }
誰能解釋我發生了什麼事?
問題是您正在契約中創建一個新的儲存變數。
FunnyToken
基礎合約仍將訪問舊的儲存變數。一種解決方案是在建構子中賦值。
pragma solidity ^0.4.0; contract TokenBase { uint _totalSupply; function totalSupply() public view returns (uint) { return _totalSupply; } } contract Token is TokenBase { // uint _totalSupply = 4321; // <-- this creates a new storage variable constructor() public { _totalSupply = 1234; // It is better to initialize the old variable } }
另一種可能的解決方案是覆蓋
totalSupply()
合約中的函式,但您將浪費額外的儲存空間。
您需要做的就是將 bignumber 轉換為實際數字。此外,考慮到有多少人使用 open zeppelin,這似乎很不尋常。嘗試將 bignumber 顯示為數字。
const number = tok.totalSupply() number.toNumber()