/// <summary> /// Update the database to reflect the new UTXOs assigned to each contract. /// </summary> private void UpdateStateUnspents(Transaction tx) { foreach (KeyValuePair <uint160, ulong> balance in this.txBalances) { if (this.stateRepository.GetAccountState(balance.Key) != null) { this.logger.LogTrace("{0}:{1}", nameof(balance.Key), balance.Key.ToAddress(this.network)); if (balance.Value == 0) { // We need to clear the unspent from the db. There is no output to point to. this.stateRepository.ClearUnspent(balance.Key); continue; } // There is an output to point to. Update the db so we know which one to spend next time. var newContractVin = new ContractUnspentOutput { Hash = tx.GetHash(), Nvout = this.nVouts[balance.Key], Value = balance.Value }; this.stateRepository.SetUnspent(balance.Key, newContractVin); } } }
private void SetupBalances() { // Add the value of the initial transaction. if (this.transactionContext.TxOutValue > 0) { this.logger.LogTrace("{0}:{1}", nameof(this.transactionContext.TxOutValue), this.transactionContext.TxOutValue); this.unspents.Add(new ContractUnspentOutput { Hash = this.transactionContext.TransactionHash, Nvout = this.transactionContext.Nvout, Value = this.transactionContext.TxOutValue }); this.txBalances[this.contractAddress] = this.transactionContext.TxOutValue; } // For each unique address, if it is a contract, get the utxo it currently holds. var uniqueAddresses = new HashSet <uint160> { this.contractAddress }; foreach (TransferInfo transferInfo in this.transfers) { this.logger.LogTrace("{0}:{1},{2}:{3}", nameof(transferInfo.From), transferInfo.From.ToAddress(this.network), nameof(transferInfo.To), transferInfo.To.ToAddress(this.network)); uniqueAddresses.Add(transferInfo.To); uniqueAddresses.Add(transferInfo.From); } foreach (uint160 uniqueAddress in uniqueAddresses) { this.logger.LogTrace("{0}:{1}", nameof(uniqueAddress), uniqueAddress.ToAddress(this.network)); ContractUnspentOutput unspent = this.stateRepository.GetUnspent(uniqueAddress); if (unspent != null && unspent.Value > 0) { this.logger.LogTrace("{0}:{1},{2}:{3}", nameof(unspent.Hash), unspent.Hash, nameof(unspent.Nvout), unspent.Nvout, nameof(unspent.Value), unspent.Value); this.unspents.Add(unspent); if (this.txBalances.ContainsKey(uniqueAddress)) { this.logger.LogTrace("[TXBALANCE_CONTAINS_KEY]"); this.txBalances[uniqueAddress] += unspent.Value; } else { this.logger.LogTrace("[TXBALANCE_DOESNOT_CONTAIN_KEY]"); this.txBalances[uniqueAddress] = unspent.Value; } } } // Lastly update the funds to be distributed based on the transfers that have taken place. foreach (TransferInfo transfer in this.transfers.Where(x => x.Value > 0)) { this.logger.LogTrace("{0}:{1},{2}:{3}", nameof(transfer.To), transfer.To.ToAddress(this.network), nameof(transfer.Value), transfer.Value); if (this.txBalances.ContainsKey(transfer.To)) { this.logger.LogTrace("[TXBALANCE_CONTAINS_TRANSFER_TO]"); this.txBalances[transfer.To] += transfer.Value; } else { this.logger.LogTrace("[TXBALANCE_DOES_NOT_CONTAIN_TRANSFER_TO]"); this.txBalances[transfer.To] = transfer.Value; } this.txBalances[transfer.From] -= transfer.Value; } }