/// 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); }
/// Creates a new [Wallet] instance from the given [json] and [privateKey]. // Static constructor for returning a TransactionResult from json // I abandoned static constructor from json - I am not sure this is the best way to do it, I'd prefer a standard constructor from a dictionary - athough, this was near to Dart approach // Std cosntructor from a dictionary - should work!!! public Wallet(Dictionary <String, Object> json, byte[] privateKey) { //byte[] wkAddress = null, wkPublicKey = null; //NetworkInfo wkNetworkInfo = null; Object outValue; if (json.TryGetValue("hex_address", out outValue)) { this.address = HexEncDec.StringToByteArray(outValue as String); } if (json.TryGetValue("public_key", out outValue)) { this.publicKey = HexEncDec.StringToByteArray(outValue as String); } if (json.TryGetValue("network_info", out outValue)) { this.networkInfo = new NetworkInfo(outValue as Dictionary <String, Object>); } this.privateKey = privateKey; }
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)); }