예제 #1
0
        /// <summary>
        /// Remove superflous branches
        /// </summary>
        /// <param name="transaction"></param>
        /// <returns></returns>
        public PartialMerkleTree Trim(params uint256[] matchedTransactions)
        {
            var trimmed = new PartialMerkleTree();

            trimmed.TransactionCount = this.TransactionCount;
            MerkleNode root = GetMerkleRoot();

            foreach (MerkleNode leaf in root.GetLeafs())
            {
                MarkToTop(leaf, false);
            }
            var flags = new BitWriter();

            foreach (MerkleNode leaf in root.GetLeafs().Where(l => matchedTransactions.Contains(l.Hash)))
            {
                MarkToTop(leaf, true);
            }
            trimmed.BuildCore(root, flags);
            trimmed.Flags = flags.ToBitArray();
            return(trimmed);
        }
예제 #2
0
        private static void MarkNodes(MerkleNode root, bool[] vMatch)
        {
            var matches = new BitReader(new BitArray(vMatch));

            foreach (MerkleNode leaf in root.GetLeafs())
            {
                if (matches.Read())
                {
                    MarkToTop(leaf, true);
                }
            }
        }
예제 #3
0
        public static MnemonicReference Parse
            (ChainBase chain,
            Wordlist wordList,
            string sentence,
            Transaction transaction,
            MerkleBlock merkleBlock)
        {
            var indices = wordList.ToIndices(sentence);

            //Step1: Determine w = number of words in the mnemonic code
            int w = indices.Length;

            //Convert mnemonic code into finalAddress following BIP-0039
            var finalAddress = Wordlist.ToBits(indices);

            var rawAddress  = DecryptFinalAddress(finalAddress);
            int blockHeight = 0;
            var x           = DecodeBlockHeight(rawAddress, out blockHeight);

            var header = chain.GetBlock((int)blockHeight);

            if (header == null)
            {
                throw new InvalidBrainAddressException("This block does not exists");
            }
            if (header.HashBlock != merkleBlock.Header.GetHash())
            {
                throw new InvalidBrainAddressException("The provided merkleblock do not match the block of the sentence");
            }
            var        blockId = header.HashBlock;
            MerkleNode root    = merkleBlock.PartialMerkleTree.TryGetMerkleRoot();

            if (root == null || root.Hash != header.Header.HashMerkleRoot)
            {
                throw new InvalidBrainAddressException("Invalid partial merkle tree");
            }

            int y1      = BitCount((int)merkleBlock.PartialMerkleTree.TransactionCount);
            int y2      = 11 * w - 1 - x - c;
            int y       = Math.Min(y1, y2);
            int txIndex = Decode(Substring(rawAddress, x, y));

            var txLeaf = root.GetLeafs().Skip((int)txIndex).FirstOrDefault();

            if (txLeaf == null || txLeaf.Hash != transaction.GetHash())
            {
                throw new InvalidBrainAddressException("The transaction do not appear in the block");
            }

            int z1          = BitCount(transaction.Outputs.Count);
            int z2          = 11 * w - 1 - x - y - c;
            int z           = Math.Min(z1, z2);
            int outputIndex = Decode(Substring(rawAddress, x + y, z));

            if (outputIndex >= transaction.Outputs.Count)
            {
                throw new InvalidBrainAddressException("The specified txout index is outside of the transaction bounds");
            }
            var txOut = transaction.Outputs[outputIndex];


            var cs               = 11 * w - 1 - x - y - z;
            var actualChecksum   = Substring(rawAddress, x + y + z, cs);
            var expectedChecksum = CalculateChecksum(blockId, txIndex, outputIndex, txOut.ScriptPubKey, cs);

            if (!actualChecksum.OfType <bool>().SequenceEqual(expectedChecksum.OfType <bool>()))
            {
                throw new InvalidBrainAddressException("Invalid checksum");
            }

            return(new MnemonicReference()
            {
                BlockHeight = (int)blockHeight,
                TransactionIndex = (int)txIndex,
                WordIndices = indices,
                Checksum = actualChecksum,
                Output = transaction.Outputs[outputIndex],
                OutputIndex = (int)outputIndex,
                BlockId = blockId,
                Transaction = transaction
            });
        }
예제 #4
0
		private static void MarkNodes(MerkleNode root, bool[] vMatch)
		{
			BitReader matches = new BitReader(new BitArray(vMatch));
			foreach(var leaf in root.GetLeafs())
			{
				if(matches.Read())
				{
					MarkToTop(leaf, true);
				}
			}
		}