ERC-20-Vertrag aus einem anderen Vertrag

Ich versuche, einen Vertrag zu erstellen, der auf Funktionen jedes ERC-20-Standard-Token-Vertrags zugreifen kann. Zuerst möchte ich das Gleichgewicht der angegebenen Adresse erhalten.

Ich betreibe ein privates Testnetz mit Geth und habe folgenden Token-Vertrag bereitgestellt:

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();
}

}

Alles funktioniert gut, ich habe es auf geth erfolgreich getestet.

Dann habe ich folgenden Vertrag erstellt:

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();
}
}

Dieser wurde mit diesem JavaScript bereitgestellt:

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);
}
})

In Geth getThis()und tokenAdrs()sind OK, aber es wird immer 0 bal()mit jedem Argument zurückgegeben:

// geth console
> token.balanceOf(eth.accounts[0]) // instance of TokenERC20
2.0999984e+25
> tokenChecker.bal(eth.accounts[0])
0
> 

Was ist falsch an meinem Code? Warum kann TokenChecker nicht mit dem bereitgestellten ERC-20-Vertrag interagieren? Könnte es sogar mit einem zufälligen ERC-20-Token kommunizieren, indem es seine Vertragsadresse wie folgt angibt? Vielen Dank im Voraus.

Bearbeiten: Wenn ich constantbei weglasse bal(), wird eine neue Transaktion übermittelt, nichts wird an die Konsole zurückgegeben. Wenn ich mit dem Mining beginne, passiert nichts Besonderes, es werden nur Informationen zum Mining angezeigt. Und viewgibt auch immer 0 zurück.

Ich sehe, dass dies in Ihrem Code definiert ist: ^0.4.16;Sie verwenden jedoch Funktionen, die nach dieser Version eingeführt wurden. Sagen Sie nicht, dass dies Ihre Lösung ist, sondern notieren Sie es als Referenz. Das Schlüsselwort constructorwurde in 0.4.22 (2018-04-16) github.com/ethereum/solidity/blob/develop/Changelog.md eingeführt
Ich habe Ihren Code kopiert und zum Testen über die JS VM in Remix eingefügt. Sie bal()haben gearbeitet und den richtigen Wert zurückgegeben. Ich würde annehmen, dass das Problem bei Ihrem JS-Code liegt, nicht bei Solidity. .
@MSwezey Ja, das ist meine Lösung, ich bin Neuling in Sachen Solidität. Ich habe die Version geändert und immer noch nichts. Der Konstruktor funktioniert, denn wenn ich ein Argument übergebe, es im Konstruktor speichere und es von einer Funktion zurückgebe, wird die übergebene Adresse angezeigt. Ich denke, dass der Fehler bei der Instanziierung von ERC20 liegt. Ich habe versucht, eine Instanz im Konstruktor zu erstellen, function tokenSupply() public constant returns (uint256 totalSupply) { return token.totalSupply(); }und es wird auch 0 zurückgegeben, als ob die Instanz von ERC20 nicht existierte.

Antworten (2)

Wenn ich weglasse constant, wird eine neue Transaktion übermittelt, nichts wird an die Konsole zurückgegeben. Wenn ich mit dem Mining beginne, passiert nichts Besonderes, es werden nur Informationen zum Mining angezeigt.
Und viewgibt auch immer 0 zurück.

function balanceOf(address _owner) constant returns (uint256 balance);ist das Problem

Ich denke, Sie müssen wie folgt verwenden:function balanceOf(address _owner) public view returns (uint256);