Пример #1
0
        /// <summary>
        /// Reads a single transaction off the blockchain in sequential order
        ///
        /// thanks
        /// https://en.bitcoin.it/wiki/Protocol_specification#block
        /// http://james.lab6.com/2012/01/12/bitcoin-285-bytes-that-changed-the-world/
        /// https://code.google.com/p/blockchain/source/browse/trunk/BlockChain.h
        /// </summary>
        public Boolean Read()
        {
            var newBlock = new BitcoinBlock {
                MagicBytes = Dequeue(4)
            };

            if (BitConverter.ToUInt32(newBlock.MagicBytes, 0) != 3652501241)
            {
                throw new Exception("Invalid magic number at the start of this block");
            }

            newBlock.BlockSize          = BitConverter.ToUInt32(Dequeue(4), 0);
            newBlock.BlockFormatVersion = BitConverter.ToUInt32(Dequeue(4), 0);
            newBlock.PreviousBlockHash  = ReverseArray(Dequeue(32));
            newBlock.MerkleRoot         = ReverseArray(Dequeue(32));
            newBlock.TimeStamp          = Helper.UnixToDateTime(BitConverter.ToUInt32(Dequeue(4), 0));
            newBlock.Bits             = BitConverter.ToUInt32(Dequeue(4), 0);
            newBlock.Nonce            = BitConverter.ToUInt32(Dequeue(4), 0);
            newBlock.TransactionCount = ReadVariableLengthInteger(Dequeue(1));

            for (var t = 0; t < newBlock.TransactionCount; t++)
            {
                var newTransaction = new BitcoinTransaction();
                newTransaction.TransactionVersionNumber = BitConverter.ToUInt32(Dequeue(4), 0);
                newTransaction.InputCount = ReadVariableLengthInteger(Dequeue(1));

                for (var i = 0; i < newTransaction.InputCount; i++)
                {
                    var newInput = new BitcoinInput();
                    newInput.InputTransactionHash  = Dequeue(32);
                    newInput.InputTransactionIndex = BitConverter.ToUInt32(Dequeue(4), 0);
                    newInput.ResponseScriptLength  = ReadVariableLengthInteger(Dequeue(1));
                    newInput.ResponseScript        = Dequeue((int)newInput.ResponseScriptLength);
                    newInput.SequenceNumber        = BitConverter.ToUInt32(Dequeue(4), 0);
                    newTransaction.Inputs.Add(newInput);
                }

                newTransaction.OutputCount = ReadVariableLengthInteger(Dequeue(1));

                for (var o = 0; o < newTransaction.OutputCount; o++)
                {
                    var newOutput = new BitcoinOutput();
                    newOutput.OutputValue           = BitConverter.ToUInt64(Dequeue(8), 0);
                    newOutput.ChallengeScriptLength = ReadVariableLengthInteger(Dequeue(1));
                    newOutput.ChallengeScript       = Dequeue((int)newOutput.ChallengeScriptLength);
                    newOutput.EcdsaPublickey        = ExtractPublicKey(newOutput.ChallengeScript);
                    newOutput.BitcoinAddress        = ComputeBitcoinAddress(newOutput.EcdsaPublickey); // todo: expensive operation, should it be a feature flag?
                    newTransaction.Outputs.Add(newOutput);
                }

                newTransaction.LockTime = BitConverter.ToUInt32(Dequeue(4), 0);
                newBlock.Transactions.Add(newTransaction);
            }

            CurrentBlock = newBlock;
            return(true);
        }
Пример #2
0
        public static void Main(string[] args)
        {
            string             hash        = "0ade9b2864672074864c1d509ac427ffdcf16fe983ef6ebe8b0606afd3fb50a4";
            BitcoinTransaction transaction = BlockchainAPI.GetTransaction(hash);

            Console.WriteLine("Block Number = {0}", transaction.BlockHeight);

            BitcoinBlock latestBlock = BlockchainAPI.GetLatestBlock();

            Console.WriteLine("LatestBlock = {0}", latestBlock.BlockHeight);

            Console.WriteLine("Number of Confirmations = {0}", latestBlock.BlockHeight - transaction.BlockHeight);

            Console.ReadLine();
        }
Пример #3
0
        private async Task ReadNewBlocksAsync(Func <GetBlockRpcModel, Task> saveTransactions)
        {
            var hashToImport = await _lastImportendBlockHash.GetAsync();

            if (string.IsNullOrEmpty(hashToImport))
            {
                hashToImport = _firstBlock;
            }

            var block = await _bitcoinRpc.GetBlockAsync(hashToImport);

            while (true)
            {
                var newBlock = new BitcoinBlock
                {
                    Hash              = block.Hash,
                    Time              = block.GetTime(),
                    Height            = block.Height,
                    Merkleroot        = block.Merkleroot,
                    Nonce             = block.Nonce,
                    Difficulty        = block.Difficulty,
                    Previousblockhash = block.Previousblockhash,
                    Nextblockhash     = block.Nextblockhash,
                    TotalTransactions = block.Tx.Length
                };

                //Console.WriteLine("\n block - " + newBlock.Hash + " room block " + newBlock.Height);
                await _bitcoinBlockRepository.SaveAsync(newBlock);
                await saveTransactions(block);

                await _lastImportendBlockHash.SetAsync(block.Hash, block.Height);

                if (block.IsLastBlock())
                {
                    //Console.WriteLine("block - " + newBlock.Hash + " room block " + newBlock.Height);
                    //Console.WriteLine("It was the last block.");
                    break;
                }


                block = await _bitcoinRpc.GetBlockAsync(block.Nextblockhash);
            }
        }