Ist es möglich, innerhalb von Geth einen eindeutigen Hash zu erstellen?

Wenn wir einen Transaktionsaufruf tätigen, erhalten wir sofort den Transaktions-Hash. Wie hier erwähnt, konnten wir den Hash der Transaktion nicht innerhalb der Vertragsfunktion abrufen. Wäre es eine gute Idee, eine Variable des Vertrags mit dem Transaktionshashwert direkt nach der Generierung zu setzen?

 > myContract.hello();
"0x41f6c6fbdfd4184172d61b390922270db087519137c43d3052fbad33876964f7"
> myContract.setUniqueHash("0x41f6c6fbdfd4184172d61b390922270db087519137c43d3052fbad33876964f7");

Ziel: Ich möchte einen eindeutigen Hashwert in meinem Vertrag als Schlüssel verwenden. Das externe Festlegen eines eindeutigen Werts scheint in Bezug auf das Gas effizienter zu sein.

[Q1] Ist es in der Geth-Konsole möglich, einen eindeutigen Hash zu erstellen? Wenn ja, könnte ich es als Argument anstelle eines Transaktionshashs in meinen Vertrag einreichen.

Würde folgendes helfen? web3.sha3("Print(helloWorld)")als einzigartiger Hash. Im schlimmsten Fall kann ich vielleicht eine Datei in ipfs hinzufügen und ihren Hash als Schlüssel verwenden.

[F2] Gibt es eine Möglichkeit, einzigartiges Hash innerhalb von Solidity zu erstellen?

Eine Frage zu etwas Verwandtem ist "Wie man eine Zufallszahl generiert" ethereum.stackexchange.com/q/191 . Sie können eine ähnliche Technik verwenden, um einen eindeutigen Hash zu generieren.

Antworten (2)

Wenn der Hash nicht vollkommen zufällig sein muss, sondern Sie nur eine garantiert eindeutige ID wünschen, können Sie sha3eine Nonce oder, um abstrakter zu sein, eine Verkettung von Daten durchführen, die mit der Transaktion gesendet wurden.

uint nonce;
...
bytes32 unique = sha3(block.number, msg.data, nonce++)`

Es hängt davon ab, welche Eigenschaften Sie im resultierenden Hash benötigen.

sha3kann zum Generieren von eigenen Indizes in Mappings verwendet werden, wie in diesem Beispiel für eigene Strings:

contract OwnedIndex {

    mapping (bytes32 => string) ownedString;

    function set(string _str)
    {
        // Generates a key unique to sender and string
        ownedString[sha3(msg.sender, _str)] = str;
    }

    function clear(string _str)
    {
        // Must be the origional sender to generate key to delete
        delete ownedString[sha3(msg.sender, _str)];
    }
}
Ist es möglich, so etwas wie: "web3.sha3(block.number, msg.data, nonce++)" innerhalb von geth aufzurufen, ich denke, es akzeptiert nur Zeichenfolgen? @o0ragman0o
Das scheint zu funktionieren: web3.eth.sign(eth.accounts[0], web3.sha3("Some text"), nonce);nonce => web3.eth.getBlock(5).noncerichtig? @o0ragman0o
Entschuldigung, ich glaube, ich habe Sie mit dieser Frage in die Irre geführt (jetzt gelöscht). web3.sha3(...)sollte alles sein was du brauchst. Möglicherweise müssen Sie nur ein wenig recherchieren, um eindeutige IDs aus pseudozufälligen Quellen zu generieren. Vielleicht nur web3.sha3(Math.random()).

Die Antwort auf die Frage im Titel lautet nein, es ist nicht möglich, in Solidity einen Hash zu erstellen, von dem Sie sicher sind, dass er einzigartig ist, zumindest angesichts der Möglichkeit von Blockverwaisung und Reorgs .

Benutzer können eine Nonce an die Transaktion übergeben, aber wenn Sie ihnen nicht vertrauen, können Sie nicht sicher sein, dass sie dieselbe nicht zweimal übergeben. Wenn Sie Ihre ID ausschließlich auf der Grundlage von Benutzerdaten erstellen, versuchen diese möglicherweise böswillig, IDs zu erhalten, von denen andere Benutzer erwarten, dass sie anderen Daten zugewiesen werden.

Wenn Sie sich keine Sorgen um Reorgs machen, können Sie einfach eine Nummer im Vertrag erhöhen. Diese Nummer identifiziert eindeutig einen einzelnen Datensatz in einem bestimmten Block. Wenn dieser Block jedoch verwaist ist, kann er am Ende einen anderen Datensatz im konkurrierenden Block identifizieren, der in der längsten Kette endet. Dies kann es unpraktisch machen, eine Anwendung zu erstellen, die es verwendet, da Sie möglicherweise die ID bearbeiten müssen, die durch eine Transaktionsänderung erstellt wurde, nachdem Sie sie bereits angezeigt oder verarbeitet haben.

Wenn der von Ihnen erstellte Datensatz aufgrund der darin enthaltenen Daten in Ihrem Vertrag eindeutig sein muss, sollten Sie die Daten im Vertrag einfach hashen, um eine ID zu erstellen, die ihn eindeutig identifiziert. Hashing ist im Vergleich zum Speichern von Daten ziemlich billig, daher sollten die Gaskosten normalerweise nicht unerschwinglich sein. Das bedeutet auch, dass Sie wissen, welche ID der Datensatz haben wird, bevor Sie die Transaktion senden, was die Nachverfolgung erleichtern kann.

Wenn ein Datensatz mit demselben Inhalt mehrere Male mit jeweils einem neuen Datensatz erstellt werden muss, möchten Sie möglicherweise eine vom Benutzer erstellte Nonce verwenden, aber diese mit der Adresse des Benutzers hashen. Lassen Sie den Vertrag überprüfen, ob er nicht bereits einen Datensatz mit dieser ID hat, und ob er einen Fehler auslöst. Die Nonce kann in der Anwendung nachverfolgt werden oder etwas verwenden, das normalerweise nicht versehentlich kollidiert, wie eine große, vom Client generierte Zufallszahl oder ein vom Client generierter Zeitstempel. Obwohl ein Benutzer Transaktionen erstellen könnte, die normalerweise dieselbe ID erhalten würden, kann ein Benutzer auf diese Weise nicht böswillig eine ID erstellen, von der ein anderer Benutzer erwartet, dass sie seinem Datensatz zugewiesen wird. Dadurch bleibt auch die Fähigkeit Ihrer Anwendung erhalten, im Voraus vorherzusagen, welche ID die gesendete Transaktion erhalten wird.