UFRMSaleAccounts.pas 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. unit UFRMSaleAccounts;
  2. { Copyright (c) 2016 by PacalCoin Developers
  3. Distributed under the MIT software license, see the accompanying file LICENSE
  4. or visit http://www.opensource.org/licenses/mit-license.php.
  5. This unit is a part of the PascalCoin Project, an infinitely scalable
  6. cryptocurrency. Find us here:
  7. Web: https://www.pascalcoin.org
  8. Source: https://github.com/PascalCoin/PascalCoin
  9. THIS LICENSE HEADER MUST NOT BE REMOVED.
  10. }
  11. {$mode delphi}
  12. {$I ..\config.inc}
  13. interface
  14. uses
  15. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  16. Dialogs, StdCtrls, UAccounts, Buttons, ActnList;
  17. type
  18. TFRMSaleAccounts = class(TApplicationForm)
  19. lblAccountCaption: TLabel;
  20. ebSenderAccount: TEdit;
  21. memoAccounts: TMemo;
  22. Label1: TLabel;
  23. ebSalePrice: TEdit;
  24. Label2: TLabel;
  25. ebLockedUntilBlock: TEdit;
  26. gbSellOptions: TGroupBox;
  27. rbEveryoneCanBuy: TRadioButton;
  28. rbReservedForAPublickKey: TRadioButton;
  29. lblNewOwnerPublicKey: TLabel;
  30. ebNewOwnerPublicKey: TEdit;
  31. Label3: TLabel;
  32. ebSellerAccount: TEdit;
  33. bbExecute: TBitBtn;
  34. bbCancel: TBitBtn;
  35. lblAccountBalance: TLabel;
  36. lblAccountsCount: TLabel;
  37. lblBalanceCaption: TLabel;
  38. ActionList: TActionList;
  39. actExecute: TAction;
  40. procedure FormCreate(Sender: TObject);
  41. procedure actExecuteExecute(Sender: TObject);
  42. procedure FormDestroy(Sender: TObject);
  43. private
  44. FDisabled : Boolean;
  45. FSenderAccounts: TOrderedCardinalList;
  46. FWalletKeys: TWalletKeys;
  47. FOldOnChanged : TNotifyEvent;
  48. { Private declarations }
  49. Procedure UpdateAccountsInfo;
  50. procedure SetWalletKeys(const Value: TWalletKeys);
  51. public
  52. { Public declarations }
  53. Property SenderAccounts : TOrderedCardinalList read FSenderAccounts;
  54. Property WalletKeys : TWalletKeys read FWalletKeys write SetWalletKeys;
  55. end;
  56. implementation
  57. uses UNode;
  58. {$R *.dfm}
  59. procedure TFRMSaleAccounts.actExecuteExecute(Sender: TObject);
  60. Var errors : AnsiString;
  61. P : PAccount;
  62. i,iAcc : Integer;
  63. wk : TWalletKey;
  64. ops : TOperationsHashTree;
  65. op : TPCOperation;
  66. account : TAccount;
  67. operation_to_string, operationstxt, auxs : String;
  68. _amount,_fee, _totalamount, _totalfee : Int64;
  69. dooperation : Boolean;
  70. begin
  71. if Not Assigned(WalletKeys) then raise Exception.Create('No wallet keys');
  72. If Not UpdateOperationOptions(errors) then raise Exception.Create(errors);
  73. ops := TOperationsHashTree.Create;
  74. Try
  75. _totalamount := 0;
  76. _totalfee := 0;
  77. operationstxt := '';
  78. operation_to_string := '';
  79. for iAcc := 0 to FSenderAccounts.Count - 1 do begin
  80. op := Nil;
  81. account := FNode.Operations.SafeBoxTransaction.Account(FSenderAccounts.Get(iAcc));
  82. If Not UpdatePayload(account, errors) then
  83. raise Exception.Create('Error encoding payload of sender account '+TAccountComp.AccountNumberToAccountTxtNumber(account.account)+': '+errors);
  84. i := WalletKeys.IndexOfAccountKey(account.accountInfo.accountKey);
  85. if i<0 then begin
  86. Raise Exception.Create('Sender account private key not found in Wallet');
  87. end;
  88. wk := WalletKeys.Key[i];
  89. dooperation := true;
  90. //
  91. if rbTransaction.Checked then begin
  92. // Amount
  93. _amount := 0;
  94. _fee := 0;
  95. if FSenderAccounts.Count>1 then begin
  96. if account.balance>0 then begin
  97. if account.balance>fee then begin
  98. _amount := account.balance - fee;
  99. _fee := fee;
  100. end else begin
  101. _amount := account.balance;
  102. _fee := 0;
  103. end;
  104. end else dooperation := false;
  105. end else begin
  106. _amount := FTxAmount;
  107. _fee := fee;
  108. end;
  109. if dooperation then begin
  110. op := TOpTransaction.CreateTransaction(account.account,account.n_operation+1,FTxDestAccount,wk.PrivateKey,_amount,_fee,FEncodedPayload);
  111. inc(_totalamount,_amount);
  112. inc(_totalfee,_fee);
  113. end;
  114. operationstxt := 'Transaction to '+TAccountComp.AccountNumberToAccountTxtNumber(FTxDestAccount);
  115. end else if rbChangeKey.Checked then begin
  116. i := PtrInt(cbNewPrivateKey.Items.Objects[cbNewPrivateKey.ItemIndex]);
  117. if (i<0) Or (i>=WalletKeys.Count) then raise Exception.Create('Invalid selected key');
  118. FNewAccountPublicKey := WalletKeys.Key[i].AccountKey;
  119. if account.balance>fee then _fee := fee
  120. else _fee := 0;
  121. op := TOpChangeKey.Create(account.account,account.n_operation+1,wk.PrivateKey,FNewAccountPublicKey,_fee,FEncodedPayload);
  122. inc(_totalfee,_fee);
  123. operationstxt := 'Change private key to '+wk.Name;
  124. end else if rbTransferToANewOwner.Checked then begin
  125. if account.balance>fee then _fee := fee
  126. else _fee := 0;
  127. op := TOpChangeKey.Create(account.account,account.n_operation+1,wk.PrivateKey,FNewAccountPublicKey,_fee,FEncodedPayload);
  128. operationstxt := 'Transfer to a new owner with key type '+TAccountComp.GetECInfoTxt(FNewAccountPublicKey.EC_OpenSSL_NID);
  129. inc(_totalfee,_fee);
  130. end else begin
  131. raise Exception.Create('No operation selected');
  132. end;
  133. if Assigned(op) And (dooperation) then begin
  134. ops.AddOperationToHashTree(op);
  135. if operation_to_string<>'' then operation_to_string := operation_to_string + #10;
  136. operation_to_string := operation_to_string + op.ToString;
  137. end;
  138. FreeAndNil(op);
  139. end;
  140. if (ops.OperationsCount=0) then raise Exception.Create('No valid operation to execute');
  141. if (FSenderAccounts.Count>1) then begin
  142. if rbTransaction.Checked then auxs := 'Total amount that dest will receive: '+TAccountComp.FormatMoney(_totalamount)+#10
  143. else auxs:='';
  144. if Application.MessageBox(PChar('Execute '+Inttostr(FSenderAccounts.Count)+' operations?'+#10+
  145. 'Operation: '+operationstxt+#10+
  146. auxs+
  147. 'Total fee: '+TAccountComp.FormatMoney(_totalfee)+#10+#10+'Note: This operation will be transmitted to the network!'),
  148. PChar(Application.Title),MB_YESNO+MB_ICONINFORMATION+MB_DEFBUTTON2)<>IdYes then exit;
  149. end else begin
  150. if Application.MessageBox(PChar('Execute this operation:'+#10+#10+operation_to_string+#10+#10+'Note: This operation will be transmitted to the network!'),
  151. PChar(Application.Title),MB_YESNO+MB_ICONINFORMATION+MB_DEFBUTTON2)<>IdYes then exit;
  152. end;
  153. i := FNode.AddOperations(nil,ops,Nil,errors);
  154. if (i=ops.OperationsCount) then begin
  155. Application.MessageBox(PChar('Successfully executed '+inttostr(i)+' operations!'+#10+#10+operation_to_string),PChar(Application.Title),MB_OK+MB_ICONINFORMATION);
  156. ModalResult := MrOk;
  157. end else if (i>0) then begin
  158. Application.MessageBox(PChar('One or more of your operations has not been executed:'+#10+
  159. 'Errors:'+#10+
  160. errors+#10+#10+
  161. 'Total successfully executed operations: '+inttostr(i)),PChar(Application.Title),MB_OK+MB_ICONWARNING);
  162. ModalResult := MrOk;
  163. end else begin
  164. raise Exception.Create(errors);
  165. end;
  166. Finally
  167. ops.Free;
  168. End;
  169. end;
  170. procedure TFRMSaleAccounts.FormCreate(Sender: TObject);
  171. begin
  172. FSenderAccounts := TOrderedCardinalList.Create;
  173. ebSenderAccount.Text := '';
  174. ebSalePrice.Text := '';
  175. ebLockedUntilBlock.Text := '';
  176. ebSellerAccount.Text := '';
  177. ebNewOwnerPublicKey.Text := '';
  178. memoAccounts.lines.Clear;
  179. FDisabled := false;
  180. end;
  181. procedure TFRMSaleAccounts.FormDestroy(Sender: TObject);
  182. begin
  183. FSenderAccounts.Free;
  184. end;
  185. procedure TFRMSaleAccounts.SetWalletKeys(const Value: TWalletKeys);
  186. begin
  187. if FWalletKeys=Value then exit;
  188. if Assigned(FWalletKeys) then FWalletKeys.OnChanged := FOldOnChanged;
  189. FWalletKeys := Value;
  190. if Assigned(FWalletKeys) then begin
  191. FOldOnChanged := FWalletKeys.OnChanged;
  192. FWalletKeys.OnChanged := OnWalletKeysChanged;
  193. end;
  194. UpdateWalletKeys;
  195. end;
  196. procedure TFRMSaleAccounts.UpdateAccountsInfo;
  197. Var ld : Boolean;
  198. i : Integer;
  199. balance : int64;
  200. acc : TAccount;
  201. accountstext : String;
  202. begin
  203. ld := FDisabled;
  204. FDisabled := true;
  205. Try
  206. lblAccountCaption.Caption := 'Account';
  207. lblAccountsCount.Visible := false;
  208. lblAccountsCount.caption := inttostr(senderAccounts.Count)+' accounts';
  209. balance := 0;
  210. if SenderAccounts.Count<=0 then begin
  211. ebSenderAccount.Text := '';
  212. memoAccounts.Visible := false;
  213. ebSenderAccount.Visible := true;
  214. end else if SenderAccounts.Count=1 then begin
  215. ebSenderAccount.Text := TAccountComp.AccountNumberToAccountTxtNumber(SenderAccounts.Get(0));
  216. memoAccounts.Visible := false;
  217. ebSenderAccount.Visible := true;
  218. balance := TNode.Node.Operations.SafeBoxTransaction.Account(SenderAccounts.Get(0)).balance;
  219. end else begin
  220. // Multiple sender accounts
  221. lblAccountCaption.Caption := 'Accounts';
  222. lblAccountsCount.Visible := true;
  223. ebSenderAccount.Visible := false;
  224. accountstext := '';
  225. for i := 0 to SenderAccounts.Count - 1 do begin
  226. acc := TNode.Node.Operations.SafeBoxTransaction.Account(SenderAccounts.Get(i));
  227. balance := balance + acc.balance;
  228. if (accountstext<>'') then accountstext:=accountstext+'; ';
  229. accountstext := accountstext+TAccountComp.AccountNumberToAccountTxtNumber(acc.account)+' ('+TAccountComp.FormatMoney(acc.balance)+')';
  230. end;
  231. memoAccounts.Lines.Text := accountstext;
  232. memoAccounts.Visible := true;
  233. end;
  234. ebSenderAccount.Enabled := ebSenderAccount.Visible;
  235. lblAccountBalance.Caption := TAccountComp.FormatMoney(balance);
  236. Finally
  237. FDisabled := ld;
  238. End;
  239. end;
  240. end.