1 ## Creating transactions
3 Creating a transaction consists of three steps:
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.
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**.
13 There are five types of actions:
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. |
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.
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.
29 ### Submit transaction
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.
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.
39 Issue 1000 units of gold to Alice.
41 #### Within a Chain Core
44 Transaction.Template issuance = new Transaction.Builder()
45 .addAction(new Transaction.Action.Issue()
46 .setAssetAlias("gold")
48 ).addAction(new Transaction.Action.ControlWithAccount()
49 .setAccountAlias("alice")
50 .setAssetAlias("gold")
54 Transaction.Template signedIssuance = new Transaction.SignerBuilder().sign(client,
57 Transaction.submit(client, signedIssuance);
60 #### Between two Chain Cores
62 First, Bob creates a receiver in his account, which he can serialize and send to the issuer of gold.
65 Receiver bobIssuanceReceiver = new Account.ReceiverBuilder()
66 .setAccountAlias("bob")
67 .create(otherCoreClient);
68 String bobIssuanceReceiverSerialized = bobIssuanceReceiver.toJson();
71 The issuer then builds, signs, and submits a transaction, sending gold to Bob’s receiver.
74 Transaction.Template issuanceToReceiver = new Transaction.Builder()
75 .addAction(new Transaction.Action.Issue()
76 .setAssetAlias("gold")
78 ).addAction(new Transaction.Action.ControlWithReceiver()
79 .setReceiver(Receiver.fromJson(bobIssuanceReceiverSerialized))
80 .setAssetAlias("gold")
84 Transaction.Template signedIssuanceToReceiver = new Transaction.SignerBuilder().sign(client,
85 issuanceToReceiver, "123456");
87 Transaction.submit(client, signedIssuanceToReceiver);
92 Alice pays 10 units of gold to Bob.
94 #### Within a Chain Core
97 Transaction.Template payment = new Transaction.Builder()
98 .addAction(new Transaction.Action.SpendFromAccount()
99 .setAccountAlias("alice")
100 .setAssetAlias("gold")
102 ).addAction(new Transaction.Action.ControlWithAccount()
103 .setAccountAlias("bob")
104 .setAssetAlias("gold")
108 Transaction.Template signedPayment = new Transaction.SignerBuilder().sign(client,
111 Transaction.submit(client, signedPayment);
114 #### Between two Chain Cores
116 First, Bob creates a receiver in his account, which he can serialize and send to Alice.
119 Receiver bobPaymentReceiver = new Account.ReceiverBuilder()
120 .setAccountAlias("bob")
121 .create(otherCoreClient);
122 String bobPaymentReceiverSerialized = bobPaymentReceiver.toJson();
125 Alice then builds, signs, and submits a transaction, sending gold to Bob’s receiver.
128 Transaction.Template paymentToReceiver = new Transaction.Builder()
129 .addAction(new Transaction.Action.SpendFromAccount()
130 .setAccountAlias("alice")
131 .setAssetAlias("gold")
133 ).addAction(new Transaction.Action.ControlWithReceiver()
134 .setReceiver(Receiver.fromJson(bobPaymentReceiverSerialized))
135 .setAssetAlias("gold")
139 Transaction.Template signedPaymentToReceiver = new Transaction.SignerBuilder().sign(client,
140 paymentToReceiver, "123456");
142 Transaction.submit(client, signedPaymentToReceiver);
145 ### Multi-asset payment
147 Alice pays 10 units of gold and 20 units of silver to Bob.
149 #### Within a Chain Core
152 Transaction.Template multiAssetPayment = new Transaction.Builder()
153 .addAction(new Transaction.Action.SpendFromAccount()
154 .setAccountAlias("alice")
155 .setAssetAlias("gold")
157 ).addAction(new Transaction.Action.SpendFromAccount()
158 .setAccountAlias("alice")
159 .setAssetAlias("silver")
161 ).addAction(new Transaction.Action.ControlWithAccount()
162 .setAccountAlias("bob")
163 .setAssetAlias("gold")
165 ).addAction(new Transaction.Action.ControlWithAccount()
166 .setAccountAlias("bob")
167 .setAssetAlias("silver")
171 Transaction.Template signedMultiAssetPayment = new Transaction.SignerBuilder().sign(client,
172 multiAssetPayment, "123456");
174 Transaction.submit(client, signedMultiAssetPayment);
177 #### Between two Chain Cores
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.
182 Receiver bobGoldReceiver = new Account.ReceiverBuilder()
183 .setAccountAlias("bob")
184 .create(otherCoreClient);
185 String bobGoldReceiverSerialized = bobGoldReceiver.toJson();
187 Receiver bobSilverReceiver = new Account.ReceiverBuilder()
188 .setAccountAlias("bob")
189 .create(otherCoreClient);
190 String bobSilverReceiverSerialized = bobSilverReceiver.toJson();
193 Alice then builds, signs, and submits a transaction, sending gold and silver to Bob’s receivers.
196 Transaction.Template multiAssetToReceiver = new Transaction.Builder()
197 .addAction(new Transaction.Action.SpendFromAccount()
198 .setAccountAlias("alice")
199 .setAssetAlias("gold")
201 ).addAction(new Transaction.Action.SpendFromAccount()
202 .setAccountAlias("alice")
203 .setAssetAlias("silver")
205 ).addAction(new Transaction.Action.ControlWithReceiver()
206 .setReceiver(Receiver.fromJson(bobGoldReceiverSerialized))
207 .setAssetAlias("gold")
209 ).addAction(new Transaction.Action.ControlWithReceiver()
210 .setReceiver(Receiver.fromJson(bobSilverReceiverSerialized))
211 .setAssetAlias("silver")
215 Transaction.Template signedMultiAssetToReceiver = new Transaction.SignerBuilder().sign(client,
216 multiAssetToReceiver, "123456");
218 Transaction.submit(client, signedMultiAssetToReceiver);
223 Alice retires 50 units of gold from her account.
226 Transaction.Template retirement = new Transaction.Builder()
227 .addAction(new Transaction.Action.SpendFromAccount()
228 .setAccountAlias("alice")
229 .setAssetAlias("gold")
231 ).addAction(new Transaction.Action.Retire()
232 .setAssetAlias("gold")
236 Transaction.Template signedRetirement = new Transaction.SignerBuilder().sign(client,
237 retirement, "123456");
239 Transaction.submit(client, signedRetirement);