Mining Sicherheit

Guten Tag,

wenn ich in einem Pool meinen sollte & ich zufällig einen kompletten validen Block finden sollte, was hält mich dann davon ab diesen Block nicht selbst im Solo Mining zu claimen um den vollen Block Reward zu erhalten?

Wie genau schafft das Netzwerk das zu verhindern?

2 „Gefällt mir“

Bin kein Experte, aber soweit ich weiß erhalten zunächst die Poolbetreiber den Reward und verteilen diesen dann anteilsmäßig an die Miner.

Du stellst ja nur deine Rechenleistung deinem Pool zur Verfügung und dieser bündelt die Rechenleistung aller Angeschlossenen zusammen um einen Block zu finden. Du „sendest“ quasi deine Rechenleistung und übergibst dem Pool alle Rechte. Also wenn, dann wirst du vom Pool beschissen.

Die genaue Antwort wirst du irgendwo hier im Forum finden. Um das Forum zu durchsuchen kannst du die Lupe oben rechts verwenden.

Wenn ich das richtig verstanden habe, ist die Ausschüttung des Mining Reward selbst auch nur eine Transaktion, die zusätzlich in den Block geschrieben wird. Für eine solche Transaktion müsste dann eine Empfängeradresse angegeben werden. Diese Adresse wird vermutlich vom Mining Pool vorgegeben.

Ob der Block gültig ist, müsste erst im Anschluss festgestellt werden können. Demnach wäre es nicht möglich, die Empfängeradresse nachträglich zu ändern. Denn dies müsste zu einem anderen Hash und somit anderen Block führen. Welcher mit ziemlicher Sicherheit wiederum ungültig wäre.

2 „Gefällt mir“

Hast du einmal selber mining betrieben? Das ist sehr interessant zu beobachten und man lernt auch viel über die Technik und vor allem über Statistik wie Bitcoin funktioniert.

Beim Solomining würfelst du solange Blöcke, bis irgendein Hash unter der globalen Difficulty ist. Diesen Block kannst du veröffentlichen und weil du den Block selber gebaut hast kannst du auch selber bestimmen auf welche Adresse die neu erschaffen Bitcoins (und die Transaktionsgebühren) überwiesen werden.

Beim Poolmining läuft das ein wenig anders. Der Pool will ja wissen ob du wirklich Blöcke rechnest oder nicht. Der Pool fordert also ein Beweis dass du rechnest. Wie kannst du diesen Beweis liefern? Natürlich über die Hashrate, wie bei Bitcoin.

Was also beim Poolmining passiert ist, dass für den Pool eine deutlich geringere Hashrate gültig ist als die Welt es erlauben würde. Damit reportet dein Miner natürlich auch deutlich mehr Blöcke. Diese Blöcke sind für die Welt zwar immernoch größtenteils nicht gültig weil die Difficulty nicht erreicht wurde, aber der Pool kann damit was anfangen. Und anhand der Rate, wie viele Blöcke du für eine eingestellte Difficulty an den Pool reportest, daran kann der Pool dir deinen Hashrateanteil ausrechnen.

Im Poolmining veröffentlichst du also regelmäßig deine allerbesten Funde (also alle Hashes mit der geringsten Hashzahl) und daraus errechnet der Pool deine Hashrate und bezahlt dich anteilig.

Das bedeutet aus Poolsicht, dass er viele Miner verwalltet, aber er generiert keine Blöcke selber sondern validiert nur die wenigen „Testblöcke“ der Miner. Und dabei fällt natürlich auf, wenn ein Miner eine falsche Addresse (seine eigene) angibt. Blöcke die mit dierer Addresse erstellt werden sind für den Pool dann nicht mehr gültig und der Miner wird wieder zum Solominer.

3 „Gefällt mir“

Im Prinzip hat @lerpy die Frage schon komplett beantwortet. Ich war mir allerdings auch nie ganz sicher, was genau vom Pool vorgegeben und vom Miner zurückübermittelt wird.

Deshalb habe ich mir mal grobe Beschreibungen des Stratum V1 Protokolls angeschaut. Ich denke das wird aktuell noch von nahezu allen Pools verwendet (s.a. Artikel zu Stratum V2).


Registrierung beim Pool und Erhalten von Mining Jobs

Nachdem sich ein Miner beim Pool registriert, authorisiert und auf Updates subscribed hat, sendet der Pool dem Miner regelmäßig Mining Jobs über mining.notify(…), wobei folgende Parameter übertragen werden:

  • Job ID job_id
  • Vorheriger Block Hash prevhash
  • Alle notwendigen Infos für die merkle_root:
    o Coinbase Transaktion, ohne Extranonce
    o Merkle Branches der vorgegebenen Transaktionen im Block
  • Block Version version
  • Block Difficulty nbits
  • Timestamp ntime
  • Clean Jobs (Hilfsparameter)

Außerdem teilt der Pool dem Miner zu Beginn, sowie später nach Bedarf über mining.set_difficulty(difficulty) die interne Difficulty für die Shares im Pool, sowie über mining.set_extranonce(extranonce1, extranonce2_size) Infos über die Extranonce mit.

Die Coinbase Transaktion ist die Transaktion, über welche die Rewards an eine Adresse des Pools ausgezahlt werden (Subsidy + Transaktionsgebühren). Entsprechend wird diese Transaktion bis auf einen variablen Anteil vom Pool vorgegeben.

Die extranonce ist ein Teil der Coinbase Transaktion, in die ein beliebiger Inhalt geschrieben werden kann. Sie wird von den Minern als variabler Parameter, zusätzlich zur eigentlichen nonce genutzt, um im Mining Prozess verschiedene Blockkandidaten zu generieren.

Die extranonce wird aus den Teilen extranonce1, extranonce2 und evtl. folgenden Nullen zusammengesetzt.
Der erste Teil extranonce1 wird vom Pool spezifisch für jeden Miner vorgegeben, damit keine zwei Miner an denselben Blockkandidaten arbeiten.
Der zweite Teil extranonce2 kann vom Miner im Rahmen der freigegebenen Größe extranonce2_size als variabler Laufparameter genutzt werden.

Anschließend kann der Miner nun einen gültigen Block suchen, indem er nonce und extranonce2, sowie nach Belieben auch den Timestamp nTime in gewissem Rahmen nach Vorgabe des Pools variiert.


Mining Vorgang

Es werden laufend neue Blockkandidaten gebildet und gehashed, um das Difficulty Target zu unterbieten. Genauer gesagt wird der Block Header gehashed.

Alle Transaktionen des Blocks werden mittels eines Merkle Trees zu einem einzigen Hash, der merkle_root, verwurstet, die ein Teil des Block Headers ist. Ein Vor-Verwursten übernimmt bereits der Pool, welcher dem Miner am Ende nur die Coinbase Transaktion und die vorgehashten anderen Zweige des Merkle Trees bereitstellt (Merkle Branches).

Zur Bildung eines Block Header Kandidaten wird also die vom Pool erhaltene Coinbase Transaktion um die extranonce1 und den aktuellen Wert der extranonce2 ergänzt, und zusammen mit den erhaltenen Merkle Branches zur merkle_root gehashed.
Anschließend wird aus der merkle_root, den aktuellen Werten für nonce und ntime, sowio den vom Pool erhaltenen version, prevhash und nbits der Block Header gebildet und gehashed.

Sollte der Hash über dem Target liegen ist der Block wertlos. Es wird also die nonce um eins hochgezählt und der Header erneut gehashed.
Nach jedem erfolglosen kompletten Durchlauf des nonce-Wertebereichs und eventueller Variation von ntime, wird die extranonce2 um eins hochgezählt. Da sich durch die extranonce2 auch die Coinbase Transaktion ändert, muss die merkle_root neu berechnet werden. Anschließend wird dann erst einmal wieder nur die nonce beginnend bei 0 hochgezählt.


Finden eines innerhalb des Pools gültigen Blocks (Share)

Zum Konzept der „Shares“ siehe den Beitrag von @DasPie, oder z.B. hier: Mining: Blocks vs. Shares

Jeder gefundene Block, der das Pool-interne Difficult Target unterschreitet, wird dem Pool vom Miner mitgeteilt. Das macht der Miner mittels mining.submit(username, job_id, extranonce2, ntime, nonce).

Es wird also nicht der komplette gefundene Block an den Pool übermittelt, sondern nur die erfolgreichen Werte von nonce, extranonce2 und ntime. Die restlichen Block-Parameter kennt der Pool anhand der job_id. Der Pool kann also einfach selbst überprüfen ob der Block gültig ist.


Block einfach selbst claimen, oder Shares an mehrere Pools übermitteln?

Zur eigentlichen Frage hier im Thread:

oder aus einem anderen Thread:

Die Fragen beantworten sich denke ich nun von selbst. Der Pool gibt die Coinbase Transaktion vor, in der eine Reward-Auszahlungs-Adresse des Pools eingetragen ist. Sollte man einen gültigen Block finden, könnte man ihn zwar selbst broadcasten, aber der Reward würde damit trotzdem an den Pool gehen.

Und findet man einen gültigen Share, hat man gar nicht die Möglichkeit diesen an mehrere Pools zu übermitteln. Schließlich teilt man den Pools nur die gefunden Werte von nonce, extranonce2 und ntime zu einer job_id mit. Die anderen Pools würden bei der Überprüfung merken, dass diese Werte zusammen mit den vorgegebenen Mining Job Parametern keinen gültigen Share ergeben.

Noch unabhängig vom Thema hier:
Ein Miner kann übrigens auch bei Stratum V1 zumindest mittels mining.get_transactions(„job id“) alle Transaktionen des aktuellen Jobs bzw. Block-Kandidaten beim Pool abfragen. Man hätte so die Möglichkeit zu prüfen, ob der Pool, für den man mined, zensiert. Ich vermute aber, dass die meisten Mining Clients das nicht machen.


Quellen:
Past and future of bitcoin mining protocols: Stratum V2 overview | Braiins
Stratum mining protocol - Bitcoin Wiki

6 „Gefällt mir“

Starke Zusammenfassung! :clap:

Genauer gesagt ja sogar doppelt, also SHA-256(SHA-256(Header)), was mich grade auf die Frage gebracht hat, was mit „100 TH/s“ die auf einem Miner draufstehen eigentlich gemeint ist.

Diese „Hashrate“ gibt nämlich die Anzahl Blockkandidaten an, die der Miner innerhalb einer Sekunde überprüfen kann, völlig ungeachtet davon, wie oft SHA-256 konkret ausgeführt wird. Die zweite Berechnung muss schließlich nicht (immer) vervollständigt werden, da man frühzeitig abbrechen kann, wenn schon die ersten Bits das Target nicht erfüllen würden.

Man könnte also fast schon argumentieren, dass ein 100 TH/s Miner theoretisch mehr als 100 Tera-SHA-256-Hashes pro Sekunde rechnen könnte (wenn er nicht derart optimiert auf den Mining Prozess wäre). :slight_smile:

mining hardware - Are miners advertised hash rate single or double hash speeds? - Bitcoin Stack Exchange

2 „Gefällt mir“

Ich hab mich immer gefragt wie die das wissen das die miner wirklich auch minen. Eigentlich logisch, ist auch wieder einfach prove of work :slight_smile:

1 „Gefällt mir“