private void ProcessBlockForSwapTransactions(BlockTransactionDetailsModel block, int blockHeight)
        {
            // Inspect each transaction
            foreach (TransactionVerboseModel transaction in block.Transactions)
            {
                //Find all the OP_RETURN outputs.
                foreach (Vout output in transaction.VOut.Where(o => o.ScriptPubKey.Type == "nulldata"))
                {
                    IList <Op> ops = new NBitcoin.Script(output.ScriptPubKey.Asm).ToOps();
                    var        potentialStraxAddress = Encoding.ASCII.GetString(ops.Last().PushData);
                    try
                    {
                        // Verify the sender address is a valid Strax address
                        var validStraxAddress = BitcoinAddress.Create(potentialStraxAddress, this.straxNetwork);
                        Console.WriteLine($"Swap found: {validStraxAddress}:{output.Value}");
                        var swapTransaction = new SwapTransaction()
                        {
                            BlockHeight     = blockHeight,
                            StraxAddress    = validStraxAddress.ToString(),
                            SenderAmount    = Money.Coins(output.Value),
                            TransactionHash = transaction.Hash
                        };

                        this.swapTransactions.Add(swapTransaction);
                    }
                    catch (Exception)
                    {
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Initializes an instance of the <see cref="ScriptPubKey"/> class.
        /// </summary>
        /// <param name="script">The script.</param>
        /// <param name="network">The network where the transaction was conducted.</param>
        public ScriptPubKey(NBitcoin.Script script, Network network) : base(script)
        {
            var destinations = new List <TxDestination> {
                script.GetDestination(network)
            };

            this.Type = this.GetScriptType(script.FindTemplate(network));

            if (destinations[0] == null)
            {
                destinations = script.GetDestinationPublicKeys(network).Select(p => p.Hash).ToList <TxDestination>();
            }

            if (destinations.Count == 1)
            {
                this.ReqSigs   = 1;
                this.Addresses = new List <string> {
                    destinations[0].GetAddress(network).ToString()
                };
            }
            else if (destinations.Count > 1)
            {
                PayToMultiSigTemplateParameters multi = PayToMultiSigTemplate.Instance.ExtractScriptPubKeyParameters(script);
                this.ReqSigs   = multi.SignatureCount;
                this.Addresses = multi.PubKeys.Select(m => m.GetAddress(network).ToString()).ToList();
            }
        }
예제 #3
0
        /// <summary>
        /// Initializes an instance of the <see cref="ScriptPubKey"/> class.
        /// </summary>
        /// <param name="script">The script.</param>
        /// <param name="network">The network where the transaction was conducted.</param>
        public ScriptPubKey(NBitcoin.Script script, Network network) : base(script)
        {
            var destinations = new List <TxDestination> {
                script.GetDestination(network)
            };

            this.Type = this.GetScriptType(script.FindTemplate(network));

            if (destinations[0] == null)
            {
                destinations = script.GetDestinationPublicKeys(network).Select(p => p.Hash).ToList <TxDestination>();
            }

            // TODO: We do not want to put the cold staking addresses into the 'addresses' element due to the high potential for confusion. Maybe introduce an additional element?
            if (destinations.Count == 1)
            {
                this.ReqSigs   = 1;
                this.Addresses = new List <string> {
                    destinations[0].GetAddress(network).ToString()
                };
            }
            else if (destinations.Count > 1)
            {
                PayToMultiSigTemplateParameters multi = PayToMultiSigTemplate.Instance.ExtractScriptPubKeyParameters(script) ??
                                                        PayToFederationTemplate.Instance.ExtractScriptPubKeyParameters(script, network);
                if (multi != null)
                {
                    this.ReqSigs   = multi.SignatureCount;
                    this.Addresses = multi.PubKeys.Select(m => m.GetAddress(network).ToString()).ToList();
                }
            }
        }
예제 #4
0
        public override BlockTemplate Build(ChainedHeader chainTip, Script scriptPubKey)
        {
            var rewardScript = (chainTip.Height + 1) == this.Network.Consensus.PremineHeight
                                   ? this.payToMultisigScript
                                   : this.payToMemberScript;

            return(base.Build(chainTip, rewardScript));
        }
예제 #5
0
        public void Watch(Script script)
        {
            if (this.Wallet.Scripts.Contains(script))
            {
                this.logger.LogDebug($"already watching script: {script}. coin: {this.coinType}");
                return;
            }

            this.logger.LogDebug($"added script: {script} to the watch list. coin: {this.coinType}");
            this.Wallet.Scripts.Add(script);
            this.SaveToFile();
        }
 internal static TransactionBuildContext CreateContext(WalletAccountReference accountReference, string password,
                                                       Script destinationScript, Money amount, FeeType feeType, int minConfirmations)
 {
     return(new TransactionBuildContext(accountReference,
                                        new[] { new Recipient {
                                                    Amount = amount, ScriptPubKey = destinationScript
                                                } }.ToList(), password)
     {
         MinConfirmations = minConfirmations,
         FeeType = feeType
     });
 }
예제 #7
0
        private Script GetRandomP2PKScript(out string address)
        {
            var bytes = RandomUtils.GetBytes(33);

            bytes[0] = 0x02;

            Script script = new Script() + Op.GetPushOp(bytes) + OpcodeType.OP_CHECKSIG;

            PubKey[] destinationKeys = script.GetDestinationPublicKeys(this.network);
            address = destinationKeys[0].GetAddress(this.network).ToString();

            return(script);
        }
        public ValidatedAddress ValidateAddress([FromQuery] string address)
        {
            Guard.NotEmpty(address, nameof(address));

            var result = new ValidatedAddress
            {
                IsValid = false,
                Address = address,
            };

            try
            {
                // P2WPKH
                if (BitcoinWitPubKeyAddress.IsValid(address, this.network, out Exception _))
                {
                    result.IsValid = true;
                }
                // P2WSH
                else if (BitcoinWitScriptAddress.IsValid(address, this.network, out Exception _))
                {
                    result.IsValid = true;
                }
                // P2PKH
                else if (BitcoinPubKeyAddress.IsValid(address, this.network))
                {
                    result.IsValid = true;
                }
                // P2SH
                else if (BitcoinScriptAddress.IsValid(address, this.network))
                {
                    result.IsValid  = true;
                    result.IsScript = true;
                }
            }
            catch (Exception e)
            {
                this.logger.LogDebug("Exception occurred: {0}", e.ToString());

                result.IsValid = false;
                return(result);
            }

            if (result.IsValid)
            {
                NBitcoin.Script scriptPubKey = BitcoinAddress.Create(address, this.network).ScriptPubKey;
                result.ScriptPubKey = scriptPubKey.ToHex();
                result.IsWitness    = scriptPubKey.IsWitness(this.network);
            }

            return(result);
        }
        /// <summary>
        /// Initializes an instance of the <see cref="ScriptPubKey"/> class.
        /// </summary>
        /// <param name="script">The script.</param>
        /// <param name="network">The network where the transaction was conducted.</param>
        public ScriptPubKey(NBitcoin.Script script, Network network) : base(script)
        {
            this.Type = this.GetScriptType(script.FindTemplate(network));

            // To avoid modifying the very low-level GetDestination logic, check for a cold staking script first.
            // The decision to show the cold pubkey's address in the 'addresses' list is based on the following:
            // 1. It seems more intuitive from a user's perspective that their balance will appear against this address.
            // 2. A balance should never appear against a hot address from an exchange's perspective, as they have no guarantee they will be able to spend those funds.
            // It is also presumed that it is preferable to show an address rather than not, as a block explorer would then have to show only a relatively meaningless raw script as the output's destination.
            // Another considered alternative was to show both addresses, but with a modified version byte. The underlying pubkey hashes would be the same, but the resulting addresses would be visually distinct from regular P2PKH.
            // This may have caused user confusion, however, as the modified addresses would not look like those they used to configure the cold staking setup, making searching for them on a block explorer more difficult.
            if (script.IsScriptType(ScriptType.ColdStaking))
            {
                var coldPubKeyHash = new KeyId(script.ToBytes(true).SafeSubarray(28, 20));

                this.ReqSigs   = 1;
                this.Addresses = new List <string> {
                    coldPubKeyHash.GetAddress(network).ToString()
                };

                return;
            }

            var destinations = new List <TxDestination> {
                script.GetDestination(network)
            };

            if (destinations[0] == null)
            {
                destinations = script.GetDestinationPublicKeys(network).Select(p => p.Hash).ToList <TxDestination>();
            }

            // TODO: We do not want to put the cold staking addresses into the 'addresses' element due to the high potential for confusion. Maybe introduce an additional element?
            if (destinations.Count == 1)
            {
                this.ReqSigs   = 1;
                this.Addresses = new List <string> {
                    destinations[0].GetAddress(network).ToString()
                };
            }
            else if (destinations.Count > 1)
            {
                PayToMultiSigTemplateParameters multi = PayToMultiSigTemplate.Instance.ExtractScriptPubKeyParameters(script) ??
                                                        PayToFederationTemplate.Instance.ExtractScriptPubKeyParameters(script, network);
                if (multi != null)
                {
                    this.ReqSigs   = multi.SignatureCount;
                    this.Addresses = multi.PubKeys.Select(m => m.GetAddress(network).ToString()).ToList();
                }
            }
        }
 public Vin(OutPoint prevOut, Sequence sequence, NBitcoin.Script scriptSig)
 {
     if (prevOut.Hash == uint256.Zero)
     {
         this.Coinbase = Encoders.Hex.EncodeData(scriptSig.ToBytes());
     }
     else
     {
         this.TxId      = prevOut.Hash.ToString();
         this.VOut      = prevOut.N;
         this.ScriptSig = new Script(scriptSig);
     }
     this.Sequence = (uint)sequence;
 }
예제 #11
0
        public IActionResult ValidateAddress([FromQuery] string address)
        {
            Guard.NotEmpty(address, nameof(address));

            var result = new ValidatedAddress
            {
                IsValid = false,
                Address = address,
            };

            try
            {
                // P2WPKH
                if (BitcoinWitPubKeyAddress.IsValid(address, this.network, out Exception _))
                {
                    result.IsValid = true;
                }
                // P2WSH
                else if (BitcoinWitScriptAddress.IsValid(address, this.network, out Exception _))
                {
                    result.IsValid = true;
                }
                // P2PKH
                else if (BitcoinPubKeyAddress.IsValid(address, this.network))
                {
                    result.IsValid = true;
                }
                // P2SH
                else if (BitcoinScriptAddress.IsValid(address, this.network))
                {
                    result.IsValid  = true;
                    result.IsScript = true;
                }
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }

            if (result.IsValid)
            {
                NBitcoin.Script scriptPubKey = BitcoinAddress.Create(address, this.network).ScriptPubKey;
                result.ScriptPubKey = scriptPubKey.ToHex();
                result.IsWitness    = scriptPubKey.IsWitness(this.network);
            }

            return(this.Json(result));
        }
예제 #12
0
        private BitcoinAddress GetAddressFromScriptPubKey(Script scriptPubKey)
        {
            BitcoinAddress address = scriptPubKey.GetDestinationAddress(this.network);

            if (address == null)
            {
                // Handle P2PK
                PubKey[] destinationKeys = scriptPubKey.GetDestinationPublicKeys(this.network);

                if (destinationKeys.Length == 1)
                {
                    address = destinationKeys[0].GetAddress(this.network);
                }
            }

            return(address);
        }
 /// <inheritdoc />
 public FederatedPegBlockDefinition(
     IBlockBufferGenerator blockBufferGenerator,
     ICoinView coinView,
     IConsensusManager consensusManager,
     IDateTimeProvider dateTimeProvider,
     IContractExecutorFactory executorFactory,
     ILoggerFactory loggerFactory,
     ITxMempool mempool,
     MempoolSchedulerLock mempoolLock,
     Network network,
     ISenderRetriever senderRetriever,
     IStateRepositoryRoot stateRoot,
     IFederationGatewaySettings federationGatewaySettings)
     : base(blockBufferGenerator, coinView, consensusManager, dateTimeProvider, executorFactory, loggerFactory, mempool, mempoolLock, network, senderRetriever, stateRoot)
 {
     this.payToMultisigScript = federationGatewaySettings.MultiSigAddress.ScriptPubKey;
     this.payToMemberScript   = PayToPubkeyTemplate.Instance.GenerateScriptPubKey(new PubKey(federationGatewaySettings.PublicKey));
 }
예제 #14
0
        private AddressIndexData GetOrCreateAddressData(Script scriptPubKey)
        {
            byte[] scriptPubKeyBytes = scriptPubKey.ToBytes();

            AddressIndexData addrData = this.addressesIndex.AddressIndexDatas.SingleOrDefault(x => StructuralComparisons.StructuralEqualityComparer.Equals(scriptPubKeyBytes, x.ScriptPubKeyBytes));

            if (addrData == null)
            {
                addrData = new AddressIndexData()
                {
                    ScriptPubKeyBytes = scriptPubKeyBytes,
                    Changes           = new List <AddressBalanceChange>()
                };

                this.addressesIndex.AddressIndexDatas.Add(addrData);
                return(addrData);
            }

            return(addrData);
        }
예제 #15
0
        private async Task ProcessBlockForCollateralVoteTransactionsAsync(BlockTransactionDetailsModel block, int blockHeight)
        {
            // Inspect each transaction
            foreach (TransactionVerboseModel transaction in block.Transactions)
            {
                // Find the first the OP_RETURN output.
                Vout opReturnOutput = transaction.VOut.FirstOrDefault(v => v.ScriptPubKey.Type == "nulldata");
                if (opReturnOutput == null)
                {
                    continue;
                }

                // Before checking if it's a vote, check if it's a swap transaction as we now know it has an OP_RETURN.
                // Ignore any transactions that have inconsequential OP_RETURN values.
                if (opReturnOutput.Value >= 1.0m)
                {
                    // For the purposes of speeding up this search, it doesn't matter per se whether the burn transaction has a valid destination address in it.

                    TransactionModel tx = this.blockExplorerClient.GetTransaction(transaction.TxId);

                    // Check the inputs of the transaction to see if it was funded by one of the vote addresses.
                    string address = null;
                    foreach (In input in tx._in)
                    {
                        if (input.hash == null)
                        {
                            continue;
                        }

                        // The block explorer calls this 'hash' but it is in fact the address that funded the input.
                        // It is possible that several voting addresses consolidated together in one swap transaction, so just take the first one.
                        if (this.collateralVotes.ContainsKey(input.hash))
                        {
                            if (address == null)
                            {
                                // We will assign the entire burn amount to the first found voting address.
                                address = input.hash;
                            }
                            else
                            {
                                // However, we have to recompute the balance of all the vote addresses present in the inputs that we are not going to assign the burn to.
                                // This is because they will not necessarily be revisited later if there are no further transactions affecting them.
                                // We presume that since they are participating in a burn subsequent to their initial vote, their balance will drop.
                                if (!address.Equals(input.hash))
                                {
                                    AddressBalancesResult balance = await $"http://localhost:{this.StratisNetworkApiPort}/api"
                                                                    .AppendPathSegment($"blockstore/{BlockStoreRouteEndPoint.GetAddressesBalances}")
                                                                    .SetQueryParams(new { addresses = input.hash, minConfirmations = 0 })
                                                                    .GetJsonAsync <AddressBalancesResult>();

                                    Console.WriteLine($"Reset balance for '{input.hash}' to {balance.Balances[0].Balance} due to burn transaction {transaction.TxId} at height {blockHeight}");

                                    this.collateralVotes[input.hash].Balance = balance.Balances[0].Balance;
                                }
                            }
                        }
                    }

                    if (address != null)
                    {
                        this.collateralVotes[address].BlockHeight = blockHeight;
                        this.collateralVotes[address].Balance     = Money.Coins(opReturnOutput.Value);

                        Console.WriteLine($"Detected that address '{address}' burnt {opReturnOutput.Value} via transaction {transaction.TxId} at height {blockHeight}");

                        // We can now skip checking if this output was a vote.
                        continue;
                    }
                }

                IList <Op> ops           = new NBitcoin.Script(opReturnOutput.ScriptPubKey.Asm).ToOps();
                var        potentialVote = Encoding.ASCII.GetString(ops.Last().PushData);
                try
                {
                    var isVote = potentialVote.Substring(0, 1);
                    if (isVote != "V")
                    {
                        continue;
                    }

                    var isCollateralVote = potentialVote.Substring(1, 1);
                    if (isCollateralVote != "C")
                    {
                        continue;
                    }

                    var collateralVote = potentialVote.Substring(2, 1);
                    if (!new[] { "A", "B", "C", "D", "E" }.Contains(collateralVote))
                    {
                        Console.WriteLine($"Invalid vote found '{collateralVote}'; height {blockHeight}.");
                        continue;
                    }

                    // Verify the sender address is a valid Strat address
                    var potentialStratAddress       = potentialVote.Substring(3);
                    ValidatedAddress validateResult = await $"http://localhost:{this.StratisNetworkApiPort}/api"
                                                      .AppendPathSegment("node/validateaddress")
                                                      .SetQueryParams(new { address = potentialStratAddress })
                                                      .GetJsonAsync <ValidatedAddress>();

                    if (!validateResult.IsValid)
                    {
                        Console.WriteLine($"Invalid STRAT address: '{potentialStratAddress}'");
                        continue;
                    }

                    AddressBalancesResult balance = await $"http://localhost:{this.StratisNetworkApiPort}/api"
                                                    .AppendPathSegment($"blockstore/{BlockStoreRouteEndPoint.GetAddressesBalances}")
                                                    .SetQueryParams(new { addresses = potentialStratAddress, minConfirmations = 0 })
                                                    .GetJsonAsync <AddressBalancesResult>();

                    Money determinedBalance = balance.Balances[0].Balance;

                    if (!this.collateralVotes.ContainsKey(potentialStratAddress))
                    {
                        Console.WriteLine($"Collateral vote found for {potentialStratAddress} at height {blockHeight}; Selection '{collateralVote}'; Balance {determinedBalance}");

                        this.collateralVotes.Add(potentialStratAddress, new CollateralVote()
                        {
                            Address = potentialStratAddress, Balance = determinedBalance, Selection = collateralVote, BlockHeight = blockHeight
                        });
                    }
                    else
                    {
                        Console.WriteLine($"Updating existing vote for {potentialStratAddress} at height {blockHeight}; Selection '{collateralVote}'; Balance {determinedBalance}");

                        this.collateralVotes[potentialStratAddress] = new CollateralVote()
                        {
                            Address = potentialStratAddress, Balance = determinedBalance, Selection = collateralVote, BlockHeight = blockHeight
                        };
                    }
                }
                catch (Exception)
                {
                }
            }
        }
        public void IsSmartContractInternalCall_Failure()
        {
            var script = new NBitcoin.Script(new byte[] { 0xFF, (byte)ScOpcodeType.OP_INTERNALCONTRACTTRANSFER, 0xFF });

            Assert.False(script.IsSmartContractInternalCall());
        }
예제 #17
0
파일: Program.cs 프로젝트: zilveer/BitPoker
        private static async Task CreateLightningTx()
        {
            //Begin lightning test
            //For testing

            NBitcoin.Transaction aliceFunding = new NBitcoin.Transaction()
            {
                Outputs =
                {
                    new NBitcoin.TxOut("1.0", alice)
                }
            };

            NBitcoin.Coin[] aliceCoinsx = aliceFunding
                                          .Outputs
                                          .Select((o, i) => new NBitcoin.Coin(new NBitcoin.OutPoint(aliceFunding.GetHash(), i), o))
                                          .ToArray();

            //Create 2 of 2
            NBitcoin.Script table = NBitcoin.PayToMultiSigTemplate
                                    .Instance
                                    .GenerateScriptPubKey(2, new[] { alice_secret.PubKey, alice_secret.PubKey });


            Console.WriteLine(table);
            Console.WriteLine(table.Hash.GetAddress(NBitcoin.Network.TestNet));

            NBitcoin.IDestination tableAddress = table.Hash.GetAddress(NBitcoin.Network.TestNet);


            var         blockr  = new NBitcoin.BlockrTransactionRepository(NBitcoin.Network.TestNet);
            Transaction aliceTx = blockr.GetAsync(new NBitcoin.uint256("f5c5e008f0cb9fc52487deb7531a8019e2d78c51c3c40e53a45248e0712102a3")).Result;

            NBitcoin.Transaction bobTx = blockr.GetAsync(new NBitcoin.uint256("c60193a33174a1252df9deb522bac3e5532e0c756d053e4ac9999ca17a79c74e")).Result;

            NBitcoin.Coin[] alicCoins = aliceTx
                                        .Outputs
                                        .Select((o, i) => new NBitcoin.Coin(new NBitcoin.OutPoint(aliceTx.GetHash(), i), o))
                                        .ToArray();

            Coin[] bobCoins = bobTx
                              .Outputs
                              .Select((o, i) => new NBitcoin.Coin(new NBitcoin.OutPoint(bobTx.GetHash(), i), o))
                              .ToArray();

            var txBuilder = new TransactionBuilder();

            var tx_alice = txBuilder
                           .AddKeys(alice_secret.PrivateKey)
                           .AddCoins(alicCoins)
                           .Send(tableAddress, new NBitcoin.Money(5000000))
                           .SetChange(alice)
                           .SendFees(NBitcoin.Money.Coins(0.001m))
                           .BuildTransaction(true);

            //Console.WriteLine(tx_alice.ToHex());

            string signature = alice_secret.PrivateKey.SignMessage("1msPJhg9GPzMN6twknwmSQvrUKZbZnk51Tv398b5fe2-da27-4772-81ce-37fa615719b52CALL 5000000");

            Console.WriteLine(signature);

            Console.ReadKey();

            var tx = txBuilder
                     .AddKeys(bob_secret.PrivateKey)
                     .AddCoins(bobCoins)
                     .Send(tableAddress, new NBitcoin.Money(100000))
                     .SetChange(bob)
                     .SendFees(NBitcoin.Money.Coins(0.001m))
                     .BuildTransaction(true);

            Boolean ok = txBuilder.Verify(tx);

            signature = bob_secret.PrivateKey.SignMessage("CALL 100000");
            Console.WriteLine(signature);

            //BE.Providers.Blockr blockr = new BE.Providers.Blockr(true);
            //return blockr.BroadCastTx(tx.ToHex());

            Console.WriteLine(tx.ToHex());
        }
예제 #18
0
 /// <summary>
 /// Initializes a transaction <see cref="Script"/>, which contains the assembly and a hexadecimal representation of the script.
 /// </summary>
 /// <param name="script">A <see cref="NBitcoin.Script"/>.</param>
 public Script(NBitcoin.Script script)
 {
     this.Asm = script.ToString();
     this.Hex = Encoders.Hex.EncodeData(script.ToBytes());
 }
예제 #19
0
 protected abstract bool CheckScriptSigCore(Script scriptSig, Op[] scriptSigOps, Script scriptPubKey, Op[] scriptPubKeyOps);
        public void IsSmartContractSpend_Success()
        {
            var script = new NBitcoin.Script(new byte[] { (byte)ScOpcodeType.OP_SPEND });

            Assert.True(script.IsSmartContractSpend());
        }
예제 #21
0
 protected virtual bool FastCheckScriptSig(Script scriptSig, Script scriptPubKey)
 {
     return(true);
 }
        public void IsSmartContractCreate_Success()
        {
            var script = new NBitcoin.Script(new byte[] { (byte)ScOpcodeType.OP_CREATECONTRACT });

            Assert.True(script.IsSmartContractCreate());
        }
        public void IsSmartContractExec_CallContract_Failure()
        {
            var script = new NBitcoin.Script(new byte[] { 0xFF, (byte)ScOpcodeType.OP_CALLCONTRACT, 0xFF });

            Assert.False(script.IsSmartContractExec());
        }
예제 #24
0
        private async Task ProcessBlockForSwapVoteTransactionsAsync(BlockTransactionDetailsModel block, int blockHeight)
        {
            // Inspect each transaction
            foreach (TransactionVerboseModel transaction in block.Transactions)
            {
                // Find the first the OP_RETURN output.
                Vout opReturnOutput = transaction.VOut.FirstOrDefault(v => v.ScriptPubKey.Type == "nulldata");
                if (opReturnOutput == null)
                {
                    continue;
                }

                IList <Op> ops           = new NBitcoin.Script(opReturnOutput.ScriptPubKey.Asm).ToOps();
                var        potentialVote = Encoding.ASCII.GetString(ops.Last().PushData);
                try
                {
                    var isVote = potentialVote.Substring(0, 1);
                    if (isVote != "V")
                    {
                        continue;
                    }

                    var isVoteValue = potentialVote.Substring(1, 1);
                    if (isVoteValue == "1" || isVoteValue == "0")
                    {
                        // Verify the sender address is a valid Strat address
                        var potentialStratAddress       = potentialVote.Substring(2);
                        ValidatedAddress validateResult = await $"http://localhost:{this.StratisNetworkApiPort}/api"
                                                          .AppendPathSegment("node/validateaddress")
                                                          .SetQueryParams(new { address = potentialStratAddress })
                                                          .GetJsonAsync <ValidatedAddress>();

                        if (!validateResult.IsValid)
                        {
                            Console.WriteLine($"Invalid STRAT address: '{potentialStratAddress}'");
                            continue;
                        }

                        AddressBalancesResult balance = await $"http://localhost:{this.StratisNetworkApiPort}/api"
                                                        .AppendPathSegment($"blockstore/{BlockStoreRouteEndPoint.GetAddressesBalances}")
                                                        .SetQueryParams(new { addresses = potentialStratAddress, minConfirmations = 0 })
                                                        .GetJsonAsync <AddressBalancesResult>();

                        if (isVoteValue == "0")
                        {
                            this.castVotes.Add(new CastVote()
                            {
                                Address = potentialStratAddress, Balance = balance.Balances[0].Balance, InFavour = false, BlockHeight = blockHeight
                            });
                            Console.WriteLine($"'No' vote found at height {blockHeight}.");
                        }

                        if (isVoteValue == "1")
                        {
                            this.castVotes.Add(new CastVote()
                            {
                                Address = potentialStratAddress, Balance = balance.Balances[0].Balance, InFavour = true, BlockHeight = blockHeight
                            });
                            Console.WriteLine($"'Yes' vote found at height {blockHeight}.");
                        }
                    }
                }
                catch (Exception)
                {
                }
            }
        }
        public void IsSmartContractExec_CallContract_Success()
        {
            var script = new NBitcoin.Script(new byte[] { (byte)ScOpcodeType.OP_CALLCONTRACT });

            Assert.True(script.IsSmartContractExec());
        }
        public void IsSmartContractSpend_Failure()
        {
            var script = new NBitcoin.Script(new byte[] { 0xFF, (byte)ScOpcodeType.OP_SPEND, 0xFF });

            Assert.False(script.IsSmartContractSpend());
        }
예제 #27
0
        public void CanIndexAddresses()
        {
            List <ChainedHeader> headers = ChainedHeadersHelper.CreateConsecutiveHeaders(100, null, false, null, this.network);

            this.consensusManagerMock.Setup(x => x.Tip).Returns(() => headers.Last());

            Script p2pk1 = this.GetRandomP2PKScript(out string address1);
            Script p2pk2 = this.GetRandomP2PKScript(out string address2);

            var block1 = new Block()
            {
                Transactions = new List <Transaction>()
                {
                    new Transaction()
                    {
                        Outputs =
                        {
                            new TxOut(new Money(10_000), p2pk1),
                            new TxOut(new Money(20_000), p2pk1),
                            new TxOut(new Money(30_000), p2pk1)
                        }
                    }
                }
            };

            var block5 = new Block()
            {
                Transactions = new List <Transaction>()
                {
                    new Transaction()
                    {
                        Outputs =
                        {
                            new TxOut(new Money(10_000), p2pk1),
                            new TxOut(new Money(1_000),  p2pk2),
                            new TxOut(new Money(1_000),  p2pk2)
                        }
                    }
                }
            };

            var tx = new Transaction();

            tx.Inputs.Add(new TxIn(new OutPoint(block5.Transactions.First().GetHash(), 0)));
            var block10 = new Block()
            {
                Transactions = new List <Transaction>()
                {
                    tx
                }
            };

            this.consensusManagerMock.Setup(x => x.GetBlockData(It.IsAny <uint256>())).Returns((uint256 hash) =>
            {
                ChainedHeader header = headers.SingleOrDefault(x => x.HashBlock == hash);

                switch (header?.Height)
                {
                case 1:
                    return(new ChainedHeaderBlock(block1, header));

                case 5:
                    return(new ChainedHeaderBlock(block5, header));

                case 10:
                    return(new ChainedHeaderBlock(block10, header));
                }

                return(new ChainedHeaderBlock(new Block(), header));
            });

            this.addressIndexer.Initialize();

            TestBase.WaitLoop(() => this.addressIndexer.IndexerTip == headers.Last());

            Assert.Equal(60_000, this.addressIndexer.GetAddressBalances(new[] { address1 }).Balances.First().Balance.Satoshi);
            Assert.Equal(2_000, this.addressIndexer.GetAddressBalances(new[] { address2 }).Balances.First().Balance.Satoshi);

            Assert.Equal(70_000, this.addressIndexer.GetAddressBalances(new[] { address1 }, 93).Balances.First().Balance.Satoshi);

            // Now trigger rewind to see if indexer can handle reorgs.
            ChainedHeader forkPoint = headers.Single(x => x.Height == 8);

            List <ChainedHeader> headersFork = ChainedHeadersHelper.CreateConsecutiveHeaders(100, forkPoint, false, null, this.network);

            this.consensusManagerMock.Setup(x => x.GetBlockData(It.IsAny <uint256>())).Returns((uint256 hash) =>
            {
                ChainedHeader headerFork = headersFork.SingleOrDefault(x => x.HashBlock == hash);

                return(new ChainedHeaderBlock(new Block(), headerFork));
            });

            this.consensusManagerMock.Setup(x => x.Tip).Returns(() => headersFork.Last());
            TestBase.WaitLoop(() => this.addressIndexer.IndexerTip == headersFork.Last());

            Assert.Equal(70_000, this.addressIndexer.GetAddressBalances(new[] { address1 }).Balances.First().Balance.Satoshi);

            this.addressIndexer.Dispose();
        }
        public void IsSmartContractInternalCall_Success()
        {
            var script = new NBitcoin.Script(new byte[] { (byte)ScOpcodeType.OP_INTERNALCONTRACTTRANSFER });

            Assert.True(script.IsSmartContractInternalCall());
        }
        public void IsSmartContractCreate_Failure()
        {
            var script = new NBitcoin.Script(new byte[] { 0xFF, (byte)ScOpcodeType.OP_CREATECONTRACT, 0xFF });

            Assert.False(script.IsSmartContractCreate());
        }
        internal static TransactionData CreateTransaction(uint256 id, Money amount, int?blockHeight, SpendingDetails spendingDetails = null, DateTimeOffset?creationTime = null, Script script = null)
        {
            if (creationTime == null)
            {
                creationTime = new DateTimeOffset(new DateTime(2017, 6, 23, 1, 2, 3));
            }

            return(new TransactionData()
            {
                Amount = amount,
                Id = id,
                CreationTime = creationTime.Value,
                BlockHeight = blockHeight,
                SpendingDetails = spendingDetails,
                ScriptPubKey = script
            });
        }