OSDN Git Service

update readme
[bytom/bytom-java-sdk.git] / tx-signer / README.md
1 # tx_signer\r
2 \r
3 Java implementation of signing transaction offline to bytomd and serializing transaction to submit.\r
4 \r
5 ## Pre\r
6 \r
7 #### Get the source code\r
8 \r
9 ```\r
10 $ git clone https://github.com/Bytom/bytom.git $GOPATH/src/github.com/bytom\r
11 ```\r
12 \r
13 #### git checkout\r
14 \r
15 ```\r
16 $ git checkout dev\r
17 ```\r
18 \r
19 **Why need dev branch? Because you could call decode transaction api from dev branch and obtain tx_id and some inputs ids.**\r
20 \r
21 #### Build\r
22 \r
23 ```\r
24 $ cd $GOPATH/src/github.com/bytom\r
25 $ make bytomd    # build bytomd\r
26 $ make bytomcli  # build bytomcli\r
27 ```\r
28 \r
29 When successfully building the project, the `bytom` and `bytomcli` binary should be present in `cmd/bytomd` and `cmd/bytomcli` directory, respectively.\r
30 \r
31 #### Initialize\r
32 \r
33 First of all, initialize the node:\r
34 \r
35 ```\r
36 $ cd ./cmd/bytomd\r
37 $ ./bytomd init --chain_id solonet\r
38 ```\r
39 \r
40 #### launch\r
41 \r
42 ```\r
43 $ ./bytomd node --mining\r
44 ```\r
45 \r
46 ## Usage\r
47 \r
48 #### Build jar\r
49 \r
50 1. first get source code\r
51 \r
52    ```\r
53    git clone https://github.com/Bytom/bytom-java-sdk.git\r
54    ```\r
55 \r
56 2. get jar package\r
57 \r
58    ```\r
59    $ mvn assembly:assembly -Dmaven.test.skip=true\r
60    ```\r
61 \r
62    You can get a jar with dependencies, and you can use it in your project.\r
63 \r
64 #### Test cases\r
65 \r
66 Need 3 Parameters:\r
67 \r
68 - Private Keys Array\r
69 - UTXO list.\r
70 - Submit Transaction\r
71   - call submit-transaction api. [submit-transaction api](https://github.com/Bytom/bytom/wiki/API-Reference#submit-transaction)\r
72 \r
73 \r
74 \r
75 ```java\r
76 \r
77 //utxo json to input public Transaction.AnnotatedInput btmUtxoToInput() {\r
78     String utxoJson = "{\n" +\r
79             " \"id\": \"cf2f5c7340490d33d535a680dc8d95bb66fcccbf1045706484621cc067b982ae\",\n" +\r
80             " \"amount\": 70000000,\n" +\r
81             " \"address\": \"tm1qf4g97wae3fsz973huwrjqnd68v530nmd7n2pc43zfpw9tvd30qfsd7jl8p\",\n" +\r
82             " \"program\": \"00204d505f3bb98a6022fa37e387204dba3b2917cf6df4d41c5622485c55b1b17813\",\n" +\r
83             " \"change\": false,\n" +\r
84             " \"highest\": 140925,\n" +\r
85             " \"account_alias\": \"mutiaccout\",\n" +\r
86             " \"asset_id\": \"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\",\n" +\r
87             " \"asset_alias\": \"BTM\",\n" +\r
88             " \"account_id\": \"0PCB0S1GG0A02\",\n" +\r
89             " \"control_program_index\": 2,\n" +\r
90             " \"source_id\": \"9b29c72a653f986d5c5a7bf16c0fe63a9f639a0d15f3faeabeb4c14df70bbd91\",\n" +\r
91             " \"source_pos\": 0,\n" +\r
92             " \"valid_height\": 0,\n" +\r
93             " \"derive_rule\": 0\n" +\r
94             "}";\r
95   UTXO utxo = UTXO.fromJson(utxoJson);\r
96   Transaction.AnnotatedInput input = UTXO.utxoToAnnotatedInput(utxo);\r
97  return input;\r
98 }\r
99 \r
100 ```\r
101 \r
102 Single-key Example :\r
103 \r
104 ```java\r
105 String rootKey = "38d2c44314c401b3ea7c23c54e12c36a527aee46a7f26b82443a46bf40583e439dea25de09b0018b35a741d8cd9f6ec06bc11db49762617485f5309ab72a12d4";\r
106 String btmAssetID = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";\r
107 \r
108 \r
109   @Test\r
110   public void testSpend() throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {\r
111         Transaction.AnnotatedInput input = btmUtxoToInput();\r
112   Transaction Transaction = new Transaction.Builder()\r
113 //                .addInput(new Transaction.AnnotatedInput().setType(1).setAssetId(btmAssetID).setAmount(880000000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b").\r
114 //                        setChange(false).setControlProgramIndex(2).setSourceId("fc43933d1c601b2503b033e31d3bacfa5c40ccb2ff0be6e94d8332462e0928a3").setSourcePosition(0))\r
115   .addInput(input.setType(1))\r
116                 .addOutput(new Transaction.AnnotatedOutput().setAssetId(btmAssetID).setAmount(170000000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b"))\r
117                 .addOutput(new Transaction.AnnotatedOutput().setAssetId(btmAssetID).setAmount(10000000).setControlProgram("0020fa56ca7d47f8528e68e120d0e052885faeb9d090d238fa4266bdde21b137513c"))\r
118                 .build(200000);\r
119   Transaction transaction = MapTransaction.mapTx(Transaction);\r
120   SignTransaction signTransaction = new SignTransaction();\r
121   String rawTransaction = signTransaction.rawTransaction(rootKey, transaction);\r
122   System.out.println(rawTransaction);\r
123   }\r
124 \r
125   //issue asset\r
126   @Test\r
127   public void testIssue() throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {\r
128 \r
129         String issueAssetId = "a680606d49daae62ef9cb03263ca82a0b1e3184bb6311ea52a5189207f718789";\r
130   String program = "ae204cae24c2cec15491e70fc554026469496e373df9b9970b23acac8b782da0822d5151ad";\r
131   String assetDefine = "7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d";\r
132   Transaction Transaction = new Transaction.Builder()\r
133                 .addInput(new Transaction.AnnotatedInput().setType(0).setAssetId(issueAssetId).setControlProgram(program).setAmount(100000000).setAssetDefinition(assetDefine).setChange(false).setKeyIndex(13))\r
134                 .addInput(new Transaction.AnnotatedInput().setType(1).setAssetId(btmAssetID).setAmount(880000000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b").\r
135                         setChange(false).setControlProgramIndex(2).setSourceId("fc43933d1c601b2503b033e31d3bacfa5c40ccb2ff0be6e94d8332462e0928a3").setSourcePosition(0))\r
136                 .addOutput(new Transaction.AnnotatedOutput().setAssetId(issueAssetId).setAmount(100000000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b"))\r
137                 .addOutput(new Transaction.AnnotatedOutput().setAssetId(btmAssetID).setAmount(870000000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b"))\r
138                 .build(2000000);\r
139   MapTransaction.mapTx(Transaction);\r
140   SignTransaction sign = new SignTransaction();\r
141   String rawTransaction = sign.rawTransaction(rootKey, Transaction);\r
142   System.out.println(rawTransaction);\r
143   }\r
144 \r
145 \r
146     //retire asset\r
147   @Test\r
148   public void testRetire() throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {\r
149         String assetId1 = "8e962912423d8aea3409d1754782e7910da81b66c640aece14a6dac238f38e9b";\r
150   Transaction transaction = new Transaction.Builder()\r
151                 .addInput(new Transaction.AnnotatedInput().setType(1).setAssetId(btmAssetID).setAmount(890000000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b").\r
152                         setChange(false).setControlProgramIndex(2).setSourceId("6026b1acb11f3cbfb5280865ea857117a76d41ba7d60509dd358648424d8496a").setSourcePosition(0))\r
153                 .addInput(new Transaction.AnnotatedInput().setType(1).setAssetId(assetId1).setAmount(100000000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b").\r
154                         setChange(false).setControlProgramIndex(2).setSourceId("d53e7ccfa06d3b27933a44e5d6e3e288edfc7e38f5396b8552ef44cf58a20347").setSourcePosition(0))\r
155                 .addOutput(new Transaction.AnnotatedOutput().setAssetId(btmAssetID).setAmount(880000000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b"))\r
156                 //arbitrary add after retire control program("6a")\r
157   .addOutput(new Transaction.AnnotatedOutput().setAssetId(assetId1).setAmount(100000000).setControlProgram("6a"))\r
158                 .build(2000000);\r
159   MapTransaction.mapTx(transaction);\r
160   SignTransaction sign = new SignTransaction();\r
161   String rawTransaction = sign.rawTransaction(rootKey, transaction);\r
162   System.out.println(rawTransaction);\r
163   }\r
164 \r
165 ```\r
166 \r
167 Multi-keys Example:\r
168 \r
169 > Need an account has two or more keys.\r
170 \r
171 ```java\r
172   //single input and multi-sign\r
173   @Test\r
174   public void testMutiSpend(){\r
175         Transaction.AnnotatedInput input = btmUtxoToInput();\r
176   Transaction Transaction = new Transaction.Builder()\r
177 //                .addInput(new Transaction.AnnotatedInput().setType(1).setAssetId(btmAssetID).setAmount(880000000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b").\r
178 //                        setChange(false).setControlProgramIndex(2).setSourceId("fc43933d1c601b2503b033e31d3bacfa5c40ccb2ff0be6e94d8332462e0928a3").setSourcePosition(0))\r
179   .addInput(input.setType(1))\r
180                 .addOutput(new Transaction.AnnotatedOutput().setAssetId(btmAssetID).setAmount(50000000).setControlProgram("00204d505f3bb98a6022fa37e387204dba3b2917cf6df4d41c5622485c55b1b17813"))\r
181                 .addOutput(new Transaction.AnnotatedOutput().setAssetId(btmAssetID).setAmount(10000000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b"))\r
182                 .build(200000);\r
183   Transaction transaction = MapTransaction.mapTx(Transaction);\r
184   SignTransaction signTransaction = new SignTransaction();\r
185   String[] rootKeys = new String[3];\r
186   rootKeys[0] = "38d2c44314c401b3ea7c23c54e12c36a527aee46a7f26b82443a46bf40583e439dea25de09b0018b35a741d8cd9f6ec06bc11db49762617485f5309ab72a12d4";\r
187   rootKeys[1] = "50a23bf6200b8a98afc049a7d0296a619e2ee27fa0d6d4d271ca244b280b324347627e543cc079614642c7b88c78ce38092430b01d124663e8b84026aefefde1";\r
188   rootKeys[2] = "00e4bf1251fb5aa37aa2a11dec6c0db5cec3f17aa312dbddb30e06957a32ae503ebcdfd4ad5e29be21ee9ec336e939eb72439cf6d99c785268c8f3d71c1be877";\r
189   signTransaction.buildWitness(transaction, 0, rootKeys);\r
190   String raw = signTransaction.serializeTransaction(transaction);\r
191   System.out.println(raw);\r
192   }\r
193 ```\r
194 \r
195 Submit-transaction:\r
196 ```java\r
197 // submit rawTransaction\r
198 @Test\r
199 public void SubmitTransaction() throws BytomException {\r
200     Client client = TestUtil.generateClient();\r
201   String raw = "0701c09a0c01016b01699b29c72a653f986d5c5a7bf16c0fe63a9f639a0d15f3faeabeb4c14df70bbd91ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bbb02100012200204d505f3bb98a6022fa37e387204dba3b2917cf6df4d41c5622485c55b1b17813ac020440290bc8593d429d5c7d02f96232cf8035d3776eebf2a7e855c906cdbcf35281f98575624e326fbf1f9e8de70a7047b5af2f43c1d102fcf632d1544cff46aa970540ff237b6d2c5760bf633b640e120600d06e57ab3119d192b33894967a74293531507df473235233033f12c493bc005c8d1e2f858524a431edc7d522891dfada04406ebebe5d380e129fb212a777aca0f971cfe38a2e54cd9b822459609664303aa2e10caa10f5cb8eae4a53688f895a9cbe13e5be085dd289251c63a7c86718730f67ae204e4fcad6d69dfbad1fa83c37e6fd2031476940b44a9165fa79084e5a4d9acaed20415a96ffead835222ee96eda7c16e99a4c87e8e5e43e54d2d493855f707baf78209613d3c8a4aa730bb24e0324a920b2e3c8db7260ded4527f6d6d7d14d86b64385353ad020148ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80e1eb17012200204d505f3bb98a6022fa37e387204dba3b2917cf6df4d41c5622485c55b1b1781300013cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80ade2040116001414d362694eacfa110dc20dec77d610d22340f95b00";\r
202   SubmitTransaction.SubmitResponse submitResponse = SubmitTransaction.submitRawTransaction(client, raw);\r
203   System.out.println(submitResponse.tx_id);\r
204 }