Solidity
來自另一個合約的 ERC-20 合約
我正在嘗試創建可以訪問任何 ERC-20 標準代幣合約功能的合約。首先,我想獲得給定地址的餘額。
我使用 geth 執行私有測試網,我已經部署了以下令牌合約:
pragma solidity ^0.4.16; interface tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) external; } contract TokenERC20 { string public name; string public symbol; uint8 public decimals = 18; uint256 public totalSupply; mapping (address => uint256) public balanceOf; mapping (address => mapping (address => uint256)) public allowance; event Transfer(address indexed from, address indexed to, uint256 value); event Burn(address indexed from, uint256 value); constructor(uint256 initialSupply, string tokenName, string tokenSymbol) public { totalSupply = initialSupply; balanceOf[msg.sender] = totalSupply; name = tokenName; symbol = tokenSymbol; } function _transfer(address _from, address _to, uint _value) internal { require(_to != 0x0); require(balanceOf[_from] >= _value); require(balanceOf[_to] + _value >= balanceOf[_to]); uint previousBalances = balanceOf[_from] + balanceOf[_to]; balanceOf[_from] -= _value; balanceOf[_to] += _value; emit Transfer(_from, _to, _value); assert(balanceOf[_from] + balanceOf[_to] == previousBalances); } function transfer(address _to, uint256 _value) public { _transfer(msg.sender, _to, _value); } function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) { require(_value <= allowance[_from][msg.sender]); allowance[_from][msg.sender] -= _value; _transfer(_from, _to, _value); return true; } function approve(address _spender, uint256 _value) public returns (bool success) { allowance[msg.sender][_spender] = _value; return true; } function approveAndCall(address _spender, uint256 _value, bytes _extraData) public returns (bool success) { tokenRecipient spender = tokenRecipient(_spender); if (approve(_spender, _value)) { spender.receiveApproval(msg.sender, _value, this, _extraData); return true; } } function burn(uint256 _value) public returns (bool success) { require(balanceOf[msg.sender] >= _value); balanceOf[msg.sender] -= _value; totalSupply -= _value; emit Burn(msg.sender, _value); return true; } function burnFrom(address _from, uint256 _value) public returns (bool success) { require(_value <= allowance[_from][msg.sender]); require(balanceOf[_from] >= _value); balanceOf[_from] -= _value; allowance[_from][msg.sender] -= _value; totalSupply -= _value; emit Burn(_from, _value); return true; } function () public payable { revert(); } }
一切正常,我在 geth 上成功測試了它。
然後我創建了以下契約:
pragma solidity ^0.4.16; contract ERC20 { function totalSupply() constant returns (uint256 totalSupply); function balanceOf(address _owner) constant returns (uint256 balance); function transfer(address _to, uint _value); event Transfer(address indexed _from, address indexed _to, uint _value); } contract TokenChecker { address private senderAddress; address private tokenAddress; constructor(address _tokenAddress) public { senderAddress = msg.sender; tokenAddress = _tokenAddress; } function bal(address _address) public constant returns (uint256 balance) { ERC20 token = ERC20(tokenAddress); return token.balanceOf(_address); } function getThis() public constant returns (address thisAddress) { return address(this); } function tokenAdrs() public constant returns (address adrs) { return tokenAddress; } function () public payable { revert(); } }
這個是使用這個 JavaScript 部署的:
var tokenCheckerFactory = eth.contract(COMPILED_WITH_SOLC_ABI) var tokenCheckerCompiled = "0xCOMPILED_WITH_SOLC_BIN" var _tokenAddress = "DEPLOYED_TokenERC20_ADDRESS" var tokenChecker = tokenCheckerFactory.new(_tokenAddress, {from:eth.accounts[0],data:tokenCheckerCompiled,gas:2000000}, function(e, contract){ if(e) { console.error(e); // If something goes wrong, at least we'll know. return; } if(!contract.address) { console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined..."); } else { console.log("Contract mined! Address: " + contract.address); console.log(contract); } })
在 geth 中,
getThis()
並且沒問題,但是任何參數tokenAdrs()
總是返回 0 :bal()
// geth console > token.balanceOf(eth.accounts[0]) // instance of TokenERC20 2.0999984e+25 > tokenChecker.bal(eth.accounts[0]) 0 >
我的程式碼有什麼問題?為什麼 TokenChecker 不能與提供的 ERC-20 合約互動?通過給定這樣的合約地址,它甚至可以與隨機的 ERC-20 代幣進行通信嗎?先感謝您。
**編輯:**當我省略
constant
at 時bal()
,送出新事務,沒有任何內容返回到控制台。當我開始挖礦時,沒有什麼特別的事情發生,只顯示關於挖礦的資訊。並且也view
總是返回 0。
也許是因為 bal 設置為常數?https://solidity.readthedocs.io/en/v0.4.21/contracts.html?highlight=constant#constant-state-variables
function balanceOf(address _owner) constant returns (uint256 balance);
是問題我認為你必須使用如下:
function balanceOf(address _owner) public view returns (uint256);