/// <summary> /// Parses a Bitcoin transaction output. /// </summary> /// <param name="blockMemoryStreamReader"> /// Provides access to a section of the Bitcoin blockchain file. /// </param> /// <returns> /// The Bitcoin transaction output that was parsed. /// </returns> private static TransactionOutput ParseTransactionOutput(BlockMemoryStreamReader blockMemoryStreamReader) { TransactionOutput transactionOutput = new TransactionOutput(); transactionOutput.OutputValueSatoshi = blockMemoryStreamReader.ReadUInt64(); int scriptLength = (int)blockMemoryStreamReader.ReadVariableLengthInteger(); byte[] OutputScriptBytes = blockMemoryStreamReader.ReadBytes(scriptLength); transactionOutput.OutputScript = new ByteArray(OutputScriptBytes); //this is new add to parse address, if can't parse the address, set the address = '0' byte[] outputAddress; if (scriptLength > 2) { using (BlockMemoryStreamReader outputScriptReader = new BlockMemoryStreamReader(OutputScriptBytes)) { byte first = outputScriptReader.ReadByte(); if (first == 0x6a)//RETURN: can't parse the address { outputAddress = System.Text.Encoding.ASCII.GetBytes("0"); } else if (first == 0x00 && (OutputScriptBytes[1] == 0x14 || OutputScriptBytes[1] == 0x20))//witness addr { int hash_len = outputScriptReader.ReadByte(); byte[] addr_hash = outputScriptReader.ReadBytes(hash_len); outputAddress = Bench32.SegwitAddrEncode("bc", 0, addr_hash, addr_hash.Length); } else if (first == 0x76 && OutputScriptBytes[1] == 0xa9)//normal bitcoin addr,base58check encode and prefix = 0 { outputScriptReader.ReadByte(); int hash_len = outputScriptReader.ReadByte(); byte[] addr_hash = outputScriptReader.ReadBytes(hash_len); outputAddress = Base58.EncodeBase58Check(addr_hash, addr_hash.Length, 0); } else if (first == 0xa9 && (OutputScriptBytes[1] == 0x14 || OutputScriptBytes[1] == 0x20))//base58check encode and prefix = 5 { int hash_len = outputScriptReader.ReadByte(); byte[] addr_hash = outputScriptReader.ReadBytes(hash_len); outputAddress = Base58.EncodeBase58Check(addr_hash, addr_hash.Length, 1); } else if (first == 0x41)//非压缩公钥 { byte[] bitcoin_addr = outputScriptReader.ReadBytes(65); byte[] addr_hash = Hash160.hash160(bitcoin_addr); outputAddress = Base58.EncodeBase58Check(addr_hash, addr_hash.Length, 0); } else { /* * string str = string.Empty; * foreach (byte item in OutputScriptBytes) * { * str += string.Format("{0:x2}", item); * } * Console.WriteLine(str); */ outputAddress = System.Text.Encoding.ASCII.GetBytes("0"); } } } else { /* * Console.WriteLine(scriptLength); * string str = string.Empty; * foreach (byte item in OutputScriptBytes) * { * str += string.Format("{0:x2}", item); * } * Console.WriteLine(str); */ outputAddress = System.Text.Encoding.ASCII.GetBytes("0"); } transactionOutput.OutputAddress = new ByteArray(outputAddress); return(transactionOutput); }