Erstellen eines Offline-Adressenerstellers für Ethereum

Ich habe diese Bitcoin Paper Wallet gefunden: https://bitcoinpaperwallet.com/bitcoinpaperwallet/generate-wallet.html

Ich würde es Ethereum nur zum Spaß hinzufügen.

Bei dieser Frage zeigen sie, wie man eine Adresse offline erstellt.

Ich habe versucht, dieselbe EllipticCurve-Bibliothek zu verwenden, die sie verwenden, Sie können es hier überprüfen . Ich denke, Elliptic Curve ist überall gleich, oder?

Basierend darauf habe ich das unten gezeigte Skript erstellt. Ich bekomme einen privaten Schlüssel, einen öffentlichen Schlüssel und eine Adresse, aber ... Wenn ich versuche, mit web3 eine Adresse aus einem privaten Schlüssel zu generieren, erhalte ich eine andere.

Irgendwelche Ideen werden sehr geschätzt.

<script type="text/javascript">
    //Ethereum - January 2018
    Ethereum.ECDSA = Bitcoin.ECDSA;

    Ethereum.ECKey = (function() {

        var ECDSA = Ethereum.ECDSA;
        var ecparams = EllipticCurve.getSECCurveByName("secp256k1");
        var rng = new SecureRandom();

        var ECKey = function (input) {
            console.log("ethereum input");
            console.log(input);
            if (!input) {
                var n = ecparams.getN();
                console.log("getN");

                this.priv = ECDSA.getBigRandom(n);
                console.log();
                console.log("this.priv");
                console.log(this.priv);
                console.log("====");
            }
        }

        ECKey.prototype.getEthereumAddress = function () {

            console.log("getEthereumAddress");
            var hash = this.getPubKeyHash();
            console.log("hashEther");
            console.log(hash);
            var ola =  Crypto.util.bytesToHex(hash).toString().toUpperCase();
            console.log("ola");
            console.log(ola);

            //var sourceAddress = keccak256(hash);



            var sourceBuffer = keccak256.buffer(hash).slice(-20);
            address = this.buffer2Hex(sourceBuffer);

            console.log("AAAAAA");
            console.log(address);
            return address.toString();
        };

        /*
         * Return public key as a byte array in DER encoding
         */
        ECKey.prototype.getPub = function () {

            console.log("getPub");
                if (this.pubUncomp) return this.pubUncomp;
                return this.pubUncomp = this.getPubPoint().getEncoded(0);

        };

        ECKey.prototype.getPubKeyHash = function () {
            console.log("getPubKeyHashx");
            console.log(this.getPub());
            console.log("====");
            if (this.pubKeyHashUncomp) return this.pubKeyHashUncomp;
            return this.pubKeyHashUncomp = this.getPub();

        };

        /**
         * Return public point as ECPoint object.
         */
        ECKey.prototype.getPubPoint = function () {
            if (!this.pubPoint) {
                this.pubPoint = ecparams.getG().multiply(this.priv);
                this.pubPoint.compressed = this.compressed;
            }
            return this.pubPoint;
        };

        ECKey.prototype.buffer2Hex = function(buffer) { // buffer is an ArrayBuffer
            return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16))).join('');
        }

        /**
         * Set whether the public key should be returned compressed or not.
         */
        ECKey.prototype.setCompressed = function (v) {
            this.compressed = !!v;
            if (this.pubPoint) this.pubPoint.compressed = this.compressed;
            return this;
        };

        // Private Key Hex Format
        ECKey.prototype.getEthereumPrivateKeyHexFormat = function () {
            var ola =  Crypto.util.bytesToHex(this.getEthereumPrivateKeyByteArray()).toString().toUpperCase();
            console.log("getBitcoinHexFormat");
            console.log(ola);
            return ola;
        };

        ECKey.prototype.getEthereumAddressHexFormat = function () {
            var ola =  Crypto.util.bytesToHex(this.getEthereumPrivateKeyByteArray()).toString().toUpperCase();
            console.log("getBitcoinHexFormat");
            console.log(ola);
            return ola;
        };

        ECKey.prototype.getEthereumPrivateKeyByteArray = function () {
            // Get a copy of private key as a byte array
            var bytes = this.priv.toByteArrayUnsigned();
            // zero pad if private key is less than 32 bytes
            while (bytes.length < 32) bytes.unshift(0x00);
            return bytes;
        };

        // Sipa Private Key Wallet Import Format
        ECKey.prototype.getEthereumPrivateKey = function () {
            console.log("getEthereumPrivateKey");
            var bytes = this.getEthereumPrivateKeyByteArray();
            return Crypto.util.bytesToHex(bytes).toString().toUpperCase();
        };


        return ECKey;
    })();


    </script>

Antworten (1)

Dieser Code ist größtenteils korrekt, aber es gibt zwei kleine Probleme:

  1. Bevor Sie den öffentlichen Schlüssel hashen, müssen Sie das erste Byte löschen. Das erste Byte gibt oft an, ob der Schlüssel komprimiert ist oder nicht. In Ethereum muss der Wert immer unkomprimiert sein, und Sie schließen das Präfix beim Hashen nicht ein.
  2. buffer2Hexscheint kaputt zu sein.

Hier ist eine feste Version von getEthereumAddress:

ECKey.prototype.getEthereumAddress = function () {
  return Crypto.util.bytesToHex(
    keccak256.array(
      this.getPub().slice(1) // drop the 1-byte prefix
    ).slice(-20));           // take the last 20 bytes
};

(Wenn keccak256.arrayes für Sie nicht existiert, verwenden Sie vielleicht eine andere Bibliothek als ich. Ich habe js-sha3 verwendet .)

Danke!!! das war mein Fehler. Können Sie mir Ihre E-Mail oder Twitter oder Linkedin geben? Du bist ein Lebensretter!!
smarx@smarx.com, @smarx
Danke @smart. Vielleicht können Sie mir dabei helfen: ethereum.stackexchange.com/questions/36036/…
Eine weitere Frage: Wenn der Benutzer eine zufällige Zeichenfolge als Startwert zum Generieren einer Adresse eingibt, wäre dies gültig? var bytes = Crypto.charenc.UTF8.stringToBytes(suppliedKey)); this.priv = new BigInteger (Bytes); Wenn ein Benutzer eine private Schlüsselzeichenfolge eingibt, wäre diese gültig? var bytes = Crypto.util.hexToBytes(privStr); this.priv = new BigInteger (Bytes);
Ich bin neu dabei und habe eine Mischung aus allen Münzen! :D