ReverseBytes() public static method

Returns a copy of the given byte array in reverse order.
public static ReverseBytes ( byte bytes ) : byte[]
bytes byte
return byte[]
Example #1
0
        /// <exception cref="ProtocolException"/>
        protected override void Parse()
        {
            _version          = ReadUint32();
            _prevBlockHash    = ReadHash();
            _merkleRoot       = ReadHash();
            _time             = ReadUint32();
            _difficultyTarget = ReadUint32();
            _nonce            = ReadUint32();

            _hash = new Sha256Hash(Utils.ReverseBytes(Utils.DoubleDigest(Bytes, 0, Cursor)));

            if (Cursor == Bytes.Length)
            {
                // This message is just a header, it has no transactions.
                return;
            }

            var numTransactions = (int)ReadVarInt();

            Transactions = new List <Transaction>(numTransactions);
            for (var i = 0; i < numTransactions; i++)
            {
                var tx = new Transaction(Params, Bytes, Cursor);
                Transactions.Add(tx);
                Cursor += tx.MessageSize;
            }
        }
Example #2
0
        private IList <byte[]> BuildMerkleTree()
        {
            // The Merkle root is based on a tree of hashes calculated from the transactions:
            //
            //          root
            //             /\
            //            /  \
            //          A      B
            //         / \    / \
            //       t1 t2  t3 t4
            //
            // The tree is represented as a list: t1,t2,t3,t4,A,B,root where each entry is a hash.
            //
            // The hashing algorithm is double SHA-256. The leaves are a hash of the serialized contents of the
            // transaction. The interior nodes are hashes of the concentration of the two child hashes.
            //
            // This structure allows the creation of proof that a transaction was included into a block without having to
            // provide the full block contents. Instead, you can provide only a Merkle branch. For example to prove tx2 was
            // in a block you can just provide tx2, the hash(tx1) and B. Now the other party has everything they need to
            // derive the root, which can be checked against the block header. These proofs aren't used right now but
            // will be helpful later when we want to download partial block contents.
            //
            // Note that if the number of transactions is not even the last tx is repeated to make it so (see
            // tx3 above). A tree with 5 transactions would look like this:
            //
            //                root
            //                /  \
            //              1     \
            //            /  \     \
            //          2     3     4
            //         / \   / \   /  \
            //       t1 t2  t3 t4  t5 t5
            var tree = new List <byte[]>();

            // Start by adding all the hashes of the transactions as leaves of the tree.
            foreach (var t in Transactions)
            {
                tree.Add(t.Hash.Bytes);
            }
            var levelOffset = 0; // Offset in the list where the currently processed level starts.

            // Step through each level, stopping when we reach the root (levelSize == 1).
            for (var levelSize = Transactions.Count; levelSize > 1; levelSize = (levelSize + 1) / 2)
            {
                // For each pair of nodes on that level:
                for (var left = 0; left < levelSize; left += 2)
                {
                    // The right hand node can be the same as the left hand, in the case where we don't have enough
                    // transactions.
                    var right      = Math.Min(left + 1, levelSize - 1);
                    var leftBytes  = Utils.ReverseBytes(tree[levelOffset + left]);
                    var rightBytes = Utils.ReverseBytes(tree[levelOffset + right]);
                    tree.Add(Utils.ReverseBytes(Utils.DoubleDigestTwoBuffers(leftBytes, 0, 32, rightBytes, 0, 32)));
                }
                // Move to the next level.
                levelOffset += levelSize;
            }
            return(tree);
        }
Example #3
0
 /// <summary>
 /// Calculates the block hash by serializing the block and hashing the resulting bytes.
 /// </summary>
 private Sha256Hash CalculateHash()
 {
     using (var bos = new MemoryStream())
     {
         WriteHeader(bos);
         return(new Sha256Hash(Utils.ReverseBytes(Utils.DoubleDigest(bos.ToArray()))));
     }
 }
Example #4
0
 /// <exception cref="IOException"/>
 private void WriteHeader(Stream stream)
 {
     Utils.Uint32ToByteStreamLe(_version, stream);
     stream.Write(Utils.ReverseBytes(_prevBlockHash.Bytes));
     stream.Write(Utils.ReverseBytes(MerkleRoot.Bytes));
     Utils.Uint32ToByteStreamLe(_time, stream);
     Utils.Uint32ToByteStreamLe(_difficultyTarget, stream);
     Utils.Uint32ToByteStreamLe(_nonce, stream);
 }
Example #5
0
        internal Sha256Hash ReadHash()
        {
            var hash = new byte[32];

            Array.Copy(Bytes, Cursor, hash, 0, 32);
            // We have to flip it around, as it's been read off the wire in little endian.
            // Not the most efficient way to do this but the clearest.
            hash    = Utils.ReverseBytes(hash);
            Cursor += 32;
            return(new Sha256Hash(hash));
        }
Example #6
0
 /// <exception cref="IOException"/>
 public override void BitcoinSerializeToStream(Stream stream)
 {
     stream.Write(new VarInt((ulong)_items.Count).Encode());
     foreach (var i in _items)
     {
         // Write out the type code.
         Utils.Uint32ToByteStreamLe((uint)i.Type, stream);
         // And now the hash.
         stream.Write(Utils.ReverseBytes(i.Hash.Bytes));
     }
 }
Example #7
0
 public override byte[] BitcoinSerialize()
 {
     using (var buf = new MemoryStream())
     {
         // Version, for some reason.
         Utils.Uint32ToByteStreamLe(NetworkParameters.ProtocolVersion, buf);
         // Then a vector of block hashes. This is actually a "block locator", a set of block
         // identifiers that spans the entire chain with exponentially increasing gaps between
         // them, until we end up at the genesis block. See CBlockLocator::Set()
         buf.Write(new VarInt((ulong)_locator.Count).Encode());
         foreach (var hash in _locator)
         {
             // Have to reverse as wire format is little endian.
             buf.Write(Utils.ReverseBytes(hash.Bytes));
         }
         // Next, a block ID to stop at.
         buf.Write(_stopHash.Bytes);
         return(buf.ToArray());
     }
 }
 /// <exception cref="IOException"/>
 public override void BitcoinSerializeToStream(Stream stream)
 {
     stream.Write(Utils.ReverseBytes(Hash.Bytes));
     Utils.Uint32ToByteStreamLe((uint)Index, stream);
 }