Exemple #1
0
 private void setupCoinReferenceWithVals(CoinReference coinRef, out UInt256 prevHashVal, out ushort prevIndexVal)
 {
     prevHashVal       = new UInt256(TestUtils.GetByteArray(32, 0x42));
     prevIndexVal      = 22;
     coinRef.PrevHash  = prevHashVal;
     coinRef.PrevIndex = prevIndexVal;
 }
 public CustomTransaction(TransactionType type) : base(type)
 {
     Version    = 1;
     Inputs     = new CoinReference[0];
     Outputs    = new TransactionOutput[0];
     Attributes = new TransactionAttribute[0];
 }
        /// <summary>
        /// INIT HISTORY OF TRANSACTIONS
        /// </summary>
        /// <param name="scriptHash"></param>
        /// <param name="value"></param>
        /// <param name="inputAmount"></param>
        public static void InitTransactionContext(string scriptHash, int value)
        {
            Transaction       initialTransaction = new CustomTransaction(TransactionType.ContractTransaction);
            Transaction       currentTransaction = new CustomTransaction(TransactionType.ContractTransaction);
            TransactionOutput transactionOutput;
            CoinReference     coinRef;

            /** CREATE FAKE PREVIOUS TRANSACTION */
            transactionOutput = new TransactionOutput
            {
                ScriptHash = UInt160.Parse(scriptHash),
                Value      = new Fixed8(value),
                AssetId    = UInt256.Parse(NEO_ASSET_ID)
            };

            initialTransaction.Outputs = new TransactionOutput[] { transactionOutput };
            /** CREATE FAKE CURRENT TRANSACTION */
            coinRef = new CoinReference
            {
                PrevHash  = initialTransaction.Hash,
                PrevIndex = 0
            };

            currentTransaction.Inputs = new CoinReference[] { coinRef };

            /**INIT CONTEXT*/
            service.transactions[initialTransaction.Hash] = initialTransaction;
            service.transactions[currentTransaction.Hash] = currentTransaction;
            scriptContainer = initialTransaction;
        }
Exemple #4
0
        public static Transaction CreateGlobalTransfer(SignDelegate2 sign)
        {
            CoinReference[] inputs = new CoinReference[]
            {
                new CoinReference()
                {
                    PrevHash  = new UInt256(preTxId.Remove(0, 2).HexToBytes().Reverse().ToArray()),
                    PrevIndex = prevIndex //vout n
                }
            }.ToArray();

            var outputs = new List <TransactionOutput>();
            var output1 = new TransactionOutput()
            {
                AssetId    = UInt256.Parse(assetid),
                ScriptHash = tansferAddress.ToScriptHash(),
                Value      = tansferValue
            };

            outputs.Add(output1);

            var tx = new ContractTransaction()
            {
                Outputs    = outputs.ToArray(),
                Inputs     = inputs,
                Attributes = new TransactionAttribute[0],
                Witnesses  = new Witness[0]
            };

            return(sign.Invoke(tx));
        }
Exemple #5
0
        // Create ClaimTransaction with 'countRefs' CoinReferences
        public static ClaimTransaction GetClaimTransaction(int countRefs)
        {
            CoinReference[] refs = new CoinReference[countRefs];
            for (var i = 0; i < countRefs; i++)
            {
                refs[i] = GetCoinReference(new UInt256(Crypto.Default.Hash256(new BigInteger(i).ToByteArray())));
            }

            //==============================
            //=== Generating random Hash ===
            var randomBytes = new byte[20];

            _random.NextBytes(randomBytes);
            //==============================
            return(new ClaimTransaction
            {
                Claims = refs,
                Attributes = new TransactionAttribute[] { new TransactionAttribute {
                                                              Usage = TransactionAttributeUsage.Script, Data = randomBytes
                                                          } },
                Inputs = new CoinReference[0],
                Outputs = new TransactionOutput[0],
                Witnesses = new Witness[0]
            });
        }
 public static CoinReferenceContract FromDomain(CoinReference source)
 {
     return(new CoinReferenceContract
     {
         PrevHash = source.PrevHash.ToString(),
         PrevIndex = source.PrevIndex
     });
 }
 public static CoinReferenceWrapper Wrap(CoinReference reference)
 {
     return(new CoinReferenceWrapper
     {
         PrevHash = reference.PrevHash,
         PrevIndex = reference.PrevIndex
     });
 }
Exemple #8
0
        private JObject ConvertTransactionInputs(CoinReference coinReference)
        {
            var json = new JObject();

            json["txid"] = coinReference.PrevHash.ToString();
            json["vout"] = coinReference.PrevIndex;

            return(json);
        }
Exemple #9
0
        public void Claims_Set()
        {
            CoinReference val = new CoinReference();

            CoinReference[] refs = new CoinReference[] { val };
            uut.Claims = refs;
            uut.Claims.Length.Should().Be(1);
            uut.Claims[0].Should().Be(val);
        }
        public static IEnumerable <Coin> GetCoins(Snapshot snapshot, ImmutableHashSet <UInt160> addresses)
        {
            var coinIndex = new Dictionary <CoinReference, Coin>();
            var height    = snapshot.Height;

            for (uint blockIndex = 0; blockIndex < height; blockIndex++)
            {
                var block = snapshot.GetBlock(blockIndex);

                for (var txIndex = 0; txIndex < block.Transactions.Length; txIndex++)
                {
                    var tx = block.Transactions[txIndex];

                    for (var outIndex = 0; outIndex < tx.Outputs.Length; outIndex++)
                    {
                        var output = tx.Outputs[outIndex];

                        if (addresses.Contains(output.ScriptHash))
                        {
                            var coinRef = new CoinReference()
                            {
                                PrevHash  = tx.Hash,
                                PrevIndex = (ushort)outIndex
                            };

                            coinIndex.Add(coinRef, new Coin()
                            {
                                Reference = coinRef,
                                Output    = output,
                                State     = CoinState.Confirmed
                            });
                        }
                    }

                    for (var inIndex = 0; inIndex < tx.Inputs.Length; inIndex++)
                    {
                        if (coinIndex.TryGetValue(tx.Inputs[inIndex], out var coin))
                        {
                            coin.State |= CoinState.Spent | CoinState.Confirmed;
                        }
                    }

                    if (tx is ClaimTransaction claimTx)
                    {
                        for (var claimIndex = 0; claimIndex < claimTx.Claims.Length; claimIndex++)
                        {
                            if (coinIndex.TryGetValue(claimTx.Claims[claimIndex], out var coin))
                            {
                                coin.State |= CoinState.Claimed;
                            }
                        }
                    }
                }
            }

            return(coinIndex.Select(kvp => kvp.Value));
        }
Exemple #11
0
        private static bool Input_GetIndex(ScriptEngine engine)
        {
            CoinReference input = engine.EvaluationStack.Pop().GetInterface <CoinReference>();

            if (input == null)
            {
                return(false);
            }
            engine.EvaluationStack.Push((int)input.PrevIndex);
            return(true);
        }
        private static bool Input_GetHash(ExecutionEngine engine)
        {
            CoinReference input = engine.EvaluationStack.Pop().GetInterface <CoinReference>();

            if (input == null)
            {
                return(false);
            }
            engine.EvaluationStack.Push(input.PrevHash.ToArray());
            return(true);
        }
        protected virtual bool Input_GetIndex(ExecutionEngine engine)
        {
            CoinReference input = engine.EvaluationStack.Pop().GetInterface <CoinReference>();

            if (input == null)
            {
                return(false);
            }
            engine.EvaluationStack.Push((int)input.PrevIndex);
            return(true);
        }
Exemple #14
0
        protected virtual bool Input_GetHash(ExecutionEngine engine)
        {
            CoinReference input = (engine.EvaluationStack.Pop() as VM.Types.InteropInterface).GetInterface <CoinReference>();

            if (input == null)
            {
                return(false);
            }
            engine.EvaluationStack.Push(input.PrevHash.ToArray());
            return(true);
        }
Exemple #15
0
        public async Task Persist_TransactionWithInputs_SpendOutputs()
        {
            var repositoryMock = AutoMockContainer.GetMock <IRepository>();
            var input          = new ContractTransaction
            {
                Hash   = UInt256.Parse(RandomInt().ToString("X64")),
                Inputs = new CoinReference[3]
            };
            var txs = new Transaction[3];

            for (var i = 0; i < input.Inputs.Length; i++)
            {
                var reference = new CoinReference
                {
                    PrevHash  = UInt256.Parse(RandomInt().ToString("X64")),
                    PrevIndex = 0
                };
                input.Inputs[i] = reference;
                txs[i]          = new Transaction
                {
                    Hash    = reference.PrevHash,
                    Outputs = new[]
                    {
                        new TransactionOutput
                        {
                            AssetId    = UInt256.Parse(RandomInt().ToString("X64")),
                            ScriptHash = UInt160.Parse(RandomInt().ToString("X40")),
                            Value      = new Fixed8(RandomInt())
                        }
                    }
                };
                repositoryMock
                .Setup(m => m.GetTransaction(reference.PrevHash))
                .ReturnsAsync(txs[i]);
                repositoryMock
                .Setup(m => m.GetCoinStates(reference.PrevHash))
                .ReturnsAsync(new[] { CoinState.Confirmed });
            }

            var accountManagerMock = AutoMockContainer.GetMock <IAccountManager>();
            var testee             = AutoMockContainer.Create <TransactionPersister>();

            await testee.Persist(input);

            for (var i = 0; i < input.Outputs.Length; i++)
            {
                var output = txs[i].Outputs[0];
                accountManagerMock.Verify(m => m.UpdateBalance(output.ScriptHash, output.AssetId, -output.Value));
                var hash = txs[i].Hash;
                repositoryMock.Verify(m => m.AddCoinStates(It.Is <UInt256>(u => u.Equals(hash)),
                                                           It.Is <CoinState[]>(cs => cs.Length == 1 && cs[0].Equals(CoinState.Confirmed | CoinState.Spent))));
            }
        }
Exemple #16
0
        public void Size__Get_0_Claims()
        {
            CoinReference[] refs = new CoinReference[0];
            uut.Claims = refs;

            uut.Attributes = new TransactionAttribute[0];
            uut.Inputs     = new CoinReference[0];
            uut.Outputs    = new TransactionOutput[0];
            uut.Scripts    = new Witness[0];

            uut.Size.Should().Be(7); // 1, 1, 1, 1, 1, 1 + claims 1
        }
Exemple #17
0
        public void Equals_SameIndex()
        {
            UInt256 prevHashVal;
            ushort  prevIndexVal;

            setupCoinReferenceWithVals(uut, out prevHashVal, out prevIndexVal);
            CoinReference newCoinRef = new CoinReference();

            setupCoinReferenceWithVals(newCoinRef, out prevHashVal, out prevIndexVal);

            uut.Equals(newCoinRef).Should().BeTrue();
        }
Exemple #18
0
        public void Equals_DiffIndex()
        {
            UInt256 prevHashVal;
            ushort  prevIndexVal;

            setupCoinReferenceWithVals(uut, out prevHashVal, out prevIndexVal);
            CoinReference newCoinRef = new CoinReference();

            setupCoinReferenceWithVals(newCoinRef, out prevHashVal, out prevIndexVal);
            newCoinRef.PrevIndex = 73;

            uut.Equals(newCoinRef).Should().BeFalse();
        }
Exemple #19
0
        public void Equals_DiffHash()
        {
            UInt256 prevHashVal;
            ushort  prevIndexVal;

            setupCoinReferenceWithVals(uut, out prevHashVal, out prevIndexVal);
            CoinReference newCoinRef = new CoinReference();

            setupCoinReferenceWithVals(newCoinRef, out prevHashVal, out prevIndexVal);
            newCoinRef.PrevHash = new UInt256(TestUtils.GetByteArray(32, 0x78));

            uut.Equals(newCoinRef).Should().BeFalse();
        }
 private bool Input_GetHash(ExecutionEngine engine)
 {
     if (engine.CurrentContext.EvaluationStack.Pop() is InteropContract _interface)
     {
         CoinReference input = _interface.GetInterface <CoinReference>();
         if (input == null)
         {
             return(false);
         }
         engine.CurrentContext.EvaluationStack.Push(input.PrevHash.ToArray());
         return(true);
     }
     return(false);
 }
Exemple #21
0
 private bool Input_GetIndex(ExecutionEngine engine)
 {
     if (engine.CurrentContext.EvaluationStack.Pop() is InteropInterface _interface)
     {
         CoinReference input = _interface.GetInterface <CoinReference>();
         if (input == null)
         {
             return(false);
         }
         engine.CurrentContext.EvaluationStack.Push((int)input.PrevIndex);
         return(true);
     }
     return(false);
 }
Exemple #22
0
        // Create ClaimTransaction with 'countRefs' CoinReferences
        public static ClaimTransaction GetClaimTransaction(int countRefs)
        {
            CoinReference[] refs = new CoinReference[countRefs];
            for (var i = 0; i < countRefs; i++)
            {
                refs[i] = GetCoinReference(new UInt256(Crypto.Default.Hash256(new BigInteger(i).ToByteArray())));
            }

            return(new ClaimTransaction
            {
                Claims = refs,
                Attributes = new TransactionAttribute[0],
                Inputs = new CoinReference[0],
                Outputs = new TransactionOutput[0],
                Witnesses = new Witness[0]
            });
        }
Exemple #23
0
        private IssueTransaction getIssueTransaction(bool inputVal, decimal outputVal, UInt256 assetId)
        {
            setupTestBlockchain(assetId);

            CoinReference[] inputsVal;
            if (inputVal)
            {
                inputsVal = new[]
                {
                    new CoinReference
                    {
                        PrevHash  = UInt256.Zero,
                        PrevIndex = 0
                    }
                };
            }
            else
            {
                inputsVal = new CoinReference[0];
            }


            return(new IssueTransaction
            {
                Attributes = new TransactionAttribute[0],
                Inputs = inputsVal,
                Outputs = new[]
                {
                    new TransactionOutput
                    {
                        AssetId = assetId,
                        Value = Fixed8.FromDecimal(outputVal),
                        ScriptHash = Contract.CreateMultiSigRedeemScript(1, TestUtils.StandbyValidators).ToScriptHash()
                    }
                },
                Scripts = new[]
                {
                    new Witness
                    {
                        InvocationScript = new byte[0],
                        VerificationScript = new[] { (byte)OpCode.PUSHT }
                    }
                }
            });
        }
Exemple #24
0
        public static void InitTransactionContext(string scriptHash, int value, ushort inputAmount = 1)
        {
            Transaction initialTransaction = new CustomTransaction(TransactionType.ContractTransaction);
            Transaction currentTransaction = new CustomTransaction(TransactionType.ContractTransaction);

            initialTransaction.Outputs = new TransactionOutput[inputAmount];
            currentTransaction.Inputs  = new CoinReference[inputAmount];


            for (ushort i = 0; i < inputAmount; ++i)
            {
                /** CREATE FAKE PREVIOUS TRANSACTION */
                var transactionOutput = new TransactionOutput
                {
                    ScriptHash = UInt160.Parse(scriptHash),
                    Value      = new Fixed8(value),
                    AssetId    = UInt256.Parse(NEO_ASSET_ID)
                };

                initialTransaction.Outputs[i] = transactionOutput;
                /** CREATE FAKE CURRENT TRANSACTION */
                var coinRef = new CoinReference
                {
                    PrevHash  = initialTransaction.Hash,
                    PrevIndex = i
                };

                currentTransaction.Outputs    = new TransactionOutput[1];
                currentTransaction.Outputs[0] = new TransactionOutput
                {
                    ScriptHash = UInt160.Parse(scriptHash),
                    Value      = new Fixed8(value),
                    AssetId    = UInt256.Parse(NEO_ASSET_ID)
                };


                currentTransaction.Inputs[i] = coinRef;
            }


            /**INIT CONTEXT*/
            service.transactions[initialTransaction.Hash] = initialTransaction;
            scriptContainer = currentTransaction;
        }
Exemple #25
0
        public static Transaction Claim(Wallet wallet)
        {
            CoinReference[] claims = wallet.GetUnclaimedCoins().Select(p => p.Reference).ToArray();
            if (claims.Length == 0)
            {
                return(null);
            }

            ClaimTransaction tx = new ClaimTransaction
            {
                Claims     = claims,
                Attributes = new TransactionAttribute[0],
                Inputs     = new CoinReference[0],
                Outputs    = new[]
                {
                    new TransactionOutput
                    {
                        AssetId    = Blockchain.UtilityToken.Hash,
                        Value      = Blockchain.CalculateBonus(claims),
                        ScriptHash = wallet.GetChangeAddress()
                    }
                }
            };

            //交易输入是 1 GAS
            var input = new CoinReference()
            {
                PrevHash  = new UInt256("0x51ac4f7f1662d8c9379ccce3fa7cd2085b9a865edfa53ad892352a41768dd1de".Remove(0, 2).HexToBytes().Reverse().ToArray()),
                PrevIndex = 0
            };
            //交易输出是 0.999 GAS,找回到原地址
            var output = new TransactionOutput()
            {
                AssetId    = Blockchain.UtilityToken.Hash,                              //Asset Id, this is NEO
                ScriptHash = Wallet.ToScriptHash("AJd31a8rYPEBkY1QSxpsGy8mdU4vTYTD4U"), //Receiver
                Value      = new Fixed8((long)(0.999 * (long)Math.Pow(10, 8)))          //Value (satoshi unit)
            };

            //则手续费是 0.001 GAS
            tx.Inputs.ToList().Add(input);
            tx.Outputs.ToList().Add(output);

            return(tx);
        }
Exemple #26
0
        private ContractTransaction getContractTransaction(bool inputVal, decimal outputVal, UInt256 assetId)
        {
            CoinReference[] inputsVal;
            if (inputVal)
            {
                inputsVal = new[]
                {
                    TestUtils.GetCoinReference(null)
                };
            }
            else
            {
                inputsVal = new CoinReference[0];
            }

            return(new ContractTransaction
            {
                Attributes = new TransactionAttribute[0],
                Inputs = inputsVal,
                Outputs = new[]
                {
                    new TransactionOutput
                    {
                        AssetId = assetId,
                        Value = Fixed8.FromDecimal(outputVal),
                        ScriptHash = Contract.CreateMultiSigRedeemScript(1, TestUtils.StandbyValidators).ToScriptHash()
                    }
                },
                Witnesses = new[]
                {
                    new Witness
                    {
                        InvocationScript = new byte[0],
                        VerificationScript = new[] { (byte)OpCode.PUSHT }
                    }
                }
            });
        }
Exemple #27
0
 private void ProcessNewBlock(Block block)
 {
     Coin[] changeset;
     lock (contracts)
         lock (coins)
         {
             foreach (Transaction tx in block.Transactions)
             {
                 for (ushort index = 0; index < tx.Outputs.Length; index++)
                 {
                     TransactionOutput output = tx.Outputs[index];
                     AddressState      state  = CheckAddressState(output.ScriptHash);
                     if (state.HasFlag(AddressState.InWallet))
                     {
                         CoinReference key = new CoinReference
                         {
                             PrevHash  = tx.Hash,
                             PrevIndex = index
                         };
                         if (coins.Contains(key))
                         {
                             coins[key].State |= CoinState.Confirmed;
                         }
                         else
                         {
                             coins.Add(new Coin
                             {
                                 Reference = key,
                                 Output    = output,
                                 State     = CoinState.Confirmed
                             });
                         }
                         if (state.HasFlag(AddressState.WatchOnly))
                         {
                             coins[key].State |= CoinState.WatchOnly;
                         }
                     }
                 }
             }
             foreach (Transaction tx in block.Transactions)
             {
                 foreach (CoinReference input in tx.Inputs)
                 {
                     if (coins.Contains(input))
                     {
                         if (coins[input].Output.AssetId.Equals(Blockchain.SystemShare.Hash))
                         {
                             coins[input].State |= CoinState.Spent | CoinState.Confirmed;
                         }
                         else
                         {
                             coins.Remove(input);
                         }
                     }
                 }
             }
             foreach (ClaimTransaction tx in block.Transactions.OfType <ClaimTransaction>())
             {
                 foreach (CoinReference claim in tx.Claims)
                 {
                     if (coins.Contains(claim))
                     {
                         coins.Remove(claim);
                     }
                 }
             }
             current_height++;
             changeset = coins.GetChangeSet();
             OnProcessNewBlock(block, changeset.Where(p => ((ITrackable <CoinReference>)p).TrackState == TrackState.Added), changeset.Where(p => ((ITrackable <CoinReference>)p).TrackState == TrackState.Changed), changeset.Where(p => ((ITrackable <CoinReference>)p).TrackState == TrackState.Deleted));
             coins.Commit();
         }
     if (changeset.Length > 0)
     {
         BalanceChanged?.Invoke(this, EventArgs.Empty);
     }
 }
        private void ProcessBlock(Block block, HashSet <UInt160> accounts, WriteBatch batch)
        {
            foreach (Transaction tx in block.Transactions)
            {
                HashSet <UInt160> accounts_changed = new HashSet <UInt160>();
                for (ushort index = 0; index < tx.Outputs.Length; index++)
                {
                    TransactionOutput output = tx.Outputs[index];
                    if (accounts_tracked.ContainsKey(output.ScriptHash))
                    {
                        CoinReference reference = new CoinReference
                        {
                            PrevHash  = tx.Hash,
                            PrevIndex = index
                        };
                        if (coins_tracked.TryGetValue(reference, out Coin coin))
                        {
                            coin.State |= CoinState.Confirmed;
                        }
                        else
                        {
                            accounts_tracked[output.ScriptHash].Add(reference);
                            coins_tracked.Add(reference, coin = new Coin
                            {
                                Reference = reference,
                                Output    = output,
                                State     = CoinState.Confirmed
                            });
                        }
                        batch.Put(SliceBuilder.Begin(DataEntryPrefix.ST_Coin).Add(reference), SliceBuilder.Begin().Add(output).Add((byte)coin.State));
                        accounts_changed.Add(output.ScriptHash);
                    }
                }
                foreach (CoinReference input in tx.Inputs)
                {
                    if (coins_tracked.TryGetValue(input, out Coin coin))
                    {
                        if (coin.Output.AssetId.Equals(Blockchain.GoverningToken.Hash))
                        {
                            coin.State |= CoinState.Spent | CoinState.Confirmed;
                            batch.Put(SliceBuilder.Begin(DataEntryPrefix.ST_Coin).Add(input), SliceBuilder.Begin().Add(coin.Output).Add((byte)coin.State));
                        }
                        else
                        {
                            accounts_tracked[coin.Output.ScriptHash].Remove(input);
                            coins_tracked.Remove(input);
                            batch.Delete(DataEntryPrefix.ST_Coin, input);
                        }
                        accounts_changed.Add(coin.Output.ScriptHash);
                    }
                }
                switch (tx)
                {
                case MinerTransaction _:
                case ContractTransaction _:
#pragma warning disable CS0612
                case PublishTransaction _:
#pragma warning restore CS0612
                    break;

                case ClaimTransaction tx_claim:
                    foreach (CoinReference claim in tx_claim.Claims)
                    {
                        if (coins_tracked.TryGetValue(claim, out Coin coin))
                        {
                            accounts_tracked[coin.Output.ScriptHash].Remove(claim);
                            coins_tracked.Remove(claim);
                            batch.Delete(DataEntryPrefix.ST_Coin, claim);
                            accounts_changed.Add(coin.Output.ScriptHash);
                        }
                    }
                    break;

#pragma warning disable CS0612
                case EnrollmentTransaction tx_enrollment:
                    if (accounts_tracked.ContainsKey(tx_enrollment.ScriptHash))
                    {
                        accounts_changed.Add(tx_enrollment.ScriptHash);
                    }
                    break;

                case RegisterTransaction tx_register:
                    if (accounts_tracked.ContainsKey(tx_register.OwnerScriptHash))
                    {
                        accounts_changed.Add(tx_register.OwnerScriptHash);
                    }
                    break;

#pragma warning restore CS0612
                default:
                    foreach (UInt160 hash in tx.Witnesses.Select(p => p.ScriptHash))
                    {
                        if (accounts_tracked.ContainsKey(hash))
                        {
                            accounts_changed.Add(hash);
                        }
                    }
                    break;
                }
                if (accounts_changed.Count > 0)
                {
                    foreach (UInt160 account in accounts_changed)
                    {
                        batch.Put(SliceBuilder.Begin(DataEntryPrefix.ST_Transaction).Add(account).Add(tx.Hash), false);
                    }
                    WalletTransaction?.Invoke(null, new WalletTransactionEventArgs
                    {
                        Transaction     = tx,
                        RelatedAccounts = accounts_changed.ToArray(),
                        Height          = block.Index,
                        Time            = block.Timestamp
                    });
                }
            }
        }
Exemple #29
0
 private static void ProcessBlock(Block block, HashSet <UInt160> accounts, WriteBatch batch)
 {
     foreach (Transaction tx in block.Transactions)
     {
         HashSet <UInt160> accounts_changed = new HashSet <UInt160>();
         for (ushort index = 0; index < tx.Outputs.Length; index++)
         {
             TransactionOutput output = tx.Outputs[index];
             if (accounts_tracked.ContainsKey(output.ScriptHash))
             {
                 CoinReference reference = new CoinReference
                 {
                     PrevHash  = tx.Hash,
                     PrevIndex = index
                 };
                 if (coins_tracked.TryGetValue(reference, out Coin coin))
                 {
                     coin.State |= CoinState.Confirmed;
                 }
                 else
                 {
                     accounts_tracked[output.ScriptHash].Add(reference);
                     coins_tracked.Add(reference, coin = new Coin
                     {
                         Reference = reference,
                         Output    = output,
                         State     = CoinState.Confirmed
                     });
                 }
                 batch.Put(SliceBuilder.Begin(DataEntryPrefix.ST_Coin).Add(reference), SliceBuilder.Begin().Add(output).Add((byte)coin.State));
                 accounts_changed.Add(output.ScriptHash);
             }
         }
         foreach (CoinReference input in tx.Inputs)
         {
             if (coins_tracked.TryGetValue(input, out Coin coin))
             {
                 if (coin.Output.AssetId.Equals(Blockchain.GoverningToken.Hash))
                 {
                     coin.State |= CoinState.Spent | CoinState.Confirmed;
                     batch.Put(SliceBuilder.Begin(DataEntryPrefix.ST_Coin).Add(input), SliceBuilder.Begin().Add(coin.Output).Add((byte)coin.State));
                 }
                 else
                 {
                     accounts_tracked[coin.Output.ScriptHash].Remove(input);
                     coins_tracked.Remove(input);
                     batch.Delete(DataEntryPrefix.ST_Coin, input);
                 }
                 accounts_changed.Add(coin.Output.ScriptHash);
             }
         }
         if (tx is ClaimTransaction ctx)
         {
             foreach (CoinReference claim in ctx.Claims)
             {
                 if (coins_tracked.TryGetValue(claim, out Coin coin))
                 {
                     accounts_tracked[coin.Output.ScriptHash].Remove(claim);
                     coins_tracked.Remove(claim);
                     batch.Delete(DataEntryPrefix.ST_Coin, claim);
                     accounts_changed.Add(coin.Output.ScriptHash);
                 }
             }
         }
         if (accounts_changed.Count > 0)
         {
             foreach (UInt160 account in accounts_changed)
             {
                 batch.Put(SliceBuilder.Begin(DataEntryPrefix.ST_Transaction).Add(account).Add(tx.Hash), false);
             }
             BalanceChanged?.Invoke(null, new BalanceEventArgs
             {
                 Transaction     = tx,
                 RelatedAccounts = accounts_changed.ToArray(),
                 Height          = block.Index,
                 Time            = block.Timestamp
             });
         }
     }
 }
Exemple #30
0
 public void TestSetup()
 {
     uut = new CoinReference();
 }