예제 #1
0
        public void WhenGetUnspentTransactionsTwoBlocks()
        {
            RemoveBlockChain();
            var serviceProvider     = BuildServiceProvider();
            var blockChainFactory   = serviceProvider.GetService <IBlockChainFactory>();
            var blockChain          = blockChainFactory.Build(_network);
            var genesisBlock        = blockChain.GetCurrentBlock();
            var firstTransaction    = genesisBlock.Transactions.First() as BcBaseTransaction;
            var firstTransactionOut = firstTransaction.TransactionOut.First();

            var genesisKey = KeyStore.GetGenesisKey();
            var genesisAdr = new BlockChainAddress(_scriptTypes, _network, genesisKey); // Create block chain address.
            var destinationBlockChainAddress = GenerateBlockChainAddress();
            var minerBlockChainAddress       = GenerateBlockChainAddress();

            var signature     = genesisKey.GetSignature(); // Create the script.
            var scriptBuilder = new ScriptBuilder();
            var genesisScript = scriptBuilder
                                .New()
                                .AddToStack(signature)
                                .AddToStack(genesisKey.GetPublicKey())
                                .Build();
            var destinationScript = Script.CreateP2PKHScript(destinationBlockChainAddress.PublicKeyHash);
            var minerScript       = Script.CreateP2PKHScript(minerBlockChainAddress.PublicKeyHash);
            var genesisScriptDest = Script.CreateP2PKHScript(genesisKey.GetPublicKeyHashed());

            var transactionBuilder  = new TransactionBuilder();
            var coinBaseTransaction = transactionBuilder // Add COIN-BASE TRANSACTION.
                                      .NewCoinbaseTransaction()
                                      .SetBlockNumber(1)
                                      .AddOutput(1, minerScript)
                                      .Build();
            var noneCoinBaseTransaction = transactionBuilder // ADD GENESIS (10 BTC) => DESTINATION TRANSACTION.
                                          .NewNoneCoinbaseTransaction()
                                          .Spend(firstTransaction, 0, genesisScript.Serialize())
                                          .AddOutput(10, destinationScript)
                                          .Build();
            var otherCoinBaseTransaction = transactionBuilder
                                           .NewNoneCoinbaseTransaction()
                                           .Spend(firstTransaction, 0, genesisScript.Serialize())
                                           .AddOutput(39, genesisScriptDest)
                                           .Build();

            var nonce = NonceHelper.GetNonceUInt32(); // CREATE A BLOCK.
            var block = new Block(genesisBlock.GetHashHeader(), Constants.DEFAULT_NBITS, nonce);

            block.Transactions.Add(coinBaseTransaction);
            block.Transactions.Add(noneCoinBaseTransaction);
            block.Transactions.Add(otherCoinBaseTransaction);
            var a = noneCoinBaseTransaction.Serialize().ToArray();
            var b = BcBaseTransaction.Deserialize(a);

            block.UpdateMerkleRoot();
            blockChain.AddBlock(block);
            var unspentTransactions = blockChain.GetUnspentTransactions();

            Assert.IsNotNull(unspentTransactions);
            Assert.IsTrue(unspentTransactions.Count() == 3);
            Assert.IsTrue(unspentTransactions.Sum(t => t.Value) == 50);
        }
예제 #2
0
        private void CheckPeerAvailability(object sender, DoWorkEventArgs e)
        {
            var callback = new Action(() =>
            {
                if (TimeOutEvent != null)
                {
                    TimeOutEvent(this, new IpAddressEventArgs(_currentIpAddress));
                }
            });
            var nonce       = NonceHelper.GetNonceUInt64();
            var pingMessage = new PingMessage(nonce, _network);

            try
            {
                var result = _messageCoordinator.Launch(this, pingMessage);
                if (result == null)
                {
                    callback();
                    return;
                }

                var pongMessage = result as PongMessage;
                if (pongMessage.Nonce != nonce)
                {
                    callback();
                }
            }
            catch (Interop.RpcException)
            {
                callback();
            }
        }
 public void WhenBuildCoinbaseTransaction()
 {
     var ba          = BuildBlockChainAddress();
     var builder     = new TransactionBuilder();
     var nonce       = BitConverter.GetBytes(NonceHelper.GetNonceUInt64());
     var transaction = builder.NewCoinbaseTransaction()
                       .SetInput(4, nonce)
                       .AddOutput(20, Script.CreateP2PKHScript(ba.PublicKeyHash))
                       .Build();
     var serializedTransaction = transaction.Serialize();
 }
예제 #4
0
        public void Connect(string host, ServiceFlags serviceFlag)
        {
            if (string.IsNullOrWhiteSpace(host))
            {
                throw new ArgumentNullException(nameof(host));
            }

            var       iid   = Interop.Constants.InterfaceId;
            var       port  = PortsHelper.GetPort(_network);
            IPAddress ipAdr = null;

            if (!IPAddress.TryParse(host, out ipAdr))
            {
                // TODO : Throw an exception.
            }

            var adrBytes = ipAdr.MapToIPv6().GetAddressBytes();

            _serviceFlag      = serviceFlag;
            _currentIpAddress = new IpAddress(serviceFlag, adrBytes, ushort.Parse(port));
            // _client = new RpcClientApi(iid, RpcProtseq.ncacn_ip_tcp, host, port);
            _client = new RpcClientApi(iid, RpcProtseq.ncalrpc, null, host);
            // Connection to peers : https://bitcoin.org/en/developer-guide#connecting-to-peers
            var instance         = PeersStore.Instance();
            var transmittingNode = instance.GetMyIpAddress();
            var nonce            = NonceHelper.GetNonceUInt64();
            var versionMessage   = new VersionMessage(transmittingNode, _currentIpAddress, nonce, string.Empty, 0, false, _network);

            try
            {
                _peerConnection = new PeerConnection(adrBytes);
                var result = _messageCoordinator.Launch(this, versionMessage);
                if (result != null && result is VerackMessage)
                {
                    _peerConnection.Connect();
                    if (ConnectEvent != null)
                    {
                        ConnectEvent(this, new IpAddressEventArgs(_currentIpAddress));
                    }

                    _timer = new Timer(TimerElapsed, _autoEvent, CHECK_INTERVAL, CHECK_INTERVAL); // CHECK PEERS AVAILABILITY EVERY 60 SECONDS.
                }
            }
            catch (Interop.RpcException)
            {
                throw new PeerConnectorException(ErrorCodes.PeerRpcError);
            }
        }
예제 #5
0
        private JObject GetBlockTemplate(JObject response)
        {
            var transactions = MemoryPool.Instance().GetTransactions();
            var blockChain   = _blockChainStore.GetBlockChain();

            if (transactions == null || !transactions.Any())
            {
                response["result"] = null;
                return(response);
            }

            var currentBlock       = blockChain.GetCurrentBlock();
            var height             = blockChain.GetCurrentBlockHeight();
            var previousBlockHash  = currentBlock.GetHashHeader().ToHexString();
            var transactionBuilder = new TransactionBuilder();
            var nonce = BitConverter.GetBytes(NonceHelper.GetNonceUInt64());
            var value = transactions.Sum(t => _transactionHelper.GetFee(t.Transaction, _network));
            var coinBaseTransaction = transactionBuilder.NewCoinbaseTransaction()
                                      .SetInput((uint)height + 1, nonce)
                                      .AddOutput(value, Script.CreateCorrectScript())
                                      .Build();
            var result        = new JObject();
            var jTransactions = new JArray();

            foreach (var transaction in transactions)
            {
                jTransactions.Add(transaction.Transaction.Serialize().ToHexString());
            }


            var currentTime    = DateTime.UtcNow.ToUnixTimeUInt32();
            var coinBaseTxnObj = new JObject();

            coinBaseTxnObj.Add("data", coinBaseTransaction.Serialize().ToHexString());
            result.Add("coinbasetxn", coinBaseTxnObj);
            result.Add("expires", "120");
            result.Add("longpollid", "");
            result.Add("height", blockChain.GetCurrentBlockHeight() + 1);
            result.Add("curtime", currentTime);
            result.Add("previousblockhash", previousBlockHash);
            result.Add("transactions", jTransactions);
            result.Add("version", BlockHeader.CURRENT_VERSION);
            result.Add("target", TargetHelper.GetTarget(Constants.DEFAULT_NBITS).ToHexString());
            result.Add("bits", Constants.DEFAULT_NBITS);
            response["result"] = result;
            return(response);
        }
예제 #6
0
        public void WhenSerializeBlockWithOneCoinbaseTransaction()
        {
            var ba          = BuildBlockChainAddress();
            var builder     = new TransactionBuilder();
            var nonce       = BitConverter.GetBytes(NonceHelper.GetNonceUInt64());
            var transaction = builder.NewCoinbaseTransaction()
                              .SetInput(4, nonce)
                              .AddOutput(20, Script.CreateP2PKHScript(ba.PublicKeyHash))
                              .Build();

            var block = new Block(null, NBits, NonceHelper.GetNonceUInt32());

            block.Transactions.Add(transaction);
            var serializedBlock = block.Serialize();

            var    des = Block.Deserialize(serializedBlock);
            string s   = "";
        }
예제 #7
0
        public void WhenSerializeAndDeserializeBlockWithOneSContract()
        {
            var smartContractTransaction = new SmartContractTransaction
            {
                Data = new byte[4] {
                    9, 8, 7, 4
                },
                From = new byte[3] {
                    1, 2, 3
                },
                Nonce = 988
            };
            var block = new Block(null, NBits, NonceHelper.GetNonceUInt32());

            block.Transactions.Add(smartContractTransaction);
            var exceptedBlockHeader = block.GetHashHeader();
            var serializedBlock     = block.Serialize();
            var deserializedBlock   = Block.Deserialize(serializedBlock);
            var blockHeader         = deserializedBlock.GetHashHeader();

            Assert.IsTrue(blockHeader.SequenceEqual(exceptedBlockHeader));
        }
예제 #8
0
        private void PublishContract(object sender, EventArgs e)
        {
            if (_viewModel == null)
            {
                return;
            }
            var authenticatedWallet = WalletStore.Instance().GetAuthenticatedWallet();

            if (authenticatedWallet == null)
            {
                MainWindowStore.Instance().DisplayError("You're not authenticated");
                return;
            }

            if (string.IsNullOrWhiteSpace(_viewModel.SmartContract))
            {
                MainWindowStore.Instance().DisplayError("The solidity contract must be filled in");
                return;
            }

            var rpcClient = new RpcClient(authenticatedWallet.Network);

            _publishedSolidityContract = null;
            rpcClient.CompileSolidity(_viewModel.SmartContract).ContinueWith((t) =>
            {
                try
                {
                    var compilationResult = t.Result;
                    if (compilationResult.Infos == null || !compilationResult.Infos.Any())
                    {
                        return;
                    }

                    UpdateSmartContractDefinition(compilationResult);
                    var newKey   = _walletHelper.CreateNewAddress();
                    var fromAddr = newKey.GetPublicKeyHashed();
                    var smartContractTransaction = new SmartContractTransaction
                    {
                        From  = fromAddr,
                        Data  = compilationResult.Infos.First().Code.FromHexString(),
                        Nonce = NonceHelper.GetNonceInt32()
                    };
                    rpcClient.SendRawTransaction(smartContractTransaction).ContinueWith((c) =>
                    {
                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            _viewModel.TransactionId = c.Result;
                        });
                        _publishedSolidityContract = new SolidityContractAggregate
                        {
                            Abi  = compilationResult.Infos.First().AbiDefinition.ToString(),
                            Code = compilationResult.Infos.First().Code
                        };
                    });
                }
                catch (AggregateException)
                {
                    Application.Current.Dispatcher.Invoke(() => MainWindowStore.Instance().DisplayError("An error occured while trying to build the solidity contract"));
                }
            });
        }