/// Converts the current [Wallet] instance into a JSON object. /// Note that the private key is not serialized for safety reasons. public Dictionary <String, Object> toJson() { Dictionary <String, Object> wkDict = new Dictionary <String, Object>(); wkDict.Add("hex_address", HexEncDec.ByteArrayToString(this.address)); wkDict.Add("bech32_address", this.bech32Address); wkDict.Add("public_key", HexEncDec.ByteArrayToString(this.publicKey)); wkDict.Add("network_info", this.networkInfo.toJson()); return(wkDict); }
private static BigInteger _decodeBigInt(byte[] bytes) { // We convert bytes in a string of digits base 16, then to BigInt return(new BigInteger(HexEncDec.ByteArrayToString(bytes), (int)16)); }
// 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)); }