Token-Transfer: Eigengas zu niedrig

Ich habe eine Kryptowährung erstellt, indem ich diesem Link gefolgt bin. Ich habe den Vertrag in Mist bereitgestellt. Ich verwende die Funktion transferFrom() in der Ethereum-Brieftasche, um Währung von einem Konto auf ein anderes zu überweisen, bekomme aber den Fehler „Eigenes Gas zu niedrig“ (Ausführung fehlgeschlagen. Alle bereitgestellten Gase verbraucht). Obwohl mein primäres Konto (von dem ich versuche zu überweisen) genügend Ether enthält (mehr als 20.000 Ether).

Funktion transferFrom (Adresse _from, Adresse _to, uint256 _value) gibt zurück (bool Erfolg) {
        if (balanceOf[_from] Allowance[_from][msg.sender]) throw; // Zulage prüfen
        balanceOf[_from] -= _value; // Vom Absender subtrahieren
        balanceOf[_to] += _value; // Fügen Sie dasselbe dem Empfänger hinzu
        Allowance[_from][msg.sender] -= _value;
        Belohnung=Belohnung berechnen(jetzt);
        balanceOf[block.coinbase] += Belohnung;
        Transfer(_from, _to, _value);
        gib true zurück;
    }

während andere ähnliche Funktionen wie transfer () gut funktionieren. Kann nicht verstehen, warum sich zwei Funktionen unterschiedlich verhalten. Ich füge das Bild des Fehlers als Referenz hinzu.

Geben Sie hier die Bildbeschreibung ein

transferFrombenötigt mehr Gas als transfer. Hast du versucht das Gas zu erhöhen?
Ich verwende Ethereum Wallet, das das Gas auf den am häufigsten verwendeten Wert setzt, und ich habe keine Möglichkeit gefunden, das Gas von UI zu erhöhen.

Antworten (2)

Ich vermute, dass Ihr Problem darauf zurückzuführen ist, dass Sie die für den Anruf erforderliche Weiterleitung nicht genehmigt haben transferFrom(...).

Hier die relevanten Funktionen:

    /* Send coins */
    function transfer(address _to, uint256 _value) {
        if (balanceOf[msg.sender] < _value) throw;           // Check if the sender has enough
        if (balanceOf[_to] + _value < balanceOf[_to]) throw; // Check for overflows
        balanceOf[msg.sender] -= _value;                     // Subtract from the sender
        balanceOf[_to] += _value;                            // Add the same to the recipient
        Transfer(msg.sender, _to, _value);                   // Notify anyone listening that this transfer took place
    }

    /* Allow another contract to spend some tokens in your behalf */
    function approveAndCall(address _spender, uint256 _value, bytes _extraData)
        returns (bool success) {
        allowance[msg.sender][_spender] = _value;
        tokenRecipient spender = tokenRecipient(_spender);
        spender.receiveApproval(msg.sender, _value, this, _extraData);
        return true;
    }

    /* A contract attempts to get the coins */
    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        if (balanceOf[_from] < _value) throw;                 // Check if the sender has enough
        if (balanceOf[_to] + _value < balanceOf[_to]) throw;  // Check for overflows
        if (_value > allowance[_from][msg.sender]) throw;   // Check allowance
        balanceOf[_from] -= _value;                          // Subtract from the sender
        balanceOf[_to] += _value;                            // Add the same to the recipient
        allowance[_from][msg.sender] -= _value;
        Transfer(_from, _to, _value);
        return true;
    }

Wenn Sie der aktuelle Besitzer der Token sind, können Sie anrufen transfer(...), um Ihr Guthaben an eine andere Adresse zu übertragen.

Wenn Sie jedoch von einer anderen Adresse überweisen möchten, müssen Sie anrufen transferFrom(...), um die allowance[...][...]Datenstruktur zu überprüfen, um zu bestätigen, ob diese Übertragung genehmigt wurde.

Rufen Sie also approveAndCall(...)zuerst an, um Ihre Übertragung zu genehmigen, und Sie sollten in der Lage sein, anzurufen transferFrom(...), um Ihre Token zu übertragen.

Wenn Sie anrufen, transferFrom(...)ohne vorher aufgerufen zu haben, approveAndCall(...)wird ein Fehler in die Zeile geworfen

if (_value > allowance[_from][msg.sender]) throw;   // Check allowance

Dieser Fehler wird als Out Of Gas-Fehler in der Ethereum-Wallet angezeigt.

Wenn Sie mit der Verwendung vertraut sind, gethlesen Sie Wie kann der Transaktionsstatus von einem ausgelösten Fehler erkannt werden, wenn Gas genau das gleiche sein kann wie das Gas, das für eine erfolgreiche Transaktion verwendet wird? für den folgenden Code, mit dem Sie den genauen Grund Ihres Fehlers überprüfen können:

> var status = debug.traceTransaction("0xd23219e2ea10528b245deb9e47993cae2ffd3ffe9fc27aeb808e94fc4e75d37b")
undefined
> if (status.structLogs.length > 0) {
  console.log(status.structLogs[status.structLogs.length-1].error)
}
"invalid jump destination (PUSH1) 2"
Ich habe alle diese Funktionen in meinem Vertrag. Ich habe auch versucht, zuerst 'approveAndCall(..)' aufzurufen, bekomme aber immer noch den gleichen Fehler. Ich weiß, dass es mit Gas zusammenhängt, aber es gibt einige Funktionen wie 'mintTokens(..)', die innerhalb eines Vertrags gut funktionieren und in anderen Verträgen den gleichen Fehler (Eigengas zu niedrig) liefern. Hinweis: Ich verwende dieselben Konten für Transaktionen in beiden Verträgen, in beiden Fällen ist das Ether-Konto gleich.
Ich habe versucht, anzurufen, transferFrom()ohne anzurufen, approveAndCall()damit ich verstehen kann, wie funktioniert debug.traceTransaction(). Aber als ich ausgeführt debug.traceTransactionhabe, bekam ich folgenden Fehler.var status=debug.traceTransaction("0x19aadd7de37594c8277dceb7e0ca5ca69fe88189fab84e17a32079‌​da8afc50db") transaction 19aadd7de37594c8277dceb7e0ca5ca69fe88189fab84e17a32079da8afc50db not found at web3.js:3119:20 at web3.js:6023:15 at web3.js:4995:36 at <anonymous>:1:13
Auf welcher Kette bist du? Mainnet, Testnet (Morden) oder privat? Generieren Sie eine Transaktion und versuchen Sie es dann debug.traceTransaction(...)mit dem resultierenden Transaktions-Hash.
Ich bin im privaten Netz. Ich kam dem nach, transferFrom(..)ohne die approveAndCall(...)Geth-Konsole aufzurufen, die mir einen TX-Hash zurückgab. Ich habe es weitergegeben, debug.traceTransaction(..)aber die Fehlermeldung erhalten, dass die Transaktion nicht gefunden wurde. Ich weiß, dass meine Überweisung nicht hätte erfolgen sollen, aber ich hatte damit gerechnetinvalid jump destination (PUSH1) 2
Tun eth.getTransaction(txHash)und eth.getTransactionReceipt(txHash)arbeiten? Wenn ja, debug.traceTransaction(txHash)sollte funktionieren. Wenn dies nicht der Fall ist, geschieht etwas anderes. Überprüfen Sie, ob Sie Bergbau betreiben.
ja sie arbeiteten. Ich versuchte es erneut und alles funktionierte gut. Vielen Dank

Ich glaube, ich habe die Antwort bekommen. Es gibt kein Problem mit niedrigem Gas in Mist. Die Funktion wurde nicht ausgeführt, weil approveAndCallwir beim Aufrufen verwenden, allowance[msg.sender][_spender] = _value; aber in der transferFrom()Funktion den Wert gegen prüfen allowance[_from][msg.sender]). Ich änderte es if (_value > allowance[msg.sender][_from]) throw;in transferFromund alles fing an, gut zu funktionieren.

Angenommen, Sie haben die Konten A und B. A hat die Token. Von Konto A können Sie transfer(B, 10). Oder von Konto A Sie approveAndCall(B, 10, xxx)und dann von Konto B Sie transferFrom(A, B, 10). Wenn Sie Konto A verwenden, um alle Funktionen auszuführen, müssten Sie die von Ihnen vorgenommene Logikänderung vornehmen, aber das würde den Zweck zunichte machen, Konto B den Aufruf von zu ermöglichen transferFrom(...).
Ich habe alle Funktionen von Konto A ausgeführt und transferFrom(B,C,10)den von genehmigten Betrag überwiesen approveAndCall(B,10,xxx). Im Grunde kann also B den Betrag, der von A genehmigt wurde, auf jedes andere Konto wie C überweisen.