Was ist eine ChainID in Ethereum, wie unterscheidet sie sich von NetworkID und wie wird sie verwendet?

Hier wird es in der go-Implementierung von Ethereum beschrieben.

type ChainConfig struct {
    ChainId *big.Int `json:"chainId"` // Chain id identifies the current chain and is used for replay protection

Ein paar Fragen:

  1. Wie ist es anders als networkID?
  2. Wird chainIDund networkIDin jedem Block benötigt oder nur im Genesis-Block?
  3. Können Sie ein konkretes Beispiel dafür geben, was es bedeutet, wenn es chainID"für den Wiedergabeschutz" verwendet wird?

EDIT: Noch unbeantwortet:

Was würde in der Situation passieren, dass Sie networkIDauf eine der Hauptnets setzen networkID, aber die anderen Konfigurationsvariablen nach Belieben ändern? Warum spielt es eine Rolle, was Sie für die Netzwerk-ID festlegen, wenn Sie eine lokale Kette betreiben?

Meine Uniswap-Transaktionen können nicht durchgeführt werden, da keine Chainid angezeigt wird. Wie kann ich das beheben?

Antworten (4)

Wie unterscheidet es sich von networkID?

ChainID wurde in EIP-155 eingeführt , um Replay-Angriffe zwischen den wichtigsten ETH- und ETC-Ketten zu verhindern, die beide eine Netzwerk-ID von haben 1.

Es ist im Grunde nur eine zusätzliche Möglichkeit, Ketten voneinander zu unterscheiden. Nach EIP-155 hat ETH eine Ketten-ID von 1, während ETC eine Ketten-ID von hat 61(obwohl sie immer noch dieselbe Netzwerk -ID von haben 1).

Werden ChainID und NetworkID in jedem Block oder nur im Genesis-Block benötigt?

Es ist für den Betrieb der Kette im Allgemeinen erforderlich - z. B. beim Signieren von Transaktionen, was bedeutet, dass im ETH-Netzwerk signierte Transaktionen mit einem anderen Hash enden als die auf ETC signierten. Vor EIP-155 sahen signierte Transaktionen in jedem Netzwerk gleich aus und konnten wiedergegeben werden.

Bearbeiten:

Ein konkretes Beispiel für die Verwendung von chainId.

Gemäß der EIP-155-Seitev hängt der Wert einer Transaktionssignatur vom Wert von chainID ab.

Wenn block.number >= FORK_BLKNUMund v = CHAIN_ID * 2 + 35oder v = CHAIN_ID * 2 + 36, dann werden bei der Berechnung des Hashs einer Transaktion zum Signieren oder Wiederherstellen, anstatt nur die ersten sechs Elemente zu hashen (d. h. nonce, gasprice, startgas, to, value, data), neun Elemente gehasht, wobei vsie durch ersetzt werden CHAIN_ID, r = 0und s = 0. Das derzeit bestehende Signaturschema mit v = 27und v = 28bleibt gültig und arbeitet weiterhin nach denselben Regeln wie jetzt.

Auf der EIP-155-Seite finden Sie ein detailliertes Beispiel dafür, wie dies angewendet wird.

Können Sie erläutern, wie dies auf granularer Ebene funktioniert? Ich schätze die Antwort, aber ich verstehe nicht näher, wie es beim Signieren funktioniert, warum der Hash anders wäre usw.
Ich habe einige weitere Details hinzugefügt (im Wesentlichen von der EIP-155-Seite kopiert). :-)
Sie sagen "Es ist erforderlich, damit die Kette im Allgemeinen funktioniert", aber woher weiß eine Transaktion am Ende der Kette von den Variablen wie chainIDdem Genesis-Block?
Ein Client kann nicht arbeiten, ohne zu wissen, auf welchem ​​Netzwerk (dh der Kombination aus Netzwerk-ID und Ketten-ID) er arbeitet. Um in ein Netzwerk zu booten, müssen die Genesis-Informationen eines Clients mit dem Rest des Netzwerks übereinstimmen. Beachten Sie, dass es technisch gesehen keinen "Genesis-Block" gibt. Es ist wirklich nur eine Statusdefinition in einer JSON-Datei, von der ein Feld die ChainID ist. (Der erste Block war Block 0, und es war nur ein normaler Block, wie alle nachfolgenden Blöcke, mit der Ausnahme, dass er meiner Meinung nach von Hand gefertigt und nicht abgebaut wurde.)
Der Client hat daher die Genesis-Informationen in seiner genesis.json, auf die er zurückgreifen kann, wenn er sie benötigt. (Beim Booten liest es wahrscheinlich den Genesis-Status von der Festplatte in eine Reihe von In-Memory-Variablen. Ich habe mir den Codepfad jedoch nicht angesehen, um dies zu bestätigen.)
Richtig, aber wenn ein Miner eine Transaktion von einem anderen Knoten erhält , wie kann der Miner dann wissen, ob die Genesis-Datei auf diesem anderen Knoten mit der auf seinem Mining-Knoten übereinstimmt?
Denn wenn er die Transaktion erhält, den vWert und schließlich den ChainID-Wert wiedererlangt, stimmt dieser nicht mit seinem eigenen überein. (Worum es bei EIP-155 geht.)

Trotz der Tatsache, dass diese Frage eine akzeptierte Antwort hat, scheint die ursprüngliche Frage nicht beantwortet zu sein, also werde ich meine zwei Cent hinzufügen.

  1. Wie unterscheidet es sich von networkID?

Die Netzwerkkennung (networkID) schützt einen Knoten davor, sich mit den Knoten zu verbinden, die sich mit anderen Netzwerken synchronisieren. Wenn eine Verbindung zwischen zwei Knoten hergestellt wird, tauschen diese Knoten Statusnachrichten aus, die unter anderem Netzwerkkennungen der sendenden Knoten enthalten. Laut Dokumentation sollte Statusdie Nachricht „gleich nach dem Verbindungsaufbau und vor allen anderen Eth-Protokollnachrichten gesendet werden“. Wenn ein Knoten eine StatusNachricht von seinem Peer empfängt, vergleicht er die Netzwerkkennung in der Nachricht mit der eigenen Netzwerkkennung des Knotens und beendet Verbindungen im Falle einer Nichtübereinstimmung.

Die in EIP-155 eingeführte Kettenkennung (chainID) schützt Transaktionen, die in einer Kette enthalten sind, davor, in eine andere Kette aufgenommen zu werden. Grundsätzlich ist die Kettenkennung eine ganze Zahl, die beim Signieren von Transaktionen und Verifizieren von Transaktionssignaturen verwendet wird. Wenn unterschiedliche Kettenkennungen zum Signieren und Verifizieren der Transaktion verwendet werden, schlägt die Transaktionsverifizierung fehl.

  1. Werden ChainID und NetworkID in jedem Block oder nur im Genesis-Block benötigt?

Die Netzwerk-ID ist nicht in Blöcken enthalten und wird auch nicht beim Signieren von Transaktionen oder Mining-Blöcken verwendet. Es ist nur ein Attribut des Ethereum Wire-Protokolls, das verhindert, dass sich Knoten verschiedener Ketten miteinander verbinden. Die Ketten-ID ist nicht in Blöcken enthalten, wird aber während Transaktionssignierungs- und Verifizierungsprozessen verwendet, um Transaktionen effektiv zu schützen, die darauf abzielen, dass eine Kette in einer anderen Kette erscheint.

  1. Können Sie ein konkretes Beispiel dafür geben, was es bedeutet, wenn ChainID "für den Wiedergabeschutz" verwendet wird?

Wenn zwei Chains unterschiedliche Chain-Identifikatoren zum Verifizieren von Transaktionen verwenden oder wenn eine Chain EIP-155 implementiert und die andere Chain es nicht implementiert hat, werden diese beiden Chains niemals beide dieselbe Transaktion akzeptieren. Dies schützt effektiv vor Replay-Angriffen, dh davor, dass eine Transaktion, die auf einer Kette ausgeführt werden sollte, tatsächlich auch auf einer anderen Kette ausgeführt wurde.

- Wie unterscheidet es sich von networkID?

Die Netzwerk-ID dient der Knotenkommunikation und die Ketten-ID wird zur Identifizierung der Zielkette in der Signatur verwendet. Die ETC- und ETH-Ketten-ID ist unterschiedlich und die Netzwerk-ID ist gleich

- Werden ChainID und NetworkID in jedem Block benötigt oder nur im Genesis-Block?

Dies ist nur in der Genesis-Datei, nicht in Blöcken. Hier ist die Beschreibung des allerersten Blocks des Mainnets (ja, ich synchronisiere gerade im schnellen Modus :D )

> eth.getBlock(0)
{
  difficulty: 17179869184,
  extraData: "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
  gasLimit: 5000,
  gasUsed: 0,
  hash: "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0x0000000000000000000000000000000000000000",
  mixHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
  nonce: "0x0000000000000042",
  number: 0,
  parentHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
  receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 540,
  stateRoot: "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544",
  timestamp: 0,
  totalDifficulty: 17179869184,
  transactions: [],
  transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  uncles: []
}

> web3.eth.chainId()
"0x5b7d"

- Können Sie ein konkretes Beispiel dafür geben, was es bedeutet, wenn ChainID "für den Wiedergabeschutz" verwendet wird?

Vielleicht finden Sie hier Ihre Antwort

Was würde in der Situation passieren, dass Sie networkIDeine der Mainnet-Netzwerk-IDs festlegen, aber die anderen Konfigurationsvariablen beliebig ändern? Warum ist es wichtig, worauf Sie sich einstellen, networkIDwenn Sie eine lokale Kette betreiben?
Mein Wissen zu diesem Thema ist nicht gut genug, um das zu beantworten. Ich kann Ihnen nur sagen, dass Geth unabhängig von der ChainID die gesamte Genesis-Datei verwendet, um zu überprüfen, ob zwei Peers dieselbe Kette verwenden.
Können Sie den Unterschied zwischen der Genesis-Datei und dem ersten Block erläutern? Wie verwendet die Blockchain diese Informationen, wenn sie nicht im ersten Block gespeichert sind?
Geth überprüft einfach die genesis.json und vergleicht sie mit derjenigen der Person, die versucht, eine Verbindung herzustellen, das war's. Darüber hinaus ist die Genesis-Datei ganz am Anfang eine Beschreibung der Kette. Der erste Block ist nur ein Block, der diese Beschreibung verwendet, dann geht es weiter.
Ja, aber was ist, wenn die Genesis-Datei so etwas wie "Fork at Block 20000" sagt, was sie tut. Wie geht das, wenn man es nur am Anfang liest? Muss es nicht immer gelesen werden?
Es fällt mir enorm schwer, die Transaktionen zu verstehen, die im ersten Block (immer gleich), der Genesis-Statusdatei, auftreten, und wenn ein neues EIP akzeptiert wird, wie sich das auf das Aussehen der Blockchain auswirkt
Was meinst du mit "Fork bei Block 20000"? Die Genesis kann nicht sagen "Hey, ich will eine Gabel an diesem Block"
Es wird nur dann eine Transaktion stattfinden, wenn jemand eine gesendet hat. Warum denkst du, dass es anders wäre? Es ist nur ein normaler Block @AlwaysQuestioning
Auf der Beschreibung chainIDtaucht @Florian Castelain nicht auf
Andere Antworten besagen, dass chainID und networkID unterschiedliche Dinge mit unterschiedlichen Zwecken sind. Ist diese Antwort falsch?

Was würde passieren, wenn Sie die Netzwerk-ID auf eine der Netzwerk-IDs des Hauptnetzes setzen, aber die anderen Konfigurationsvariablen beliebig ändern? Warum spielt es eine Rolle, was Sie für die Netzwerk-ID festlegen, wenn Sie eine lokale Kette betreiben?

Um eine wirklich lokale Kette zu haben, müssen Sie --bootnodesauf einen Ihrer Knoten verweisen. Mit welchem ​​Bootknoten sich ein Knoten verbindet, bestimmt, welche Peers er sieht. Dann bestimmt die Netzwerk-ID, mit welchen Peers (von denen sie sieht) sie sich verbindet.

Wenn Sie also --bootnodeseinen Ihrer Knoten festlegen, können Sie die Netzwerk-ID beliebig einstellen – Sie sind jetzt vom öffentlichen Ethereum-Netzwerk getrennt.

Wenn Sie keinen --bootnodesIhrer Knoten festlegen:

In diesem Fall haben Sie nicht wirklich eine vollständig lokale Kette – Sie sind mit allen Peers im öffentlichen Ethereum-Netzwerk verbunden, die dieselbe Netzwerk-ID wie Sie verwenden.

Ihnen ist nicht klar, was Sie mit "anderen Konfigurationsvariablen" meinen. Wenn Sie Ketten-ID oder Inhalt des Genesis-Blocks meinen, wird Ihr Knoten dann immer noch eine Verbindung zu Peers auf denselben Bootnodes mit derselben Netzwerk-ID herstellen, aber der Hash des Genesis-Blocks (und aller nachfolgenden Blöcke) wird nicht übereinstimmen, und der Knoten wird es tun ziemlich einsam fühlen ... es wird Schwierigkeiten haben, einen Peer zu finden, mit dem es Blockchain-Daten austauschen kann.