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) { } } } }
/// <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(); } }
/// <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(); } } }
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)); }
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 }); }
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; }
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)); }
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)); }
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); }
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()); }
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()); }
/// <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()); }
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()); }
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()); }
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()); }
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 }); }