Wie das ERC20-Token-Guthaben während des Zurückrollens der Ethereum-Kette wiederhergestellt wird

Meine Antwort:

Ok, das Problem liegt wirklich bei Ganache ... Wenn ich Geth verwende, ist alles in Ordnung.

... ... Entschuldigung für Ihre Zeit ...

----------- Die Ausgangsfrage --------------------

Meines Wissens nach werden ERC20-Token-Guthaben im Speicher gespeichert , die sich im Laufe der Zeit ändern werden. Außerdem token.balanceOf(accountHash, {}, blockNumber)scheint nur der letzte Kontostand zurückgegeben zu werden, egal was das blockNumberist. Ich frage mich, ob die Ethereum-Kette zurückrollt und dann entlang einer neuen Kette wächst, wie werden ERC20-Token-Guthaben behandelt?

Ich möchte das hier etwas klarstellen Rollback. Stellen Sie sich eine vereinfachte Kette mit nur 8 Blöcken vor, die durch die Reihenfolge gekennzeichnet sind, in der sie an die Kette angehängt werden (nicht die Blocknummer, die die Höhe des Blocks definiert).

# blocks are labeled by the order they are added to the chain
               /--[6]<--[7]<--[8]
              /
[1]<--[2]<--[3]<--[4]<--[5]

Angenommen, in all diesen Blöcken gibt es Transaktionen über einen Token (ERC20).

Wenn [5]zur Kette hinzugefügt wird, befindet es sich in der längsten Kette und token.balanceOf['0xAA']gibt mir balance1.

Nehmen wir nun an , [6][7][8]dass an angehängt werden [3], dieser Zweig wird der längste und alle Transaktionen in [4]und [5]werden ungültig.

Nehmen wir nun an, ich möchte sicher sein, also kümmere ich mich nur um das Gleichgewicht eines ERC20-Tokens (nicht ETH) im (N-4)-ten Block. Wie bekomme ich dieses Gleichgewicht.

Ich habe meine Suche durchgeführt und die einzige Möglichkeit besteht darin, die API von Etherscan zu verwenden, die für eine starke Nutzung nicht in Ordnung ist. Es gibt hier und da andere Leute, die ähnliche Fragen stellen, und ich spüre ihre Frustration total.

Danke schön.


Update am 5.4.

Ich möchte mehr Details über meine bisherigen Versuche geben.

1) Ich verwende Ubuntu 16.04 und Geth 1.8.2-stable.

2) Ich begann mit dem Ausführen von Ganache, der App mit grafischer Benutzeroberfläche.

3) Mein Token ist fast derselbe wie der im offiziellen Dokument https://ethereum.org/token .

4) Ich habe das Token mit eth.accounts[0]in Geth bereitgestellt (Ganache generiert 10 Konten mit jeweils 100 anfänglichen ETH für mich)

$ geth attach http://localhost:8545

var tokenABI = [...];
var tokenFactory = eth.conract(tokenABI);
var byteCode = "0x" + "606..."

var token = tokenFactory.new(
    100,
    "TestCoin",
    "TSC",
    {
        from: eth.accounts[0],  // owner
        data: byteCode,
        gas: 4700000
    }, function(e, contract) {});

5) Ich habe die folgenden Transaktionen durchgeführt:

// 3 ETH transactions
eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(5, "ether") });
eth.sendTransaction({from: eth.accounts[1], to: eth.accounts[2], value: web3.toWei(3, "ether") });
eth.sendTransaction({from: eth.accounts[2], to: eth.accounts[3], value: web3.toWei(1, "ether") });

// 3 token transfers
token.transfer(eth.accounts[1], web3.toWei(5, 'ether'), { from: eth.accounts[0] }, function(err, contract) {})
token.transfer(eth.accounts[2], web3.toWei(3, 'ether'), { from: eth.accounts[1] })
token.transfer(eth.accounts[3], web3.toWei(1, 'ether'), { from: eth.accounts[2] })

Für den Token erwarte ich das Endguthaben

account 0: 95
account 1: 2
account 2: 2
account 3: 1

Meine eth.blockNumberzeigt 7 Blöcke, was korrekt ist (3 Eth-Transfer, 1 Vertragserstellung, 3 Token-Transfer). Jeder Saldo von Konto 3 ist definitiv kleiner als 1 in früheren Blöcken. Der folgende Befehl gibt jedoch 1 Ether (in der Einheit von Wei) für mich zurück:

> token.balanceOf(eth.accounts[3], 0, function(err, res) {console.log(err, res};)
null 1000000000000000000
undefined

Egal wie ich diese Zahl ändere, von 0 bis 7, ich bekomme immer die gleiche Ausgabe.

Übrigens habe ich keine Probleme, ETH-Bestände in früheren Blöcken abzurufen. Dies geschieht nur mit dem Token. Eine Sache, die mir aufgefallen ist, ist, dass meine eth.syncingRenditen false, vielleicht weil ich Ganache verwende?

Wenn die Ethereum-Kette zurückrollt, wird der vorherige Speicher wiederhergestellt. Nehmen wir an, wir sind bei Block 100 und jemand kauft 30 Token von Token A, jetzt hat er 40 Token. Anscheinend ist diese Kette ein Fork - wir wollen zu Block 99 zurückkehren, also tun wir das. Jetzt hat diese Person 10 A-Token, ihre vorherige ETH ist immer noch ihre alte Menge an ETH und ihre Transaktion ist immer noch in der Warteschlange (abhängig davon, ob der neue Fork seine Transaktion abgebaut hat oder nicht). TL;DR beim Rollback stellen wir eine alte Version der vollständigen Blockchain wieder her.
Habe noch nie von rollbackBlockchains gehört. Sie beziehen sich möglicherweise auf Chain Split, wenn jemand 2 Gabeln einer Kette von Blöcken abbaut. Die längere Kette gewinnt, und der Knoten löscht einfach die kürzeste Kette und wechselt zur längsten Kette. Token sind Variablen im Zustand , also werden die Variablen auf der längsten Kette gewählt, das war's.
@MathematicalRain Ich verstehe, wie ETH wiederhergestellt wird. Ich spreche hier von den ERC20-Token, die Guthaben im Smart Contract als Mapping speichern.
Wo hast du das gefunden token.balanceOf(accountHash, {}, blockNumber)? Es macht für mich keinen Sinn, dass diese Funktion on-chain existieren sollte. Außerdem wird der gesamte Speicher zurückgesetzt, wenn die Kette gegabelt wird; also Zuordnungen auch. Ethereum-Ketten-Rollbacks sollten niemals passieren, dies ruiniert die gesamte Idee hinter Ethereum, da jetzt eine zentralisierte Organisation wählen kann, eine „Hard-Fork“ der gesamten Kette durchzuführen.
@MathematicalRain vielleicht formuliere ich es nicht richtig. aber alles, was ich will, ist, den ERC20-Token-Saldo einer Adresse in einem bestimmten Block zu finden . Ist das möglich? Für diese balanceOfFunktion habe ich es hier gelesen ethereum.stackexchange.com/questions/42783/…
@MathematicalRain Ich habe meine Frage aktualisiert. Hoffe ich habe mich etwas klarer ausgedrückt.

Antworten (1)

Lassen Sie uns dieses Rollback zuerst klären. In dem von Ihnen angegebenen Beispiel werden der Kette zwei Blöcke (4 und 5) hinzugefügt. Es wird aber auch eine separate Kette geschürft, die (6,7,8) macht und damit die Kette mit 4 und 5 übernimmt. Bei normaler Funktion des Netzwerks kann es vorkommen, dass zwei Miner ungefähr zur gleichen Zeit einen Block erstellen und senden sie im Netzwerk. An diesem Punkt ist unklar, was der „echte“ Block ist, und wir befinden uns somit in einer Verzweigung des Netzwerks.

Im bereitgestellten Beispiel wird ein weiterer Block 5 hinzugefügt, aber plötzlich hat ein Miner 5,6 und 7 generiert und veröffentlicht diese, was nun die längste Kette ist. Dies impliziert, dass dieser Miner >50 % der Netzwerk-Hashrate hat. Aufgrund von „Glück“ kann dies jedoch manchmal passieren, und wenn Sie möchten, dass Ihre Transaktionen sicher überprüft werden, müssen Sie einige Blöcke warten, bevor Sie diese Transaktion „echt“ bestätigen. (Als ob Sie jemandem ETH schicken, 10 Blocks warten und an diesem Punkt ist es für "böse Bergleute" wirklich schwer, wieder abzuholen).

Nun die zweite Frage, die im Grunde darauf hinausläuft, "wie kann ich das Gleichgewicht von X auf einem bestimmten Block erhalten?". Grundsätzlich möchten Sie eine Funktion auf einem bestimmten Block ausführen. Dies kann über web3 erfolgen. Zuerst erzeugen Sie einen Vertragsgegenstand und dann können Sie (Javascript)

ERC20Contract.balanceOf(address, BlockNumber, function(){})

(Das obige Beispiel verwendet ERC20Contractals Vertragsadresse, balanceOfist die Vertragsfunktion, die den Saldo von zurückgibt address, BlockNumberist der tatsächliche Block, in dem Sie suchen möchten, und die leere Funktion ist eine Rückruffunktion (einige Web3-Implementierungen wie MetaMask benötigen diese))

(Siehe: https://github.com/ethereum/wiki/wiki/JavaScript-API unter Vertragsmethoden)

Das ist genau meine Frage. Wenn ich anrufe , bekomme ich immer die gleiche Nummer - ERC20Contract.balanceOf(address, BlockNumber, function(){})egal was ich angebe - den letzten Kontostand. BlockNumberMeine Testumgebung ist Ganache + Geth + Javascript Web3.
Welche Web3-Version verwendest du?
Ich schätze Ihre Geduld sehr. Ich habe die Frage bearbeitet. Ich benutze eigentlich kein nodejs, ich benutze Geth 1.8.2-stable.
Ich kenne die Geth-Syntax nicht wirklich, aber es sollte die gleiche sein. Überprüfen Sie ihre Dokumentation darüber, an welchen Block sie sich anschließen.