public Wallet(NetworkInfo networkInfo, byte[] address, byte[] privateKey, byte[] publicKey) { Trace.Assert(networkInfo != null); Trace.Assert(privateKey != null); Trace.Assert(publicKey != null); this.networkInfo = networkInfo; this.address = address; this.privateKey = privateKey; this.publicKey = publicKey; }
/// Creates a new [Wallet] instance based on the existent [wallet] for /// the given [networkInfo]. public static Wallet convert(Wallet wallet, NetworkInfo networkInfo) { return(new Wallet(networkInfo: networkInfo, address: wallet.address, privateKey: wallet.privateKey, publicKey: wallet.publicKey)); }
// This are implented as static constructors to translate Dart factory /// Derives the private key from the given [mnemonic] using the specified /// [networkInfo]. public static Wallet derive(List <String> mnemonic, NetworkInfo networkInfo, String lastDerivationPathSegment = "0") { Mnemonic bip39; // Get the mnemonic as a single concatenated string String mnemonicString = String.Join(' ', mnemonic); // Check the mnemonic try { bip39 = new Mnemonic(mnemonicString); } catch (ArgumentException e) { System.ArgumentException argEx = new System.ArgumentException($"Invalid mnemonic string - Exception ${e.Message} - '${mnemonicString}'"); throw argEx; } // Get the seed - byte[]. !!!Note the empty password - OK! byte[] seed = bip39.DeriveSeed(); // Using the seed in a BIP32 instance ExtKey root = new ExtKey(seed); // Check for correct lastDerivationPathSegment int segValue = -1; bool isNumeric = int.TryParse(lastDerivationPathSegment, out segValue); if ((isNumeric == false) || (segValue < 0)) { // Exception - derivation path not valid! System.ArgumentException argEx = new System.ArgumentException($"Argument Exception - Invalid Derivation Path: '{lastDerivationPathSegment}'"); throw argEx; } // Create the Keypath - with the last Path Segment String derivedPathString = $"{DERIVATION_PATH}/{lastDerivationPathSegment}"; KeyPath derivationPath = new KeyPath(derivedPathString); // Get the node ExtKey derivedNode = root.Derive(derivationPath); // Get the private key byte[] privateKey = derivedNode.PrivateKey.ToBytes(); // Get the curve data X9ECParameters secp256k1 = ECNamedCurveTable.GetByName("secp256k1"); ECPoint point = secp256k1.G; // Compute the curve point associated to the private key BigInteger bigInt = new BigInteger(HexEncDec.ByteArrayToString(privateKey), (int)16); ECPoint curvePoint = point.Multiply(bigInt); // Get the public key - Be Careful, this MUST be compressed format!!! byte[] publicKeyBytes = curvePoint.GetEncoded(true); // Get the address Sha256Digest sha256digest = new Sha256Digest(); sha256digest.BlockUpdate(publicKeyBytes, 0, publicKeyBytes.Length); // byte[] sha256digestOut = new byte[sha256digest.GetByteLength()]; byte[] sha256digestOut = new byte[sha256digest.GetDigestSize()]; sha256digest.DoFinal(sha256digestOut, 0); RipeMD160Digest ripeMD160Digest = new RipeMD160Digest(); ripeMD160Digest.BlockUpdate(sha256digestOut, 0, sha256digestOut.Length); // byte[] address = new byte[ripeMD160Digest.GetByteLength()]; byte[] address = new byte[ADDRESS_LENGTH]; ripeMD160Digest.DoFinal(address, 0); // Return the key bytes return(new Wallet(address: address, publicKey: publicKeyBytes, privateKey: privateKey, networkInfo: networkInfo)); }