ERC-20-Transfer Von einem möglichen Fehler bei der Implementierung … oder nicht?

Nehmen wir an, die transferFromFunktion wird auf folgende Weise implementiert:

function transferFrom (address _from, address _to, uint256 _value)
public returns (bool success) {
   uint256 spenderAllowance = allowances [_from][msg.sender];
   if (spenderAllowance < _value) return false;
   uint256 fromBalance = accounts [_from];
   if (fromBalance < _value) return false;

   allowances [_from][msg.sender] = safeSub (spenderAllowance, _value);

   if (_value > 0 && _from != _to) {
     accounts [_from] = safeSub (fromBalance, _value);
     accounts [_to] = safeAdd (accounts [_to], _value);
   }
   Transfer (_from, _to, _value);
   return true;
}

Wie ich es sehe, wenn _toes anders ist als msg.senderals _to, werden alle Tokens erhalten, die von msg.senderder zulässigen Menge entfernt werden.

Dies sollte praktisch nicht der Fehler sein, denn niemand ist verrückt genug, um seinen erlaubten Betrag an jemand anderen zu senden, aber kann er auf schlechte Weise verwendet werden? Was sind Ihre Gedanken dazu?

Es gibt einen bekannten Angriff zum Genehmigen/ÜbertragenVon, wenn der Absender nicht aufpasst github.com/ethereum/EIPs/issues/738 . Es gab einige schlechte ERC20-Implementierungen, die angegriffen wurden, aber ansonsten hat die Logik den Test der Zeit bestanden. Es hat seine eigenen Einschränkungen und es wurden andere Alternativen wie ERC223 vorgestellt.

Antworten (3)

Der transferFrom-Fluss ist irgendwie definiert als:

// Send `tokens` 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, uint tokens) public returns (bool success) {
    balances[_from] = balances[_from].sub(tokens);
    allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(tokens);
    balances[_to] = balances[_to].add(tokens);
    Transfer(_from, _to, tokens);
    return true;
}

Wie Sie sehen können, besteht das Ziel darin, jedem msg.sender , der dies zuvor genehmigt hat (natürlich von _from ), zu erlauben, Token von einem _from- Konto auf ein beliebiges _to - Konto zu übertragen, das er möchte.

Msg.sender zahlt sowohl in Form von Zertifikaten als auch in Form von Gas für die Transaktion.

Es gibt also keinen Platz für Tricks: msg.sender zahlt Benzin und Taschengeld, _from gibt einige genehmigte Token aus, _to erhält die von msg.sender gesendeten Token .

Falls wir diese Art von Funktion nicht haben können, sollte msg.sender Token zuerst auf sein eigenes Konto übertragen (Transaktion auf Blockchain Nr. 1) und sie dann an _to Account senden (Transaktion auf Blockchain Nr. 2). . Also zahlt msg.sender sein Taschengeld UND zweimal das Gas für die Transaktion.

Dies kann durch den transferFrom-Mechanismus vermieden werden, der dies nur mithilfe einer Blockchain-Transaktion tun kann und für msg.sender billiger durchzuführen ist.

Das Verhalten ist beabsichtigt. Die Idee der Übertragung von ist, dass ein Benutzer einem anderen Benutzer erlaubt, Token zu verschieben. Der berechtigte Benutzer kann jedoch tun, was er möchte, dh es an sein eigenes Konto senden oder an jemand anderen senden.

Ich denke, Ihre Hauptannahme, dass "niemand verrückt genug ist, seinen erlaubten Betrag an jemand anderen zu senden", ist nicht wahr. In Fällen, in denen Sie Token als Zahlungsmittel an einen anderen Vertrag senden möchten, wird der Vertrag die Token-Übertragung nicht bemerken, also tun Sie dies approveAndCall, dann wird der Zielvertrag dies tun transferFromund er könnte die Token (zum Beispiel) an den senden Eigentümer dieses Vertrags (ein Konto im externen Besitz). So trasnferFromist es nützlich, wie es ist.

Hoffe das hilft.

Lassen Sie mich allgemein antworten.

ERC20 ist nur ein Standard und kann als Schnittstelle betrachtet werden. Eine Schnittstelle sagt nichts über die eigentliche Implementierung aus.

Es steht Ihnen also frei, beliebige Fehler in einer ERC20-Funktion zu codieren. Es gibt Beispielimplementierungen, die normalerweise sicher sind und das tun, was von der Funktion erwartet wird , aber Sie müssen diese Implementierungen nicht verwenden, um vollständig ERC20-konform zu sein. Ihr Token kann mit der dümmsten vorstellbaren Implementierung vollständig ERC20-konform sein, solange die Funktionssignaturen korrekt sind.

Wie Sie sagten, allgemeine Antwort, beantwortet meine Frage also nicht ganz. Dies ist nicht mein Code und ich bin nur gespannt, ob dieser ausgenutzt werden kann. Aber Sie haben Platz für die nächste Frage gemacht ... warum gibt es überhaupt einen _to-Parameter? Kennen Sie vielleicht einen Hinweis auf eine Diskussion zu diesem Thema, bevor der ERC-20 angenommen wurde?
Schauen Sie sich die Kommentare zur Implementierung unter theethereum.wiki/w/index.php/ERC20_Token_Standard an
Ja, richtig, ich habe es verstanden. Ich musste diese Seite nur sorgfältig lesen, anstatt eine Frage zu schreiben, aber ich hoffe, es wird jemandem helfen :)