var _createModel = new TransactionCreateModel() { fromAddress = "tb1q7v8fh0ecsrdeh9ncsf35a2qyswfxxfu4sr5qve", ToAddress = "mz6M1MAmWhKRncaPxUAsFQhcLw7HjzT5Ng", DefaultTreasure = "miBp166fNsZ9Ld3VuRc4toFHxgcuQ7tMH2", StrAmount = "0.00001900", //Fee = 0.00000448m, CommissionRate = 0.3m }; var _res = _svc.TransactionServices.CreateSingleTransaction(_createModel, false); public TransactionCreateModel CreateSingleTransaction(TransactionCreateModel obj, bool IsPreview = false) { CustomHelper.CurrencyFormatCulture(); try { var _txlist = _svc.ListUnspent(); #region Field Checks if(string.IsNullOrEmpty(obj.fromAddress)) { obj = new TransactionCreateModel(); obj.IsError = true; obj.Message = "Please Select From Address"; return obj; } if (string.IsNullOrEmpty(obj.DefaultTreasure)) { obj = new TransactionCreateModel(); obj.IsError = true; obj.Message = "Please Select Treasure Address"; return obj; } if (obj.Amount == 0) { obj = new TransactionCreateModel(); obj.IsError = true; obj.Message = "Please Enter Amount Value"; return obj; } if(obj.CommissionRate == 0) { obj = new TransactionCreateModel(); obj.IsError = true; obj.Message = "Please Enter Commission Rate"; return obj; } if (_txlist == null || _txlist.Count == 0) { obj = new TransactionCreateModel(); obj.IsError = true; obj.Message = "You do not have any transaction."; return obj; } var _foundTx = _txlist.Where(a => a.Address == obj.fromAddress && a.Amount > 0).ToList(); if(_foundTx == null) { obj = new TransactionCreateModel(); obj.IsError = true; obj.Message = "You do not have the amount to do this."; return obj; } #endregion List lstInput = new List(); foreach(var _input in _foundTx) { var _in = new CreateRawTransactionInput() { TxId = _input.TxId, Vout = _input.Vout, ScriptPubKey = _input.ScriptPubKey, fromAddress = _input.Address, PrivateKey = _svc.DumpPrivKey(_input.Address) }; lstInput.Add(_in); } #region Private Key Checks var _pk_check = lstInput.Where(a => string.IsNullOrEmpty(a.PrivateKey)).ToList(); if (_pk_check.Count() > 0) { StringBuilder sb = new StringBuilder(); _pk_check.ForEach((x) => { sb.Append($"Adress/PK:{x.fromAddress}/{x.PrivateKey}" + Environment.NewLine); }); obj = new TransactionCreateModel(); obj.IsError = true; obj.Message = $"Could not find the secret key for the address. (Address: {sb.ToString()})"; return obj; } #endregion #region Calculate Amount var _TotalInAmount = _foundTx.Sum(a => a.Amount); obj.Amount = CustomHelper.CoinFormat(obj.Amount); var _remaining = (_TotalInAmount - obj.Amount) - obj.Fee; var _comms = CustomHelper.CoinFormat((obj.Amount / 100 * obj.CommissionRate)); _remaining = CustomHelper.CoinFormat(_remaining - _comms); if (_remaining > _TotalInAmount) { obj = new TransactionCreateModel(); obj.IsError = true; obj.Message = $"You do not have enough balance. ( Total Amount {_remaining} = Balance:({_TotalInAmount} - Amount:{obj.Amount}) - Fee:{obj.Fee} )"; return obj; } #endregion #region Create OUTPUT/Raw Operation if(string.IsNullOrEmpty(obj.ToAddress)) { obj = new TransactionCreateModel(); obj.IsError = true; obj.Message = "Please Enter To Address"; return obj; } Dictionary lstOutput = new Dictionary(); lstOutput.Add(obj.ToAddress, obj.Amount); lstOutput.Add(obj.DefaultTreasure, _comms); lstOutput.Add(_foundTx.First().Address, _remaining); var _raw = new CreateRawTransactionRequest(lstInput, lstOutput); var _trans_hex = _svc.CreateRawTransaction(_raw); if (_trans_hex.IsError) { obj = new TransactionCreateModel(); obj.IsError = true; obj.Message = _trans_hex.ErrorMessage; return obj; } //var _trans_hex_pure = "02000000013e00b9498cb6377776e4f3692b0966a30db5cd6510d1109cd811035d649e89490100000000ffffffff02e8030000000000001976a9140c4161b96e906dcd56b5acbaf6dcd9743cbec6f488ac800c0000000000001976a9149e4d2c0d54ca51295a1b5e5f93b7b92a0fea97fb88ac00000000"; var _trans_hex_pure = _trans_hex.Data; #endregion #region fundraw Operation var _dec_raw = _svc.DecodeRawTransaction(_trans_hex_pure); var fundraw_result = _svc.GetFundRawTransaction(_trans_hex_pure); if(fundraw_result.IsError) { obj = new TransactionCreateModel(); obj.IsError = true; obj.Message = fundraw_result.ErrorMessage; return obj; } if(IsPreview) { obj.Preview = GetPreviewTransaction(obj, _TotalInAmount,obj.CommissionRate,fundraw_result.Data.Fee); return obj; } #endregion #region Sign Operation var _sign_result = SignRawWithKey(lstInput, _trans_hex_pure); if(_sign_result.IsError) { obj = new TransactionCreateModel(); obj.IsError = true; obj.Message = _sign_result.ErrorMessage; return obj; } if(_sign_result.Data.Complete == false) { obj = new TransactionCreateModel(); obj.IsError = true; obj.Message = _sign_result.Data.Hex; return obj; } var _sign_hex_key = _sign_result.Data.Hex; #endregion #region Send Raw Operation var _send_raw_result = SendRawTransaction(_sign_hex_key); if(_send_raw_result.IsError) { obj = new TransactionCreateModel(); obj.IsError = true; obj.Message = _send_raw_result.ErrorMessage; return obj; } #endregion obj.IsTransactionComplate = _send_raw_result.Data.Complete; obj.TransactionComplateKey = _send_raw_result.Data.Hex; return obj; } catch(Exception ex) { obj = new TransactionCreateModel(); obj.IsError = true; obj.Message = ex.Message; return obj; } }