Local-Variables

從其他solidity文件訪問變數時出錯

  • January 18, 2019

當我呼叫 testToken 文件中的 getVal 函式時出現錯誤。EVM 向我返回以下資訊:

呼叫 testCoin.getVal 出錯:VM 錯誤:還原。

revert 事務已恢復到初始狀態。

注意:如果您發送值,則應支付建構子。

pragma solidity ^0.4.24;

library SafeMath {
function mul(uint256 a, uint256 b) internal constant returns (uint256) {
   uint256 c = a * b;
   assert(a == 0 || c / a == b);
   return c;
}

function div(uint256 a, uint256 b) internal constant returns (uint256) {
   assert(b > 0); // Solidity automatically throws when dividing by 0
   uint256 c = a / b;
   assert(a == b * c + a % b); // There is no case in which this doesn't hold
   return c;
}

function sub(uint256 a, uint256 b) internal constant returns (uint256) {
   assert(b <= a);
   return a - b;
}

function add(uint256 a, uint256 b) internal constant returns (uint256) {
   uint256 c = a + b;
   assert(c >= a);
   return c;
}
}

// ERC20 Token Smart Contract
contract MyToken {
   
   string public constant name = "MyToken";
   string public constant symbol = "MYT";
   uint8 public constant decimals = 0;
   uint public _totalSupply = 1000000;
   uint256 public RATE = 1;
   bool public isMinting = false;
   
   using SafeMath for uint256;
   address public owner;
   
    // Functions with this modifier can only be executed by the owner
    modifier onlyOwner() {
       if (msg.sender != owner) {
           throw;
       }
        _;
    }

   // Balances for each account
   mapping(address => uint256) balances;
   // Owner of account approves the transfer of an amount to another account
   mapping(address => mapping(address=>uint256)) allowed;
   
   // Constructor
   constructor() public {
       owner = msg.sender; 
       balances[owner] = _totalSupply;
   }

   //allows owner to burn tokens that are not sold in a crowdsale
   function burnTokens(uint256 _value) onlyOwner {

        require(balances[msg.sender] >= _value && _value > 0 );
        _totalSupply = _totalSupply.sub(_value);
        balances[msg.sender] = balances[msg.sender].sub(_value);
        
   }
   
   
   function createTokens(uint newTokens){
       if(isMinting == true){
           require(newTokens > 0);
           balances[msg.sender] = balances[msg.sender].add(newTokens);
           _totalSupply = _totalSupply.add(newTokens);
       }
       else{
           throw;
       }
   }
   
   function endCrowdsale() onlyOwner {
       isMinting = false;
   }
   
   function startCrowdsale() onlyOwner{
       isMinting = true;
   }

   /*function changeCrowdsaleRate(uint256 _value) onlyOwner {
       RATE = _value;
   }*/

   
   function totalSupply() constant returns(uint256){
       return _totalSupply;
   }
   
   // What is the balance of a particular account?
   function balanceOf(address _owner) constant returns(uint256){
       return balances[_owner];
   }

    // Transfer the balance from owner's account to another account   
   function transfer(address _to, uint256 _value)  returns(bool) {
       require(balances[msg.sender] >= _value && _value > 0 );
       balances[msg.sender] = balances[msg.sender].sub(_value);
       balances[_to] = balances[_to].add(_value);
       Transfer(msg.sender, _to, _value);
       return true;
   }
   
// Send _value amount of tokens from address _from to address _to
// The transferFrom method is used for a withdraw workflow, allowing contracts to send
// tokens on your behalf, for example to "deposit" to a contract address and/or to charge
// fees in sub-currencies; the command should fail unless the _from account has
// deliberately authorized the sender of the message via some mechanism; we propose
// these standardized APIs for approval:
function transferFrom(address _from, address _to, uint256 _value)  returns(bool) {
   require(allowed[_from][msg.sender] >= _value && balances[_from] >= _value && _value > 0);
   balances[_from] = balances[_from].sub(_value);
   balances[_to] = balances[_to].add(_value);
   allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
   Transfer(_from, _to, _value);
   return true;
}

// Allow _spender to withdraw from your account, multiple times, up to the _value amount.
// If this function is called again it overwrites the current allowance with _value.
function approve(address _spender, uint256 _value) returns(bool){
   allowed[msg.sender][_spender] = _value; 
   Approval(msg.sender, _spender, _value);
   return true;
}

// Returns the amount which _spender is still allowed to withdraw from _owner
function allowance(address _owner, address _spender) constant returns(uint256){
   return allowed[_owner][_spender];
}

event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}




pragma solidity ^0.4.24;

import './MyToken.sol';

contract testCoin {

   MyToken token;

   function getVal() constant public returns (uint256) {
   return token._totalSupply();
   }
}

我刪除了對應付函式的呼叫。但鋼鐵出現

編輯:

我做了一個簡單的例子,但問題仍然存在。

pragma solidity ^0.4.24;

contract Value {
   
   uint public testValue = 321;
   
}

pragma solidity ^0.4.24;

import './value.sol';


contract testCoin {

Value value;

function getVal() view public returns (uint){
   return value.testValue();
}
}

在後一個範例中,“值”是一個空指針。你不初始化它。

分配給它適當的價值,一切都完美無瑕。

最簡單的方法是讓建構子傳遞另一個合約的地址:

constructor (address _DeployedContract) public {
value = Value(_DeployedContract);
}

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