Addresses

為乙太坊創建離線地址創建者

  • January 9, 2018

我發現了這個比特幣紙錢包:https ://bitcoinpaperwallet.com/bitcoinpaperwallet/generate-wallet.html

我想添加它乙太坊只是為了好玩。

在這個問題上,他們展示瞭如何離線創建地址。

我嘗試使用他們正在使用的同一個 EllipticCurve 庫,你可以在這裡查看,我猜 Elliptic Curve 到處都是一樣的,對吧?

基於此,我創建瞭如下所示的腳本。我得到了私鑰、公鑰和地址,但是……如果我嘗試使用 web3 從私鑰生成地址,我會得到一個不同的地址。

任何想法將不勝感激。

<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>

這段程式碼大部分是正確的,但有兩個小問題:

  1. 在散列公鑰之前,您需要刪除第一個字節。第一個字節通常表示密鑰是否被壓縮。在乙太坊中,該值必須始終未壓縮,並且在散列時不包含前綴。
  2. buffer2Hex似乎壞了。

這是一個固定版本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
};

(如果keccak256.array您不存在,也許您使用的庫與我使用的庫不同。我使用了js-sha3。)

引用自:https://ethereum.stackexchange.com/questions/35573