OSDN Git Service

Merge pull request #4 from Bytom/retireTx
[bytom/bytom-java-sdk.git] / java-sdk / src / main / java / io / bytom / api / Transaction.java
1 package io.bytom.api;
2
3 import com.google.gson.annotations.SerializedName;
4 import io.bytom.common.ParameterizedTypeImpl;
5 import io.bytom.common.Utils;
6 import io.bytom.exception.BytomException;
7 import io.bytom.http.Client;
8 import org.apache.log4j.Logger;
9
10 import java.lang.reflect.Type;
11 import java.util.*;
12
13 /**
14  * <h1>Transaction Class</h1>
15  */
16 public class Transaction {
17     /**
18      * Unique identifier, or transaction hash, of a transaction.
19      */
20     @SerializedName("tx_id")
21     public String txId;
22
23     /**
24      * Time of transaction.
25      */
26     @SerializedName("block_time")
27     public String blockTime;
28
29     /**
30      * Unique identifier, or block hash, of the block containing a transaction.
31      */
32     @SerializedName("block_hash")
33     public String blockHash;
34
35     /**
36      * Index of a transaction within the block.
37      */
38     @SerializedName("block_index")
39     public String blockIndex;
40
41     @SerializedName("block_transactions_count")
42     public String blockTransactionsCount;
43
44     /**
45      * Height of the block containing a transaction.
46      */
47     @SerializedName("block_height")
48     public int blockHeight;
49
50     /**
51      * whether the state of the request has failed.
52      */
53     @SerializedName("status_fail")
54     public boolean statusFail;
55
56     /**
57      * List of specified inputs for a transaction.
58      */
59     public List<Input> inputs;
60
61     /**
62      * List of specified outputs for a transaction.
63      */
64     public List<Output> outputs;
65
66     private static Logger logger = Logger.getLogger(Transaction.class);
67
68     /**
69      * Serializes the Address into a form that is safe to transfer over the wire.
70      *
71      * @return the JSON-serialized representation of the Receiver object
72      */
73     public String toJson() {
74         return Utils.serializer.toJson(this);
75     }
76
77     public static class Builder {
78         /**
79          * Hex-encoded serialization of a transaction to add to the current template.
80          */
81         @SerializedName("base_transaction")
82         protected String baseTransaction;
83
84         /**
85          * List of actions in a transaction.
86          */
87         protected List<Action> actions;
88
89         /**
90          * A time duration in milliseconds. If the transaction is not fully signed and
91          * submitted within this time, it will be rejected by the blockchain.
92          * Additionally, any outputs reserved when building this transaction will remain
93          * reserved for this duration.
94          */
95         protected long ttl;
96
97         /**
98          * Call build-transaction api.<br>
99          *
100          * Builds a single transaction template.
101          *
102          * @param client client object which makes requests to the server
103          * @return a transaction template
104          */
105         public Template build(Client client) throws BytomException {
106             return client.request("build-transaction", this, Template.class);
107         }
108
109         /**
110          * Default constructor initializes actions list.
111          */
112         public Builder() {
113             this.actions = new ArrayList<>();
114         }
115
116         /**
117          * Sets the baseTransaction field and initializes the actions lists.<br>
118          * This constructor can be used when executing an atomic swap and the counter
119          * party has sent an initialized tx template.
120          */
121         public Builder(String baseTransaction) {
122             this.setBaseTransaction(baseTransaction);
123             this.actions = new ArrayList<>();
124         }
125
126         /**
127          * Sets the base transaction that will be added to the current template.
128          */
129         public Builder setBaseTransaction(String baseTransaction) {
130             this.baseTransaction = baseTransaction;
131             return this;
132         }
133
134         /**
135          * Adds an action to a transaction builder.
136          * @param action action to add
137          * @return updated builder object
138          */
139         public Builder addAction(Action action) {
140             this.actions.add(action);
141             return this;
142         }
143
144         /**
145          * Sets a transaction's time-to-live, which indicates how long outputs will be
146          * reserved for, and how long the transaction will remain valid. Passing zero will
147          * use the default TTL, which is 300000ms (5 minutes).
148          * @param ms the duration of the TTL, in milliseconds.
149          * @return updated builder object
150          */
151         public Builder setTtl(long ms) {
152             this.ttl = ms;
153             return this;
154         }
155     }
156
157     public static class QueryBuilder {
158
159         public String txId;
160
161         public String accountId;
162
163         public QueryBuilder setTxId(String txId) {
164             this.txId = txId;
165             return this;
166         }
167
168         public QueryBuilder setAccountId(String accountId) {
169             this.accountId = accountId;
170             return this;
171         }
172
173
174         /**
175          * call list-transactions api
176          *
177          * @param client client object that makes requests to the core
178          * @return Transaction Info
179          * @throws BytomException BytomException
180          */
181         public List<Transaction> list(Client client) throws BytomException {
182
183             Type listType = new ParameterizedTypeImpl(List.class, new Class[]{Transaction.class});
184             List<Transaction> transactionList = client.request("list-transactions", null, listType);
185
186             logger.info("list-transactions:");
187             logger.info("size of transactionList:" + transactionList.size());
188             logger.info("all transactions:");
189             for (int i = 0; i < transactionList.size(); i++) {
190                 logger.info(transactionList.get(i).toJson());
191             }
192
193             return transactionList;
194         }
195
196         public List<Transaction> listById(Client client) throws BytomException {
197             Map<String, Object> req = new HashMap<String, Object>();
198             req.put("tx_id", this.txId);
199             req.put("detail", true);
200
201             Type listType = new ParameterizedTypeImpl(List.class, new Class[]{Transaction.class});
202             List<Transaction> transactionList = client.request("list-transactions", req, listType);
203
204             logger.info("list-transactions:");
205             logger.info("size of transactionList:" + transactionList.size());
206             logger.info("all transactions:");
207             for (int i = 0; i < transactionList.size(); i++) {
208                 logger.info(transactionList.get(i).toJson());
209             }
210
211             return transactionList;
212         }
213
214         public List<Transaction> listByAccountId(Client client) throws BytomException {
215             Map<String, Object> req = new HashMap<String, Object>();
216             req.put("account_id", this.accountId);
217
218             Type listType = new ParameterizedTypeImpl(List.class, new Class[]{Transaction.class});
219             List<Transaction> transactionList = client.request("list-transactions", req, listType);
220
221             logger.info("list-transactions:");
222             logger.info("size of transactionList:" + transactionList.size());
223             logger.info("all transactions:");
224             for (int i = 0; i < transactionList.size(); i++) {
225                 logger.info(transactionList.get(i).toJson());
226             }
227
228             return transactionList;
229         }
230
231         /**
232          * call get-transaction api
233          *
234          * @param client
235          * @return
236          * @throws BytomException
237          */
238         public Transaction get(Client client) throws BytomException {
239             Map<String, Object> req = new HashMap<String, Object>();
240             req.put("tx_id", this.txId);
241
242             Transaction transaction = client.request("get-transaction", req, Transaction.class);
243
244             logger.info("get-transaction:");
245             logger.info(transaction.toJson());
246
247             return transaction;
248         }
249
250     }
251
252     public static class SignerBuilder {
253         /**
254          * call sign-transaction api
255          *
256          * Sends a transaction template to a remote password for signing.
257          *
258          * @param client
259          * @param template a signed transaction template
260          * @param password
261          * @return
262          * @throws BytomException
263          */
264         public Template sign(Client client, Template template,
265                                          String password) throws BytomException {
266             HashMap<String, Object> req = new HashMap<String, Object>();
267             req.put("transaction", template);
268             req.put("password", password);
269
270             Template templateResult = client.requestGet("sign-transaction", req, "transaction",
271                     Transaction.Template.class);
272
273             logger.info("sign-transaction:");
274             logger.info(templateResult.toJson());
275
276             return templateResult;
277         }
278
279     }
280
281     /**
282      * A single input included in a transaction.
283      */
284     public static class Input {
285         /**
286          * The alias of the account transferring the asset (possibly null if the input is
287          * an issuance or an unspent output is specified).
288          */
289         @SerializedName("account_alias")
290         public String accountAlias;
291
292         /**
293          * The id of the account transferring the asset (possibly null if the input is an
294          * issuance or an unspent output is specified).
295          */
296         @SerializedName("account_id")
297         public String accountId;
298
299         @SerializedName("address")
300         public String address;
301
302         /**
303          * The number of units of the asset being issued or spent.
304          */
305         public long amount;
306
307         /**
308          * The alias of the asset being issued or spent (possibly null).
309          */
310         @SerializedName("asset_alias")
311         public String assetAlias;
312
313         /**
314          * The definition of the asset being issued or spent (possibly null).
315          */
316         @SerializedName("asset_definition")
317         public Map<String, Object> assetDefinition;
318
319         /**
320          * The id of the asset being issued or spent.
321          */
322         @SerializedName("asset_id")
323         public String assetId;
324
325         /**
326          * The id of the output consumed by this input. Null if the input is an issuance.
327          */
328         @SerializedName("spent_output_id")
329         public String spentOutputId;
330
331         /**
332          * The type of the input.<br>
333          * Possible values are "issue" and "spend".
334          */
335         public String type;
336
337         public String arbitrary;
338
339         @SerializedName("control_program")
340         public String controlProgram;
341
342     }
343
344     /**
345      * A single output included in a transaction.
346      */
347     public static class Output {
348         /**
349          * The id of the output.
350          */
351         @SerializedName("id")
352         public String id;
353
354         /**
355          * The type the output.<br>
356          * Possible values are "control" and "retire".
357          */
358         public String type;
359
360         /**
361          * The output's position in a transaction's list of outputs.
362          */
363         public int position;
364
365         /**
366          * The control program which must be satisfied to transfer this output.
367          */
368         @SerializedName("control_program")
369         public String controlProgram;
370
371         /**
372          * The id of the asset being controlled.
373          */
374         @SerializedName("asset_id")
375         public String assetId;
376
377         /**
378          * The alias of the asset being controlled.
379          */
380         @SerializedName("asset_alias")
381         public String assetAlias;
382
383         /**
384          * The definition of the asset being controlled (possibly null).
385          */
386         @SerializedName("asset_definition")
387         public Map<String, Object> assetDefinition;
388
389         /**
390          * The number of units of the asset being controlled.
391          */
392         public long amount;
393
394         /**
395          * The id of the account controlling this output (possibly null if a control
396          * program is specified).
397          */
398         @SerializedName("account_id")
399         public String accountId;
400
401         /**
402          * The alias of the account controlling this output (possibly null if a control
403          * program is specified).
404          */
405         @SerializedName("account_alias")
406         public String accountAlias;
407
408         @SerializedName("address")
409         public String address;
410
411     }
412
413     /**
414      * Base class representing actions that can be taken within a transaction.
415      */
416     public static class Action extends HashMap<String, Object> {
417         /**
418          *
419          */
420         private static final long serialVersionUID = 7948250382060074590L;
421
422         /**
423          * Default constructor initializes list and sets the client token.
424          */
425         public Action() {
426             // Several action types require client_token as an idempotency key.
427             // It's safest to include a default value for this param.
428             this.put("client_token", UUID.randomUUID().toString());
429         }
430
431         /**
432          * Represents an issuance action.
433          */
434         public static class Issue extends Action {
435             /**
436              *
437              */
438             private static final long serialVersionUID = -6296543909434749786L;
439
440             /**
441              * Default constructor defines the action type as "issue"
442              */
443             public Issue() {
444                 this.put("type", "issue");
445             }
446
447             /**
448              * Specifies the asset to be issued using its alias.<br>
449              * <strong>Either this or {@link Issue#setAssetId(String)} must be
450              * called.</strong>
451              * @param alias alias of the asset to be issued
452              * @return updated action object
453              */
454             public Issue setAssetAlias(String alias) {
455                 this.put("asset_alias", alias);
456                 return this;
457             }
458
459             /**
460              * Specifies the asset to be issued using its id.<br>
461              * <strong>Either this or {@link Issue#setAssetAlias(String)} must be
462              * called.</strong>
463              * @param id id of the asset to be issued
464              * @return updated action object
465              */
466             public Issue setAssetId(String id) {
467                 this.put("asset_id", id);
468                 return this;
469             }
470
471             /**
472              * Specifies the amount of the asset to be issued.<br>
473              * <strong>Must be called.</strong>
474              * @param amount number of units of the asset to be issued
475              * @return updated action object
476              */
477             public Issue setAmount(long amount) {
478                 this.put("amount", amount);
479                 return this;
480             }
481         }
482
483         /**
484          * Represents a spend action taken on a particular account.
485          */
486         public static class SpendFromAccount extends Action {
487             /**
488              *
489              */
490             private static final long serialVersionUID = 6444162327409625893L;
491
492             /**
493              * Default constructor defines the action type as "spend_account"
494              */
495             public SpendFromAccount() {
496                 this.put("type", "spend_account");
497             }
498
499             /**
500              * Specifies the spending account using its alias.<br>
501              * <strong>Either this or {@link SpendFromAccount#setAccountId(String)} must
502              * be called.</strong><br>
503              * <strong>Must be used with {@link SpendFromAccount#setAssetAlias(String)}
504              * .</strong>
505              * @param alias alias of the spending account
506              * @return updated action object
507              */
508             public SpendFromAccount setAccountAlias(String alias) {
509                 this.put("account_alias", alias);
510                 return this;
511             }
512
513             /**
514              * Specifies the spending account using its id.<br>
515              * <strong>Either this or {@link SpendFromAccount#setAccountAlias(String)}
516              * must be called.</strong><br>
517              * <strong>Must be used with {@link SpendFromAccount#setAssetId(String)}
518              * .</strong>
519              * @param id id of the spending account
520              * @return updated action object
521              */
522             public SpendFromAccount setAccountId(String id) {
523                 this.put("account_id", id);
524                 return this;
525             }
526
527             /**
528              * Specifies the asset to be spent using its alias.<br>
529              * <strong>Either this or {@link SpendFromAccount#setAssetId(String)} must be
530              * called.</strong><br>
531              * <strong>Must be used with {@link SpendFromAccount#setAccountAlias(String)}
532              * .</strong>
533              * @param alias alias of the asset to be spent
534              * @return updated action object
535              */
536             public SpendFromAccount setAssetAlias(String alias) {
537                 this.put("asset_alias", alias);
538                 return this;
539             }
540
541             /**
542              * Specifies the asset to be spent using its id.<br>
543              * <strong>Either this or {@link SpendFromAccount#setAssetAlias(String)} must
544              * be called.</strong><br>
545              * <strong>Must be used with {@link SpendFromAccount#setAccountId(String)}
546              * .</strong><br>
547              * @param id id of the asset to be spent
548              * @return updated action object
549              */
550             public SpendFromAccount setAssetId(String id) {
551                 this.put("asset_id", id);
552                 return this;
553             }
554
555             /**
556              * Specifies the amount of asset to be spent.<br>
557              * <strong>Must be called.</strong>
558              * @param amount number of units of the asset to be spent
559              * @return updated action object
560              */
561             public SpendFromAccount setAmount(long amount) {
562                 this.put("amount", amount);
563                 return this;
564             }
565         }
566
567         /**
568          * Represents a control action taken on a particular account.
569          */
570         public static class ControlWithAccount extends Action {
571             /**
572              *
573              */
574             private static final long serialVersionUID = -1067464339402520620L;
575
576             /**
577              * Default constructor defines the action type as "control_account"
578              */
579             public ControlWithAccount() {
580                 this.put("type", "control_account");
581             }
582
583             /**
584              * Specifies the controlling account using its alias.<br>
585              * <strong>Either this or {@link ControlWithAccount#setAccountId(String)} must
586              * be called.</strong><br>
587              * <strong>Must be used with {@link ControlWithAccount#setAssetAlias(String)}
588              * .</strong>
589              * @param alias alias of the controlling account
590              * @return updated action object
591              */
592             public ControlWithAccount setAccountAlias(String alias) {
593                 this.put("account_alias", alias);
594                 return this;
595             }
596
597             /**
598              * Specifies the controlling account using its id.<br>
599              * <strong>Either this or {@link ControlWithAccount#setAccountAlias(String)}
600              * must be called.</strong><br>
601              * <strong>Must be used with {@link ControlWithAccount#setAssetId(String)}
602              * .</strong>
603              * @param id id of the controlling account
604              * @return updated action object
605              */
606             public ControlWithAccount setAccountId(String id) {
607                 this.put("account_id", id);
608                 return this;
609             }
610
611             /**
612              * Specifies the asset to be controlled using its alias.<br>
613              * <strong>Either this or {@link ControlWithAccount#setAssetId(String)} must
614              * be called.</strong><br>
615              * <strong>Must be used with
616              * {@link ControlWithAccount#setAccountAlias(String)}.</strong>
617              * @param alias alias of the asset to be controlled
618              * @return updated action object
619              */
620             public ControlWithAccount setAssetAlias(String alias) {
621                 this.put("asset_alias", alias);
622                 return this;
623             }
624
625             /**
626              * Specifies the asset to be controlled using its id.<br>
627              * <strong>Either this or {@link ControlWithAccount#setAssetAlias(String)}
628              * must be called.</strong><br>
629              * <strong>Must be used with {@link ControlWithAccount#setAccountId(String)}
630              * .</strong>
631              * @param id id of the asset to be controlled
632              * @return updated action object
633              */
634             public ControlWithAccount setAssetId(String id) {
635                 this.put("asset_id", id);
636                 return this;
637             }
638
639             /**
640              * Specifies the amount of the asset to be controlled.<br>
641              * <strong>Must be called.</strong>
642              * @param amount number of units of the asset to be controlled
643              * @return updated action object
644              */
645             public ControlWithAccount setAmount(long amount) {
646                 this.put("amount", amount);
647                 return this;
648             }
649
650         }
651
652         /**
653          * Represents a control action taken on a particular address.
654          */
655         public static class ControlWithAddress extends Action {
656             /**
657              *
658              */
659             private static final long serialVersionUID = 1292007349260961499L;
660
661             /**
662              * Default constructor defines the action type as "control_address"
663              */
664             public ControlWithAddress() {
665                 this.put("type", "control_address");
666             }
667
668             public ControlWithAddress setAddress(String address) {
669                 this.put("address", address);
670                 return this;
671             }
672
673             /**
674              * Specifies the asset to be controlled using its alias.<br>
675              * <strong>Either this or {@link ControlWithAddress#setAssetId(String)} must
676              * be called.</strong><br>
677              * @param alias alias of the asset to be controlled
678              * @return updated action object
679              */
680             public ControlWithAddress setAssetAlias(String alias) {
681                 this.put("asset_alias", alias);
682                 return this;
683             }
684
685             /**
686              * Specifies the asset to be controlled using its id.<br>
687              * <strong>Either this or {@link ControlWithAccount#setAssetAlias(String)}
688              * must be called.</strong><br>
689              * @param id id of the asset to be controlled
690              * @return updated action object
691              */
692             public ControlWithAddress setAssetId(String id) {
693                 this.put("asset_id", id);
694                 return this;
695             }
696
697             /**
698              * Specifies the amount of the asset to be controlled.<br>
699              * <strong>Must be called.</strong>
700              * @param amount number of units of the asset to be controlled
701              * @return updated action object
702              */
703             public ControlWithAddress setAmount(long amount) {
704                 this.put("amount", amount);
705                 return this;
706             }
707
708         }
709
710         /**
711          * Use this action to pay assets into a {@link Receiver}.
712          */
713         public static class ControlWithReceiver extends Action {
714             /**
715              *
716              */
717             private static final long serialVersionUID = 7280759134960453401L;
718
719             /**
720              * Default constructor.
721              */
722             public ControlWithReceiver() {
723                 this.put("type", "control_receiver");
724             }
725
726             /**
727              * Specifies the receiver that is being paid to.
728              *
729              * @param receiver the receiver being paid to
730              * @return this ControlWithReceiver object
731              */
732             public ControlWithReceiver setReceiver(Receiver receiver) {
733                 this.put("receiver", receiver);
734                 return this;
735             }
736
737             /**
738              * Specifies the asset to be controlled using its alias.
739              * <p>
740              * <strong>Either this or {@link ControlWithReceiver#setAssetId(String)} must
741              * be called.</strong>
742              * @param alias unique alias of the asset to be controlled
743              * @return this ControlWithReceiver object
744              */
745             public ControlWithReceiver setAssetAlias(String alias) {
746                 this.put("asset_alias", alias);
747                 return this;
748             }
749
750             /**
751              * Specifies the asset to be controlled using its id.
752              * <p>
753              * <strong>Either this or {@link ControlWithReceiver#setAssetAlias(String)}
754              * must be called.</strong>
755              * @param id unique ID of the asset to be controlled
756              * @return this ControlWithReceiver object
757              */
758             public ControlWithReceiver setAssetId(String id) {
759                 this.put("asset_id", id);
760                 return this;
761             }
762
763             /**
764              * Specifies the amount of the asset to be controlled.
765              * <p>
766              * <strong>Must be called.</strong>
767              * @param amount the number of units of the asset to be controlled
768              * @return this ControlWithReceiver object
769              */
770             public ControlWithReceiver setAmount(long amount) {
771                 this.put("amount", amount);
772                 return this;
773             }
774
775         }
776
777         /**
778          * Represents a retire action.
779          */
780         public static class Retire extends Action {
781             /**
782              *
783              */
784             private static final long serialVersionUID = -8434272436211832706L;
785
786             /**
787              * Default constructor defines the action type as "control_program"
788              */
789             public Retire() {
790                 this.put("type", "retire");
791             }
792
793             /**
794              * Specifies the amount of the asset to be retired.<br>
795              * <strong>Must be called.</strong>
796              * @param amount number of units of the asset to be retired
797              * @return updated action object
798              */
799             public Retire setAmount(long amount) {
800                 this.put("amount", amount);
801                 return this;
802             }
803
804             /**
805              * Specifies the asset to be retired using its alias.<br>
806              * <strong>Either this or {@link Retire#setAssetId(String)} must be
807              * called.</strong>
808              * @param alias alias of the asset to be retired
809              * @return updated action object
810              */
811             public Retire setAssetAlias(String alias) {
812                 this.put("asset_alias", alias);
813                 return this;
814             }
815
816             /**
817              * Specifies the asset to be retired using its id.<br>
818              * <strong>Either this or {@link Retire#setAssetAlias(String)} must be
819              * called.</strong>
820              * @param id id of the asset to be retired
821              * @return updated action object
822              */
823             public Retire setAssetId(String id) {
824                 this.put("asset_id", id);
825                 return this;
826             }
827             /**
828              * @param arbitrary message to be on the chain (must be hexadecimal)
829              * @return updated action object
830              */
831             public Retire setArbitrary(String arbitrary){
832                 this.put("arbitrary",arbitrary);
833                 return this;
834             }
835             public Retire setAccountAlias(String alias) {
836                 this.put("account_alias", alias);
837                 return this;
838             }
839
840             public Retire setAccountId(String id) {
841                 this.put("account_id", id);
842                 return this;
843             }
844
845         }
846
847         /**
848          * Sets a k,v parameter pair.
849          * @param key the key on the parameter object
850          * @param value the corresponding value
851          * @return updated action object
852          */
853         public Action setParameter(String key, Object value) {
854             this.put(key, value);
855             return this;
856         }
857     }
858
859     public static class Template {
860         /**
861          * A hex-encoded representation of a transaction template.
862          */
863         @SerializedName("raw_transaction")
864         public String rawTransaction;
865
866         /**
867          * The list of signing instructions for inputs in the transaction.
868          */
869         @SerializedName("signing_instructions")
870         public List<SigningInstruction> signingInstructions;
871
872         /**
873          * For core use only.
874          */
875         @SerializedName("local")
876         private boolean local;
877
878         /**
879          * False (the default) makes the transaction "final" when signing, preventing
880          * further changes - the signature program commits to the transaction's signature
881          * hash. True makes the transaction extensible, committing only to the elements in
882          * the transaction so far, permitting the addition of new elements.
883          */
884         @SerializedName("allow_additional_actions")
885         private boolean allowAdditionalActions;
886
887         /**
888          * allowAdditionalActions causes the transaction to be signed so that it can be
889          * used as a base transaction in a multiparty trade flow. To enable this setting,
890          * call this method after building the transaction, but before sending it to the
891          * signer.
892          *
893          * All participants in a multiparty trade flow should call this method except for
894          * the last signer. Do not call this option if the transaction is complete, i.e.
895          * if it will not be used as a base transaction.
896          * @return updated transaction template
897          */
898         public Template allowAdditionalActions() {
899             this.allowAdditionalActions = true;
900             return this;
901         }
902
903         /**
904          * A single signing instruction included in a transaction template.
905          */
906         public static class SigningInstruction {
907             /**
908              * The input's position in a transaction's list of inputs.
909              */
910             public int position;
911
912             /**
913              * A list of components used to coordinate the signing of an input.
914              */
915             @SerializedName("witness_components")
916             public WitnessComponent[] witnessComponents;
917         }
918
919         /**
920          * A single witness component, holding information that will become the input
921          * witness.
922          */
923         public static class WitnessComponent {
924             /**
925              * The type of witness component.<br>
926              * Possible types are "data" and "raw_tx_signature".
927              */
928             public String type;
929
930             /**
931              * Data to be included in the input witness (null unless type is "data").
932              */
933             public String value;
934
935             /**
936              * The number of signatures required for an input (null unless type is
937              * "signature").
938              */
939             public int quorum;
940
941             /**
942              * The list of keys to sign with (null unless type is "signature").
943              */
944             public KeyID[] keys;
945
946             /**
947              * The list of signatures made with the specified keys (null unless type is
948              * "signature").
949              */
950             public String[] signatures;
951         }
952
953         /**
954          * A class representing a derived signing key.
955          */
956         public static class KeyID {
957             /**
958              * The extended public key associated with the private key used to sign.
959              */
960             public String xpub;
961
962             /**
963              * The derivation path of the extended public key.
964              */
965             @SerializedName("derivation_path")
966             public String[] derivationPath;
967         }
968
969         /**
970          * Serializes the Address into a form that is safe to transfer over the wire.
971          *
972          * @return the JSON-serialized representation of the Receiver object
973          */
974         public String toJson() {
975             return Utils.serializer.toJson(this);
976         }
977
978     }
979
980     public static class SubmitResponse {
981         /**
982          * The transaction id.
983          */
984         public String tx_id;
985
986         public String toJson() {
987             return Utils.serializer.toJson(this);
988         }
989
990     }
991
992     /**
993      * Call submit-transaction api
994      *
995      * @param client
996      * @param template
997      * @return
998      * @throws BytomException
999      */
1000     public static SubmitResponse submit(Client client, Template template)
1001             throws BytomException {
1002         HashMap<String, Object> body = new HashMap<>();
1003         body.put("raw_transaction", template.rawTransaction);
1004         return client.request("submit-transaction", body, SubmitResponse.class);
1005     }
1006
1007     public static class TransactionGas {
1008         /**
1009          * total consumed neu(1BTM = 10^8NEU) for execute transaction.
1010          */
1011         @SerializedName("total_neu")
1012         public int totalNeu;
1013
1014         /**
1015          * consumed neu for storage transaction .
1016          */
1017         @SerializedName("storage_neu")
1018         public int storageNeu;
1019         /**
1020          * consumed neu for execute VM.
1021          */
1022         @SerializedName("vm_neu")
1023         public int vmNeu;
1024     }
1025
1026     /**
1027      * call estimate-transaction-gas api
1028      *
1029      * @param client
1030      * @param template
1031      * @return
1032      * @throws BytomException
1033      */
1034     public static TransactionGas estimateGas(Client client, Template template)
1035             throws BytomException {
1036         HashMap<String, Object> body = new HashMap<>();
1037         body.put("transaction_template", template);
1038         return client.request("estimate-transaction-gas", body, TransactionGas.class);
1039     }
1040
1041     public static class Feed {
1042         /**
1043          * name of the transaction feed.
1044          */
1045         public String alias;
1046         /**
1047          * filter, filter of the transaction feed.
1048          */
1049         public String filter;
1050
1051         /**
1052          * param, param of the transaction feed.
1053          */
1054         public TransactionFeedParam param;
1055
1056         private static Logger logger = Logger.getLogger(Transaction.class);
1057
1058         /**
1059          * Serializes the TransactionFeed into a form that is safe to transfer over the wire.
1060          *
1061          * @return the JSON-serialized representation of the TransactionFeed object
1062          */
1063         public String toJson() {
1064             return Utils.serializer.toJson(this);
1065         }
1066
1067         public static class Builder {
1068
1069             public String alias;
1070
1071             public String filter;
1072
1073             public Builder() {
1074             }
1075
1076             public Builder setAlias(String alias) {
1077                 this.alias = alias;
1078                 return this;
1079             }
1080
1081             public Builder setFilter(String filter) {
1082                 this.filter = filter;
1083                 return this;
1084             }
1085
1086             /**
1087              * Call create-transaction-feed api
1088              *
1089              * @param client
1090              * @throws BytomException
1091              */
1092             public void create(Client client) throws BytomException {
1093                 client.request("create-transaction-feed", this);
1094                 logger.info("create-transaction-feed");
1095             }
1096         }
1097
1098         /**
1099          * Call get-transaction-feed api
1100          *
1101          * @param client
1102          * @param alias
1103          * @return
1104          * @throws BytomException
1105          */
1106         public static Feed getByAlias(Client client, String alias) throws BytomException {
1107             Map<String, Object> req = new HashMap<String, Object>();
1108             req.put("alias", alias);
1109
1110             // the return param contains txfeed.
1111             Feed transactionFeed = client.requestGet("get-transaction-feed",
1112                     req, "txfeed", Feed.class);
1113             logger.info("get-transaction-feed.");
1114             logger.info(transactionFeed.toJson());
1115
1116             return transactionFeed;
1117         }
1118
1119         /**
1120          * Call update-transaction-feed api
1121          *
1122          * @param client
1123          * @param alias
1124          * @param filter
1125          * @throws BytomException
1126          */
1127         public static void update(Client client, String alias, String filter) throws BytomException {
1128             Map<String, Object> req = new HashMap<String, Object>();
1129             req.put("alias", alias);
1130             req.put("filter", filter);
1131             client.request("update-transaction-feed", req);
1132             logger.info("update-transaction-feed successfully");
1133         }
1134
1135         /**
1136          * Call list-transaction-feeds api
1137          * @param client
1138          * @return
1139          * @throws BytomException
1140          */
1141         public static List<Feed> list(Client client) throws BytomException {
1142
1143             Type listType = new ParameterizedTypeImpl(List.class, new Class[]{Feed.class});
1144             List<Feed> transactionFeedList = client.request("list-transaction-feeds", null, listType);
1145
1146             logger.info("list-transaction-feeds:");
1147             logger.info("size of transactionList:" + transactionFeedList.size());
1148             for (int i =0 ;i < transactionFeedList.size();i++) {
1149                 logger.info(transactionFeedList.get(i).toJson());
1150             }
1151             return transactionFeedList;
1152         }
1153
1154         /**
1155          * Call delete-transaction-feed api
1156          *
1157          * @param client
1158          * @param alias
1159          * @throws BytomException
1160          */
1161         public static void deleteByAlias(Client client, String alias) throws BytomException {
1162             Map<String, Object> req = new HashMap<String, Object>();
1163             req.put("alias", alias);
1164             client.request("delete-transaction-feed", req);
1165             logger.info("delete-transaction-feed successfully");
1166         }
1167
1168
1169
1170         public class TransactionFeedParam {
1171
1172             /**
1173              * assetid
1174              */
1175             public String assetid;
1176
1177             /**
1178              * lowerlimit
1179              */
1180             public long lowerlimit;
1181
1182             /**
1183              * upperlimit
1184              */
1185             public long upperlimit;
1186
1187         }
1188     }
1189 }