/// <summary> /// Appends truncated double sha256 checksum to a byte array /// </summary> /// <param name="data">byte array from bitcoin script representing an address</param> /// <returns>byte array with appended checksum</returns> private static byte[] AddCheckSum(byte[] data) { SHA256 sha256 = new SHA256Managed(); var hash1 = sha256.ComputeHash(data); var hash2 = sha256.ComputeHash(hash1); var checkSum = new byte[CheckSumBytes]; Buffer.BlockCopy(hash2, 0, checkSum, 0, checkSum.Length); var dataWithCheckSum = ArrayTools.ConcatArrays(data, checkSum); return(dataWithCheckSum); }
/// <summary> /// Encodes a bech32 address /// </summary> /// <param name="witnessVersion">the witness version (only v0 exists so far)</param> /// <param name="witnessScriptData">byte array representing address from bitcoin OP_0 (segwit) script</param> /// <param name="mainnet">generate mainnet address, otherwise testnet address</param> /// <returns>bech32 encoded string with checksum and header</returns> public static string EncodeWithHeaderAndChecksum(byte witnessVersion, byte[] witnessScriptData, bool mainnet = true) { // header is bc for mainnet, or tb for testnet var header = mainnet ? "bc" : "tb"; // convert byte array from 8bits to 5 var base5 = ConvertBits(witnessScriptData, 8, 5, true); // generate checksum from witnessVersion concat base5 array var checksumBytes = CreateChecksum(header, ArrayTools.ConcatArrays(new[] { witnessVersion }, base5)); // append the checksum to the base5 array var combined = base5.Concat(checksumBytes).ToArray(); // convert byte array to bech32 string var encoded = BytesToBech32String(combined); // return address format - Header+Separator(1)+WitnessVersion+EncodedData return(header + "1" + Digits[witnessVersion] + encoded); }