OSDN Git Service

add some details to transactions.md file
[bytom/bytom-java-sdk.git] / doc / transactions.md
1 ## Creating transactions
2
3 Creating a transaction consists of three steps:
4
5 1. **Build transaction**: Define what the transaction is supposed to do: issue new units of an asset, spend assets held in an account, control assets with an account, etc.
6 2. **Sign transaction**: Authorize the spending of assets or the issuance of new asset units using private keys.
7 3. **Submit transaction**: Submit a complete, signed transaction to the blockchain, and propagate it to other cores on the network.
8
9 ### Build transaction
10
11 Rather than forcing you to manipulate inputs, outputs and change directly, the Bytom Core API allows you to build transactions using a list of high-level **actions**.
12
13 There are five types of actions:
14
15 | ACTION                                  | DESCRIPTION                                                  |
16 | --------------------------------------- | ------------------------------------------------------------ |
17 | Issue                                   | Issues new units of a specified asset.                       |
18 | Spend from account                      | Spends units of a specified asset from a specified account. Automatically handles locating outputs with enough units, and the creation of change outputs. |
19 | Spend an unspent output from an account | Spends an entire, specific unspent output in an account. Change must be handled manually, using other actions. |
20 | Control with receiver                   | Receives units of an asset into a receiver, which contains a control program and supplementary payment information, such as an expiration date. Used when making a payment to an external party/account in another Bytom Core. |
21 | Retire                                  | Retires units of a specified asset.                          |
22
23 ### Sign transaction
24
25 In order for a transaction to be accepted into the blockchain, its inputs must contain valid signatures. For issuance inputs, the signature must correspond to public keys named in the issuance program. For spending inputs, the signature must correspond to the public keys named in the control programs of the outputs being spent.
26
27 Transaction signing provides the blockchain with its security. Strong cryptography prevents everyone–even the operators of the blockchain network–from producing valid transaction signatures without the relevant private keys.
28
29 ### Submit transaction
30
31 Once a transaction is balanced and all inputs are signed, it is considered valid and can be submitted to the blockchain. The local core will forward the transaction to the generator, which adds it to the blockchain and propagates it to other cores on the network. 
32
33 The Chain Core API does not return a response until either the transaction has been added to the blockchain and indexed by the local core, or there was an error. This allows you to write your applications in a linear fashion. In general, if a submission responds with success, the rest of your application may proceed with the guarantee that the transaction has been committed to the blockchain.
34
35 ## Examples
36
37 ### Asset issuance
38
39 Issue 1000 units of gold to Alice.
40
41 #### Within a Chain Core
42
43 ```java
44 Transaction.Template issuance = new Transaction.Builder()
45   .addAction(new Transaction.Action.Issue()
46     .setAssetAlias("gold")
47     .setAmount(1000)
48   ).addAction(new Transaction.Action.ControlWithAccount()
49     .setAccountAlias("alice")
50     .setAssetAlias("gold")
51     .setAmount(1000)
52   ).build(client);
53
54 Transaction.Template signedIssuance = new Transaction.SignerBuilder().sign(client,
55                 issuance, "123456");
56
57 Transaction.submit(client, signedIssuance);
58 ```
59
60 #### Between two Chain Cores
61
62 First, Bob creates a receiver in his account, which he can serialize and send to the issuer of gold.
63
64 ```java
65 Receiver bobIssuanceReceiver = new Account.ReceiverBuilder()
66   .setAccountAlias("bob")
67   .create(otherCoreClient);
68 String bobIssuanceReceiverSerialized = bobIssuanceReceiver.toJson();
69 ```
70
71 The issuer then builds, signs, and submits a transaction, sending gold to Bob’s receiver.
72
73 ```java
74 Transaction.Template issuanceToReceiver = new Transaction.Builder()
75   .addAction(new Transaction.Action.Issue()
76     .setAssetAlias("gold")
77     .setAmount(10)
78   ).addAction(new Transaction.Action.ControlWithReceiver()
79     .setReceiver(Receiver.fromJson(bobIssuanceReceiverSerialized))
80     .setAssetAlias("gold")
81     .setAmount(10)
82   ).build(client);
83
84 Transaction.Template signedIssuanceToReceiver = new Transaction.SignerBuilder().sign(client,
85                 issuanceToReceiver, "123456");
86
87 Transaction.submit(client, signedIssuanceToReceiver);
88 ```
89
90 ### Simple payment
91
92 Alice pays 10 units of gold to Bob.
93
94 #### Within a Chain Core
95
96 ```java
97 Transaction.Template payment = new Transaction.Builder()
98   .addAction(new Transaction.Action.SpendFromAccount()
99     .setAccountAlias("alice")
100     .setAssetAlias("gold")
101     .setAmount(10)
102   ).addAction(new Transaction.Action.ControlWithAccount()
103     .setAccountAlias("bob")
104     .setAssetAlias("gold")
105     .setAmount(10)
106   ).build(client);
107
108 Transaction.Template signedPayment = new Transaction.SignerBuilder().sign(client,
109                 payment, "123456");
110
111 Transaction.submit(client, signedPayment);
112 ```
113
114 #### Between two Chain Cores
115
116 First, Bob creates a receiver in his account, which he can serialize and send to Alice.
117
118 ```java
119 Receiver bobPaymentReceiver = new Account.ReceiverBuilder()
120   .setAccountAlias("bob")
121   .create(otherCoreClient);
122 String bobPaymentReceiverSerialized = bobPaymentReceiver.toJson();
123 ```
124
125 Alice then builds, signs, and submits a transaction, sending gold to Bob’s receiver.
126
127 ```java
128 Transaction.Template paymentToReceiver = new Transaction.Builder()
129   .addAction(new Transaction.Action.SpendFromAccount()
130     .setAccountAlias("alice")
131     .setAssetAlias("gold")
132     .setAmount(10)
133   ).addAction(new Transaction.Action.ControlWithReceiver()
134     .setReceiver(Receiver.fromJson(bobPaymentReceiverSerialized))
135     .setAssetAlias("gold")
136     .setAmount(10)
137   ).build(client);
138
139 Transaction.Template signedPaymentToReceiver = new Transaction.SignerBuilder().sign(client,
140                 paymentToReceiver, "123456");
141
142 Transaction.submit(client, signedPaymentToReceiver);
143 ```
144
145 ### Multi-asset payment
146
147 Alice pays 10 units of gold and 20 units of silver to Bob.
148
149 #### Within a Chain Core
150
151 ```java
152 Transaction.Template multiAssetPayment = new Transaction.Builder()
153   .addAction(new Transaction.Action.SpendFromAccount()
154     .setAccountAlias("alice")
155     .setAssetAlias("gold")
156     .setAmount(10)
157   ).addAction(new Transaction.Action.SpendFromAccount()
158     .setAccountAlias("alice")
159     .setAssetAlias("silver")
160     .setAmount(20)
161   ).addAction(new Transaction.Action.ControlWithAccount()
162     .setAccountAlias("bob")
163     .setAssetAlias("gold")
164     .setAmount(10)
165   ).addAction(new Transaction.Action.ControlWithAccount()
166     .setAccountAlias("bob")
167     .setAssetAlias("silver")
168     .setAmount(20)
169   ).build(client);
170
171 Transaction.Template signedMultiAssetPayment = new Transaction.SignerBuilder().sign(client,
172                 multiAssetPayment, "123456");
173
174 Transaction.submit(client, signedMultiAssetPayment);
175 ```
176
177 #### Between two Chain Cores
178
179 Currently, the transaction builder API assigns each receiver to its own output, which means that a single receiver can only be used to receive a single asset type. It’s important for Bob not to re-use receivers, so he creates one for each asset payment he will receive. He serializes both and sends them to Alice.
180
181 ```java
182 Receiver bobGoldReceiver = new Account.ReceiverBuilder()
183   .setAccountAlias("bob")
184   .create(otherCoreClient);
185 String bobGoldReceiverSerialized = bobGoldReceiver.toJson();
186
187 Receiver bobSilverReceiver = new Account.ReceiverBuilder()
188   .setAccountAlias("bob")
189   .create(otherCoreClient);
190 String bobSilverReceiverSerialized = bobSilverReceiver.toJson();
191 ```
192
193 Alice then builds, signs, and submits a transaction, sending gold and silver to Bob’s receivers.
194
195 ```java
196 Transaction.Template multiAssetToReceiver = new Transaction.Builder()
197   .addAction(new Transaction.Action.SpendFromAccount()
198     .setAccountAlias("alice")
199     .setAssetAlias("gold")
200     .setAmount(10)
201   ).addAction(new Transaction.Action.SpendFromAccount()
202     .setAccountAlias("alice")
203     .setAssetAlias("silver")
204     .setAmount(20)
205   ).addAction(new Transaction.Action.ControlWithReceiver()
206     .setReceiver(Receiver.fromJson(bobGoldReceiverSerialized))
207     .setAssetAlias("gold")
208     .setAmount(10)
209   ).addAction(new Transaction.Action.ControlWithReceiver()
210     .setReceiver(Receiver.fromJson(bobSilverReceiverSerialized))
211     .setAssetAlias("silver")
212     .setAmount(20)
213   ).build(client);
214
215 Transaction.Template signedMultiAssetToReceiver = new Transaction.SignerBuilder().sign(client,
216                 multiAssetToReceiver, "123456");
217
218 Transaction.submit(client, signedMultiAssetToReceiver);
219 ```
220
221 ### Asset retirement
222
223 Alice retires 50 units of gold from her account.
224
225 ```java
226 Transaction.Template retirement = new Transaction.Builder()
227   .addAction(new Transaction.Action.SpendFromAccount()
228     .setAccountAlias("alice")
229     .setAssetAlias("gold")
230     .setAmount(50)
231   ).addAction(new Transaction.Action.Retire()
232     .setAssetAlias("gold")
233     .setAmount(50)
234   ).build(client);
235
236 Transaction.Template signedRetirement = new Transaction.SignerBuilder().sign(client,
237                 retirement, "123456");
238
239 Transaction.submit(client, signedRetirement);
240 ```
241