Local-Variables
從其他solidity文件訪問變數時出錯
當我呼叫 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); }