OSDN Git Service

update readme
authorwyjDoraemon <wyjDoraemon@163.com>
Wed, 27 Feb 2019 08:17:05 +0000 (16:17 +0800)
committerwyjDoraemon <wyjDoraemon@163.com>
Wed, 27 Feb 2019 08:17:05 +0000 (16:17 +0800)
tx-signer/README.md

index d26e3cd..93686ae 100755 (executable)
@@ -1,6 +1,6 @@
 # tx_signer\r
 \r
-Java implementation of signing transaction offline to bytomd.\r
+Java implementation of signing transaction offline to bytomd and serializing transaction to submit.\r
 \r
 ## Pre\r
 \r
@@ -50,7 +50,7 @@ $ ./bytomd node --mining
 1. first get source code\r
 \r
    ```\r
-   git clone https://github.com/successli/tx_signer.git\r
+   git clone https://github.com/Bytom/bytom-java-sdk.git\r
    ```\r
 \r
 2. get jar package\r
@@ -66,68 +66,102 @@ $ ./bytomd node --mining
 Need 3 Parameters:\r
 \r
 - Private Keys Array\r
-- Template Object\r
-  - After call build transaction api return a Template json object. [build transaction api](https://github.com/Bytom/bytom/wiki/API-Reference#build-transaction)\r
-  - use bytom java sdk return a Template object.\r
-- Raw Transaction\r
-  - call decode raw-transaction api from dev branch. [decode raw-transaction api](https://github.com/Bytom/bytom/wiki/API-Reference#decode-raw-transaction)\r
+- UTXO list.\r
+- Submit Transaction\r
+  - call submit-transaction api. [submit-transaction api](https://github.com/Bytom/bytom/wiki/API-Reference#submit-transaction)\r
+\r
 \r
-Call method:\r
 \r
 ```java\r
-// return a Template object signed offline basically.\r
-Template result = signatures.generateSignatures(privates, template, rawTransaction);\r
-// use result's raw_transaction call sign transaction api to build another data but not need password or private key.\r
+\r
+//utxo json to input public Transaction.AnnotatedInput btmUtxoToInput() {\r
+    String utxoJson = "{\n" +\r
+            " \"id\": \"cf2f5c7340490d33d535a680dc8d95bb66fcccbf1045706484621cc067b982ae\",\n" +\r
+            " \"amount\": 70000000,\n" +\r
+            " \"address\": \"tm1qf4g97wae3fsz973huwrjqnd68v530nmd7n2pc43zfpw9tvd30qfsd7jl8p\",\n" +\r
+            " \"program\": \"00204d505f3bb98a6022fa37e387204dba3b2917cf6df4d41c5622485c55b1b17813\",\n" +\r
+            " \"change\": false,\n" +\r
+            " \"highest\": 140925,\n" +\r
+            " \"account_alias\": \"mutiaccout\",\n" +\r
+            " \"asset_id\": \"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\",\n" +\r
+            " \"asset_alias\": \"BTM\",\n" +\r
+            " \"account_id\": \"0PCB0S1GG0A02\",\n" +\r
+            " \"control_program_index\": 2,\n" +\r
+            " \"source_id\": \"9b29c72a653f986d5c5a7bf16c0fe63a9f639a0d15f3faeabeb4c14df70bbd91\",\n" +\r
+            " \"source_pos\": 0,\n" +\r
+            " \"valid_height\": 0,\n" +\r
+            " \"derive_rule\": 0\n" +\r
+            "}";\r
+  UTXO utxo = UTXO.fromJson(utxoJson);\r
+  Transaction.AnnotatedInput input = UTXO.utxoToAnnotatedInput(utxo);\r
+ return input;\r
+}\r
+\r
 ```\r
 \r
-Single-key Example:\r
+Single-key Example :\r
 \r
 ```java\r
-@Test\r
-// 使用 SDK 来构造 Template 对象参数, 单签\r
-public void testSignSingleKey() throws BytomException {\r
-    Client client = Client.generateClient();\r
-\r
-    String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";\r
-    String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";\r
-    // build transaction obtain a Template object\r
-    Template template = new Transaction.Builder()\r
-        .addAction(\r
-        new Transaction.Action.SpendFromAccount()\r
-        .setAccountId("0G0NLBNU00A02")\r
-        .setAssetId(asset_id)\r
-        .setAmount(40000000)\r
-    )\r
-        .addAction(\r
-        new Transaction.Action.SpendFromAccount()\r
-        .setAccountId("0G0NLBNU00A02")\r
-        .setAssetId(asset_id)\r
-        .setAmount(300000000)\r
-    )\r
-        .addAction(\r
-        new Transaction.Action.ControlWithAddress()\r
-        .setAddress(address)\r
-        .setAssetId(asset_id)\r
-        .setAmount(30000000)\r
-    ).build(client);\r
-    logger.info("template: " + template.toJson());\r
-    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object\r
-    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);\r
-    logger.info("decodeTx: " + decodedTx.toJson());\r
-    // need a private key array\r
-    String[] privateKeys = new String[]{"10fdbc41a4d3b8e5a0f50dd3905c1660e7476d4db3dbd9454fa4347500a633531c487e8174ffc0cfa76c3be6833111a9b8cd94446e37a76ee18bb21a7d6ea66b"};\r
-    logger.info("private key:" + privateKeys[0]);\r
-    // call offline sign method to obtain a basic offline signed template\r
-    Signatures signatures = new SignaturesImpl();\r
-    Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);\r
-    logger.info("basic signed raw: " + basicSigned.toJson());\r
-    // call sign transaction api to calculate whole raw_transaction id\r
-    // sign password is None or another random String\r
-    Template result = new Transaction.SignerBuilder().sign(client,\r
-                                                           basicSigned, "");\r
-    logger.info("result raw_transaction: " + result.toJson());\r
-    // success to submit transaction\r
-}\r
+String rootKey = "38d2c44314c401b3ea7c23c54e12c36a527aee46a7f26b82443a46bf40583e439dea25de09b0018b35a741d8cd9f6ec06bc11db49762617485f5309ab72a12d4";\r
+String btmAssetID = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";\r
+\r
+\r
+  @Test\r
+  public void testSpend() throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {\r
+        Transaction.AnnotatedInput input = btmUtxoToInput();\r
+  Transaction Transaction = new Transaction.Builder()\r
+//                .addInput(new Transaction.AnnotatedInput().setType(1).setAssetId(btmAssetID).setAmount(880000000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b").\r
+//                        setChange(false).setControlProgramIndex(2).setSourceId("fc43933d1c601b2503b033e31d3bacfa5c40ccb2ff0be6e94d8332462e0928a3").setSourcePosition(0))\r
+  .addInput(input.setType(1))\r
+                .addOutput(new Transaction.AnnotatedOutput().setAssetId(btmAssetID).setAmount(170000000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b"))\r
+                .addOutput(new Transaction.AnnotatedOutput().setAssetId(btmAssetID).setAmount(10000000).setControlProgram("0020fa56ca7d47f8528e68e120d0e052885faeb9d090d238fa4266bdde21b137513c"))\r
+                .build(200000);\r
+  Transaction transaction = MapTransaction.mapTx(Transaction);\r
+  SignTransaction signTransaction = new SignTransaction();\r
+  String rawTransaction = signTransaction.rawTransaction(rootKey, transaction);\r
+  System.out.println(rawTransaction);\r
+  }\r
+\r
+  //issue asset\r
+  @Test\r
+  public void testIssue() throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {\r
+\r
+        String issueAssetId = "a680606d49daae62ef9cb03263ca82a0b1e3184bb6311ea52a5189207f718789";\r
+  String program = "ae204cae24c2cec15491e70fc554026469496e373df9b9970b23acac8b782da0822d5151ad";\r
+  String assetDefine = "7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d";\r
+  Transaction Transaction = new Transaction.Builder()\r
+                .addInput(new Transaction.AnnotatedInput().setType(0).setAssetId(issueAssetId).setControlProgram(program).setAmount(100000000).setAssetDefinition(assetDefine).setChange(false).setKeyIndex(13))\r
+                .addInput(new Transaction.AnnotatedInput().setType(1).setAssetId(btmAssetID).setAmount(880000000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b").\r
+                        setChange(false).setControlProgramIndex(2).setSourceId("fc43933d1c601b2503b033e31d3bacfa5c40ccb2ff0be6e94d8332462e0928a3").setSourcePosition(0))\r
+                .addOutput(new Transaction.AnnotatedOutput().setAssetId(issueAssetId).setAmount(100000000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b"))\r
+                .addOutput(new Transaction.AnnotatedOutput().setAssetId(btmAssetID).setAmount(870000000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b"))\r
+                .build(2000000);\r
+  MapTransaction.mapTx(Transaction);\r
+  SignTransaction sign = new SignTransaction();\r
+  String rawTransaction = sign.rawTransaction(rootKey, Transaction);\r
+  System.out.println(rawTransaction);\r
+  }\r
+\r
+\r
+    //retire asset\r
+  @Test\r
+  public void testRetire() throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {\r
+        String assetId1 = "8e962912423d8aea3409d1754782e7910da81b66c640aece14a6dac238f38e9b";\r
+  Transaction transaction = new Transaction.Builder()\r
+                .addInput(new Transaction.AnnotatedInput().setType(1).setAssetId(btmAssetID).setAmount(890000000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b").\r
+                        setChange(false).setControlProgramIndex(2).setSourceId("6026b1acb11f3cbfb5280865ea857117a76d41ba7d60509dd358648424d8496a").setSourcePosition(0))\r
+                .addInput(new Transaction.AnnotatedInput().setType(1).setAssetId(assetId1).setAmount(100000000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b").\r
+                        setChange(false).setControlProgramIndex(2).setSourceId("d53e7ccfa06d3b27933a44e5d6e3e288edfc7e38f5396b8552ef44cf58a20347").setSourcePosition(0))\r
+                .addOutput(new Transaction.AnnotatedOutput().setAssetId(btmAssetID).setAmount(880000000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b"))\r
+                //arbitrary add after retire control program("6a")\r
+  .addOutput(new Transaction.AnnotatedOutput().setAssetId(assetId1).setAmount(100000000).setControlProgram("6a"))\r
+                .build(2000000);\r
+  MapTransaction.mapTx(transaction);\r
+  SignTransaction sign = new SignTransaction();\r
+  String rawTransaction = sign.rawTransaction(rootKey, transaction);\r
+  System.out.println(rawTransaction);\r
+  }\r
+\r
 ```\r
 \r
 Multi-keys Example:\r
@@ -135,120 +169,36 @@ Multi-keys Example:
 > Need an account has two or more keys.\r
 \r
 ```java\r
-@Test\r
-// 使用 SDK 来构造 Template 对象参数, 多签\r
-public void testSignMultiKeys() throws BytomException {\r
-    Client client = Client.generateClient();\r
-\r
-    String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";\r
-    String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";\r
-    // build transaction obtain a Template object\r
-    // account 0G1RPP6OG0A06 has two keys\r
-    Template template = new Transaction.Builder()\r
-        .setTtl(10)\r
-        .addAction(\r
-        new Transaction.Action.SpendFromAccount()\r
-        .setAccountId("0G1RPP6OG0A06")\r
-        .setAssetId(asset_id)\r
-        .setAmount(40000000)\r
-    )\r
-        .addAction(\r
-        new Transaction.Action.SpendFromAccount()\r
-        .setAccountId("0G1RPP6OG0A06")\r
-        .setAssetId(asset_id)\r
-        .setAmount(300000000)\r
-    )\r
-        .addAction(\r
-        new Transaction.Action.ControlWithAddress()\r
-        .setAddress(address)\r
-        .setAssetId(asset_id)\r
-        .setAmount(30000000)\r
-    ).build(client);\r
-    logger.info("template: " + template.toJson());\r
-    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object\r
-    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);\r
-    logger.info("decodeTx: " + decodedTx.toJson());\r
-    // need a private key array\r
-    String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",\r
-                                        "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b"};\r
-    logger.info("private key 1:" + privateKeys[0]);\r
-    logger.info("private key 2:" + privateKeys[1]);\r
-    // call offline sign method to obtain a basic offline signed template\r
-    Signatures signatures = new SignaturesImpl();\r
-    Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);\r
-    logger.info("basic signed raw: " + basicSigned.toJson());\r
-    // call sign transaction api to calculate whole raw_transaction id\r
-    // sign password is None or another random String\r
-    Template result = new Transaction.SignerBuilder().sign(client,\r
-                                                           basicSigned, "");\r
-    logger.info("result raw_transaction: " + result.toJson());\r
-    // success to submit transaction\r
-}\r
+  //single input and multi-sign\r
+  @Test\r
+  public void testMutiSpend(){\r
+        Transaction.AnnotatedInput input = btmUtxoToInput();\r
+  Transaction Transaction = new Transaction.Builder()\r
+//                .addInput(new Transaction.AnnotatedInput().setType(1).setAssetId(btmAssetID).setAmount(880000000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b").\r
+//                        setChange(false).setControlProgramIndex(2).setSourceId("fc43933d1c601b2503b033e31d3bacfa5c40ccb2ff0be6e94d8332462e0928a3").setSourcePosition(0))\r
+  .addInput(input.setType(1))\r
+                .addOutput(new Transaction.AnnotatedOutput().setAssetId(btmAssetID).setAmount(50000000).setControlProgram("00204d505f3bb98a6022fa37e387204dba3b2917cf6df4d41c5622485c55b1b17813"))\r
+                .addOutput(new Transaction.AnnotatedOutput().setAssetId(btmAssetID).setAmount(10000000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b"))\r
+                .build(200000);\r
+  Transaction transaction = MapTransaction.mapTx(Transaction);\r
+  SignTransaction signTransaction = new SignTransaction();\r
+  String[] rootKeys = new String[3];\r
+  rootKeys[0] = "38d2c44314c401b3ea7c23c54e12c36a527aee46a7f26b82443a46bf40583e439dea25de09b0018b35a741d8cd9f6ec06bc11db49762617485f5309ab72a12d4";\r
+  rootKeys[1] = "50a23bf6200b8a98afc049a7d0296a619e2ee27fa0d6d4d271ca244b280b324347627e543cc079614642c7b88c78ce38092430b01d124663e8b84026aefefde1";\r
+  rootKeys[2] = "00e4bf1251fb5aa37aa2a11dec6c0db5cec3f17aa312dbddb30e06957a32ae503ebcdfd4ad5e29be21ee9ec336e939eb72439cf6d99c785268c8f3d71c1be877";\r
+  signTransaction.buildWitness(transaction, 0, rootKeys);\r
+  String raw = signTransaction.serializeTransaction(transaction);\r
+  System.out.println(raw);\r
+  }\r
 ```\r
-Multi-keys and Multi-inputs Example:\r
 \r
+Submit-transaction:\r
 ```java\r
+// submit rawTransaction\r
 @Test\r
-// 使用 SDK 来构造 Template 对象参数, 多签, 多输入\r
-public void testSignMultiKeysMultiInputs() throws BytomException {\r
-    Client client = Client.generateClient();\r
-\r
-    String asset_id = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";\r
-    String address = "sm1qvyus3s5d7jv782syuqe3qrh65fx23lgpzf33em";\r
-    // build transaction obtain a Template object\r
-    Template template = new Transaction.Builder()\r
-        .setTtl(10)\r
-        // 1 input\r
-        .addAction(\r
-        new Transaction.Action.SpendFromAccount()\r
-        .setAccountId("0G1RPP6OG0A06") // Multi-keys account\r
-        .setAssetId(asset_id)\r
-        .setAmount(40000000)\r
-    )\r
-        .addAction(\r
-        new Transaction.Action.SpendFromAccount()\r
-        .setAccountId("0G1RPP6OG0A06")\r
-        .setAssetId(asset_id)\r
-        .setAmount(300000000)\r
-    )  // 2 input\r
-        .addAction(\r
-        new Transaction.Action.SpendFromAccount()\r
-        .setAccountId("0G1Q6V1P00A02") // Multi-keys account\r
-        .setAssetId(asset_id)\r
-        .setAmount(40000000)\r
-    )\r
-        .addAction(\r
-        new Transaction.Action.SpendFromAccount()\r
-        .setAccountId("0G1Q6V1P00A02")\r
-        .setAssetId(asset_id)\r
-        .setAmount(300000000)\r
-    )\r
-        .addAction(\r
-        new Transaction.Action.ControlWithAddress()\r
-        .setAddress(address)\r
-        .setAssetId(asset_id)\r
-        .setAmount(60000000)\r
-    ).build(client);\r
-    logger.info("template: " + template.toJson());\r
-    // use Template object's raw_transaction id to decode raw_transaction obtain a RawTransaction object\r
-    RawTransaction decodedTx = RawTransaction.decode(client, template.rawTransaction);\r
-    logger.info("decodeTx: " + decodedTx.toJson());\r
-    // need a private key array\r
-    String[] privateKeys = new String[]{"08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67",\r
-                                        "40c821f736f60805ad59b1fea158762fa6355e258601dfb49dda6f672092ae5adf072d5cab2ceaaa0d68dd3fe7fa04869d95afed8c20069f446a338576901e1b",\r
-                                        "08bdbd6c22856c5747c930f64d0e5d58ded17c4473910c6c0c3f94e485833a436247976253c8e29e961041ad8dfad9309744255364323163837cbef2483b4f67"};\r
-    logger.info("private key 1:" + privateKeys[0]);\r
-    logger.info("private key 2:" + privateKeys[1]);\r
-    // call offline sign method to obtain a basic offline signed template\r
-    Signatures signatures = new SignaturesImpl();\r
-    Template basicSigned = signatures.generateSignatures(privateKeys, template, decodedTx);\r
-    logger.info("basic signed raw: " + basicSigned.toJson());\r
-    // call sign transaction api to calculate whole raw_transaction id\r
-    // sign password is None or another random String\r
-    Template result = new Transaction.SignerBuilder().sign(client,\r
-                                                           basicSigned, "");\r
-    logger.info("result raw_transaction: " + result.toJson());\r
-    // success to submit transaction\r
-}\r
-```\r
-\r
+public void SubmitTransaction() throws BytomException {\r
+    Client client = TestUtil.generateClient();\r
+  String raw = "0701c09a0c01016b01699b29c72a653f986d5c5a7bf16c0fe63a9f639a0d15f3faeabeb4c14df70bbd91ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bbb02100012200204d505f3bb98a6022fa37e387204dba3b2917cf6df4d41c5622485c55b1b17813ac020440290bc8593d429d5c7d02f96232cf8035d3776eebf2a7e855c906cdbcf35281f98575624e326fbf1f9e8de70a7047b5af2f43c1d102fcf632d1544cff46aa970540ff237b6d2c5760bf633b640e120600d06e57ab3119d192b33894967a74293531507df473235233033f12c493bc005c8d1e2f858524a431edc7d522891dfada04406ebebe5d380e129fb212a777aca0f971cfe38a2e54cd9b822459609664303aa2e10caa10f5cb8eae4a53688f895a9cbe13e5be085dd289251c63a7c86718730f67ae204e4fcad6d69dfbad1fa83c37e6fd2031476940b44a9165fa79084e5a4d9acaed20415a96ffead835222ee96eda7c16e99a4c87e8e5e43e54d2d493855f707baf78209613d3c8a4aa730bb24e0324a920b2e3c8db7260ded4527f6d6d7d14d86b64385353ad020148ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80e1eb17012200204d505f3bb98a6022fa37e387204dba3b2917cf6df4d41c5622485c55b1b1781300013cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80ade2040116001414d362694eacfa110dc20dec77d610d22340f95b00";\r
+  SubmitTransaction.SubmitResponse submitResponse = SubmitTransaction.submitRawTransaction(client, raw);\r
+  System.out.println(submitResponse.tx_id);\r
+}
\ No newline at end of file