예제 #1
0
        public async Task <IActionResult> BuildSingle([FromBody] BuildSingleTransactionRequest request)
        {
            if (request == null)
            {
                return(BadRequest(ErrorResponse.Create("Unable to deserialize request")));
            }

            if (!new [] { Constants.Assets.Neo.AssetId, Constants.Assets.Gas.AssetId }.Contains(request.AssetId))
            {
                return(BadRequest(ErrorResponse.Create("Invalid assetId")));
            }

            var amount = MoneyConversionHelper.FromContract(request.Amount, request.AssetId);

            if (amount <= 0)
            {
                return(BadRequest(ErrorResponse.Create($"Amount can't be less or equal to zero: {amount}")));
            }

            if (request.AssetId == Constants.Assets.Neo.AssetId && amount % 1 != 0)
            {
                return(BadRequest($"The minimum unit of NEO is 1 and tokens cannot be subdivided.: {amount}"));
            }

            var toAddressValid = _addressValidator.IsAddressValid(request.ToAddress);

            if (!toAddressValid)
            {
                return(BadRequest(ErrorResponse.Create("Invalid toAddress")));
            }

            var fromAddressValid = _addressValidator.IsAddressValid(request.FromAddress);

            if (!fromAddressValid)
            {
                return(BadRequest(ErrorResponse.Create("Invalid fromAddress")));
            }

            if (!ModelState.IsValidOperationId(request.OperationId))
            {
                return(BadRequest(ErrorResponseFactory.Create(ModelState)));
            }



            if ((await _operationRepository.GetOrDefault(request.OperationId))?.IsBroadcasted ?? false)
            {
                return(Conflict());
            }

            Transaction tx;
            decimal     fee = 0;

            switch (request.AssetId)
            {
            case Constants.Assets.Neo.AssetId:

                (tx, fee) = await _transactionBuilder.BuildNeoContractTransactionAsync(request.FromAddress,
                                                                                       request.ToAddress,
                                                                                       amount,
                                                                                       request.IncludeFee);

                break;

            case Constants.Assets.Gas.AssetId:
                tx = await _transactionBuilder.BuildGasTransactionAsync(request.FromAddress,
                                                                        request.ToAddress,
                                                                        amount);

                break;

            default:
                throw new ArgumentException("Unknown switch", nameof(request.AssetId));
            }

            await _operationRepository.GetOrInsert(request.OperationId,
                                                   () => OperationAggregate.StartNew(request.OperationId,
                                                                                     fromAddress: request.FromAddress,
                                                                                     toAddress: request.ToAddress,
                                                                                     amount: amount,
                                                                                     assetId: request.AssetId,
                                                                                     fee: fee,
                                                                                     includeFee: request.IncludeFee));

            return(Ok(new BuildTransactionResponse
            {
                TransactionContext = TransactionSerializer.Serialize(tx, TransactionType.ContractTransaction)
            }));
        }