/// <inheritdoc />
        public Transaction Process(SmartContractCarrier carrier,
                                   IContractStateRepository stateSnapshot,
                                   ISmartContractTransactionContext transactionContext,
                                   IList <TransferInfo> internalTransfers,
                                   bool reversionRequired)
        {
            if (reversionRequired)
            {
                // Send back funds
                if (carrier.Value > 0)
                {
                    return(CreateRefundTransaction(transactionContext));
                }
            }

            // If contract received no funds and made no transfers, do nothing.
            if (carrier.Value == 0 && !internalTransfers.Any())
            {
                return(null);
            }

            // TODO we should not be generating addresses in here!
            uint160 contractAddress = null;

            if (carrier.CallData.ContractAddress == uint160.Zero)
            {
                contractAddress = carrier.GetNewContractAddress();
            }
            else
            {
                contractAddress = carrier.CallData.ContractAddress;
            }

            // If contract had no balance, received funds, but made no transfers, assign the current UTXO.
            if (stateSnapshot.GetUnspent(contractAddress) == null && carrier.Value > 0 && !internalTransfers.Any())
            {
                stateSnapshot.SetUnspent(contractAddress, new ContractUnspentOutput
                {
                    Value = carrier.Value,
                    Hash  = carrier.TransactionHash,
                    Nvout = carrier.Nvout
                });

                return(null);
            }
            // All other cases we need a condensing transaction

            var transactionCondenser = new TransactionCondenser(contractAddress, this.loggerFactory, internalTransfers, stateSnapshot, this.network, transactionContext);

            return(transactionCondenser.CreateCondensingTransaction());
        }
Esempio n. 2
0
        /// <inheritdoc />
        public Transaction Process(IStateRepository stateSnapshot,
                                   uint160 contractAddress,
                                   IContractTransactionContext transactionContext,
                                   IReadOnlyList <TransferInfo> internalTransfers,
                                   bool reversionRequired)
        {
            if (reversionRequired)
            {
                // Send back funds
                if (transactionContext.TxOutValue > 0)
                {
                    return(this.CreateRefundTransaction(transactionContext));
                }

                return(null);
            }

            // If contract received no funds and made no transfers, do nothing.
            if (transactionContext.TxOutValue == 0 && !internalTransfers.Any(x => x.Value > 0))
            {
                return(null);
            }

            // If contract had no balance, received funds, but made no transfers, assign the current UTXO.
            if (stateSnapshot.GetUnspent(contractAddress) == null && transactionContext.TxOutValue > 0 && !internalTransfers.Any())
            {
                stateSnapshot.SetUnspent(contractAddress, new ContractUnspentOutput
                {
                    Value = transactionContext.TxOutValue,
                    Hash  = transactionContext.TransactionHash,
                    Nvout = transactionContext.Nvout
                });

                return(null);
            }

            // All other cases we need a condensing transaction
            var transactionCondenser = new TransactionCondenser(contractAddress, this.loggerFactory, internalTransfers, stateSnapshot, this.network, transactionContext);

            return(transactionCondenser.CreateCondensingTransaction());
        }