Wie speichere ich den öffentlichen Schlüssel im Ethereum-Vertrag?

Ich möchte einen öffentlichen Schlüssel einer Ethereum-Adresse in einem Vertrag speichern. Was ist der empfohlene primitive Datentyp zum Speichern eines öffentlichen Schlüssels?

  1. Soll ich als String oder Bytes32 speichern?
  2. Ist es sicher, einen öffentlichen Schlüssel in einem Vertrag zu speichern? Ich weiß, dass es sich um einen öffentlichen Schlüssel handelt, aber trotzdem ... möchte ich wissen, welche Fallstricke ich beachten sollte.

Vielen Dank!

Antworten (2)

Speichern Sie Schlüssel immer als Bytes, da Zeichenfolgen in einigen Sprachen bekanntermaßen durch Nullwert-Bytes abgeschlossen werden. Sie können ein bytes32- Attribut verwenden, um den Schlüssel zu speichern, und eine Getter-Methode, um ihn aus dem bereitgestellten (instanziierten) Vertrag abzurufen:

contract PubKey {
         bytes32 pubKey;

         function PubKey(bytes32 initKey) {
             pubKey = initKey;
         }

         function getPubKey() constant returns (bytes32) {

            return pubKey;

         }
    }

Bearbeiten:

Der öffentliche Schlüssel ist ohne sein Präfix 64 Bytes lang :

contract PubKey {
    uint8[] pubKeyBytes;

    function PubKey(uint8[] initKey) {
       for(uint i = 0; i < initKey.length; i++) {
          pubKeyBytes.push(initKey[i]);
       }
}

function getPubKeyByte(uint i) constant returns (uint) {
    return pubKeyBytes[i];
}

Dies ist teuer, da jeder Abruf des öffentlichen Schlüssels 64 Mal aufgerufen werden muss. Die Verwendung von zwei 32-Byte-Blöcken ist billiger (aber hässlicher):

contract PubKey {
     bytes32 pubKeyHalf1, pubKeyHalf2;

     function PubKey(bytes32 initKeyHalf1, bytes32 initKeyHalf2) {
         pubKeyHalf1 = initKeyHalf1;
         pubKeyHalf2 = initKeyHalf2;
     }

     function getPubKeyHalf1() constant returns (bytes32) {
        return pubKeyHalf1;
     }

     function getPubKeyHalf2() constant returns (bytes32) {
        return pubKeyHalf2;
     }
}
Vielen Dank für Ihre Antwort. Ich habe auch noch eine Anschlussfrage. Wie würde die Accessor-Funktion aussehen? Nehmen wir an ... die Funktion getPubKey() gibt (bytes32) zurück, sollten wir in bytes32 rekonstruieren, bevor wir den PubKey zurückgeben?
@etherfaces stellen zusätzliche Fragen als neue Threads. Das ist der empfohlene Weg,
Ich habe die Antwort aktualisiert.
In der getPubKey-Funktion gibt die Zeile: (byte) (key[i]) = pubKey[i] einen Fehler aus. Sieht so aus, als ob die Syntax ungültig ist. Ich werde eine neue Frage zum Konvertieren von Byte-Arrays in Bytes32 in Solidity stellen.
Wenn Sie den Konstruktor des Vertrags aufrufen, übergeben Sie das Argument als Zeichenfolge der Form "0x1234...".
Sicherlich vermisse ich etwas direkt vor mir, aber sind 32 Bytes nicht 1 Byte zu kurz? Müssen Sie nicht die 32-Byte-x-Koordinate und auch das Vorzeichen speichern?
Diese Antwort ist veraltet. „Der private Schlüssel muss 32 Bytes lang sein und nicht mit 0x00 beginnen und der öffentliche muss unkomprimiert und 64 Bytes lang sein oder 65 mit dem konstanten Präfix 0x04. Mehr dazu im nächsten Abschnitt.“ kobl.one/blog/create-full-ethereum-keypair-and-address . PubKey ist 64 Byte lang.
Dies könnte eine dumme Frage sein, aber was ist mit dem Adressdatentyp falsch?
Aber Sie können den öffentlichen Schlüssel immer noch komprimiert speichern , oder? Gibt es wirklich keinen besseren Weg, dies zu tun als zwei Bytes32? @jasper: Adressen sind nur 20 Bytes groß. Nicht genug Platz.

Sie können den öffentlichen Schlüssel auch in einer Variablen speichern bytes, aber das wird mehr Gas verbrauchen. In meinem einfachen Test verbraucht das Speichern eines öffentlichen Schlüssels in zwei bytes32Variablen ~ 67.000 Gas und das Speichern in einer bytesVariablen ~ 85.000 Gas