Solidity

應付外部函式呼叫不更新狀態變數

  • October 26, 2019

我正在嘗試buyToken()更新呼叫者的餘額。我正在使用 Truffle 和 Ganache,執行測試,但testBuyToken()函式一直失敗,顯然BALANCES變數沒有改變,CIRCULATING_SUPPLY.

這是因為address(this)in與inTestBasicToken.sol不同嗎?這是因為在斷言嘗試執行之前它無法足夠快地更新變數嗎?或者還有什麼我從根本上誤解的東西。另外兩個測試工作正常,我猜這與這個功能是付費的事實有關。msg.sender``BasicToken.sol

TestBasicToken.sol

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/BasicToken.sol";

contract TestBasicToken{
  uint public inintialBalance = 10**17 * 10;

  address payable Owner = 0x65727c4c3869EA9BbB3BE13613F0a2Fd37e28259;
  address contractAddress = address(this);
  BasicToken basicToken = new BasicToken(Owner);

  uint expectedSupply = 0;
  uint expectedBalance = 300;


  function testTotalSupply() public {
     uint _totalSupply = basicToken.totalSupply();
     Assert.equal(expectedSupply, _totalSupply, "Expected supply should match return value");
  }
  function testBalanceOf() public {
     uint _balance = basicToken.balanceOf(Owner);
     Assert.equal(expectedBalance, _balance, "Expected balance should match return value");
  }
  function testBuyToken() public {
     basicToken.buyToken.value(10**17);
     uint _balance = basicToken.balanceOf(contractAddress);
     Assert.notEqual(0, _balance, "Balance should no longer be 0");
  }
}

基本令牌.sol

pragma solidity ^0.5.3;

contract BasicToken {
  uint MAX_SUPPLY = 1000;
  uint OWNER_SUPPLY = 300;
  uint CIRCULATING_SUPPLY = 0;

  address payable public BASIC_TOKEN_ETH_WALLET;
  uint TOKEN_PRICE;

  mapping(address => mapping(address => uint)) APPROVED;
  mapping(address => uint) BALANCES;

  event SupplyChangeEvent(uint NewBalance, uint NewSupply);

  constructor(address payable eth_wallet) public {
     BASIC_TOKEN_ETH_WALLET = eth_wallet;
     BALANCES[BASIC_TOKEN_ETH_WALLET] = OWNER_SUPPLY;
  }

  //********************ERC20 TOKEN FUNCTIONS********************************
  function totalSupply() public view returns(uint _total_supply) {
     return CIRCULATING_SUPPLY;
  }
  function balanceOf(address _owner) public view returns (uint balance){
     return BALANCES[_owner];  
  }
  function transfer(address _to, uint _value) public returns (bool success){

     if( _value < 0 || _value > BALANCES[msg.sender]) return false;

     BALANCES[msg.sender] -= _value;
     BALANCES[_to] += _value;

     return true;
  }
  function approve(address _spender, uint _value) public returns (bool success) {
     if( _value <= 0 || _value > BALANCES[msg.sender]) return false;

     APPROVED[msg.sender][_spender] = _value;

     return true;
  }
  function allowance(address _owner, address _spender) public view returns(uint remaining){
     return APPROVED[_owner][_spender];
  }
  function transferFrom(address _from, address _to, uint _value) public returns (bool success){
     if(_value <= 0 || _value > allowance(_from, msg.sender) || _value > BALANCES[_from])
        return false;

     BALANCES[_from] -= _value;
     APPROVED[_from][msg.sender] -= _value;
     BALANCES[_to] += _value;

     return true;
  }
  //****************************************************************************
  function buyToken() public payable{
     CIRCULATING_SUPPLY += 1;
     BALANCES[msg.sender] += 1;
     emit SupplyChangeEvent(BALANCES[msg.sender], CIRCULATING_SUPPLY);
     /*
     uint tokenAmount = (msg.value)/(10**17);
     uint returningValue = 0;
     uint availableSupply = MAX_SUPPLY - CIRCULATING_SUPPLY - OWNER_SUPPLY;
     if(tokenAmount > availableSupply){
        tokenAmount = availableSupply;
        returningValue = msg.value - tokenAmount * 10**17;
     }

     msg.sender.transfer(returningValue);
     BASIC_TOKEN_ETH_WALLET.transfer(msg.value - returningValue);
     BALANCES[msg.sender] += 1;
     CIRCULATING_SUPPLY += tokenAmount;
    */
  }
}

執行的輸出truffle test

2 passing (5s)   1 failing

 1) TestBasicToken
      testBuyToken:
    Error: Balance should no longer be 0 (Tested: 0, Against: 0)
     at /usr/lib/node_modules/truffle/build/webpack:/packages/core/lib/testing/soliditytest.js:71:1
     at Array.forEach (<anonymous>)
     at processResult (/usr/lib/node_modules/truffle/build/webpack:/packages/core/lib/testing/soliditytest.js:69:1)
     at runMicrotasks (<anonymous>)
     at processTicksAndRejections (internal/process/task_queues.js:93:5)

tl;博士:你的行應該是:

basicToken.buyToken.value(10**17)();

解釋:basicToken.buyToken.value(10**17);看起來您正在呼叫該buyToken函式,但它沒有呼叫它。.value事情是一個函式呼叫修飾符。所以當你這樣做時buyToken.value(10**17),你要問的是請通過傳遞值來修改我的函式呼叫。之後,您需要真正呼叫該函式。所以添加().

引用自:https://ethereum.stackexchange.com/questions/76969