OSDN Git Service

modify retire and muti-sign
authorwyjDoraemon <wyjDoraemon@163.com>
Thu, 28 Feb 2019 07:21:44 +0000 (15:21 +0800)
committerwyjDoraemon <wyjDoraemon@163.com>
Thu, 28 Feb 2019 07:21:44 +0000 (15:21 +0800)
tx-signer/README.md
tx-signer/pom.xml
tx-signer/src/main/java/io/bytom/api/MapTransaction.java
tx-signer/src/main/java/io/bytom/api/SignTransaction.java
tx-signer/src/main/java/io/bytom/common/Utils.java
tx-signer/src/main/java/io/bytom/types/Asset.java
tx-signer/src/test/java/io/bytom/AppTest.java
tx-signer/src/test/java/io/bytom/api/SignerTest.java

index 93686ae..10b8c24 100755 (executable)
-# tx_signer\r
-\r
-Java implementation of signing transaction offline to bytomd and serializing transaction to submit.\r
-\r
-## Pre\r
-\r
-#### Get the source code\r
-\r
-```\r
-$ git clone https://github.com/Bytom/bytom.git $GOPATH/src/github.com/bytom\r
-```\r
-\r
-#### git checkout\r
-\r
-```\r
-$ git checkout dev\r
-```\r
-\r
-**Why need dev branch? Because you could call decode transaction api from dev branch and obtain tx_id and some inputs ids.**\r
-\r
-#### Build\r
-\r
-```\r
-$ cd $GOPATH/src/github.com/bytom\r
-$ make bytomd    # build bytomd\r
-$ make bytomcli  # build bytomcli\r
-```\r
-\r
-When successfully building the project, the `bytom` and `bytomcli` binary should be present in `cmd/bytomd` and `cmd/bytomcli` directory, respectively.\r
-\r
-#### Initialize\r
-\r
-First of all, initialize the node:\r
-\r
-```\r
-$ cd ./cmd/bytomd\r
-$ ./bytomd init --chain_id solonet\r
-```\r
-\r
-#### launch\r
-\r
-```\r
-$ ./bytomd node --mining\r
-```\r
-\r
-## Usage\r
-\r
-#### Build jar\r
-\r
-1. first get source code\r
-\r
-   ```\r
-   git clone https://github.com/Bytom/bytom-java-sdk.git\r
-   ```\r
-\r
-2. get jar package\r
-\r
-   ```\r
-   $ mvn assembly:assembly -Dmaven.test.skip=true\r
-   ```\r
-\r
-   You can get a jar with dependencies, and you can use it in your project.\r
-\r
-#### Test cases\r
-\r
-Need 3 Parameters:\r
-\r
-- Private Keys Array\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
+# tx_signer  \r
+  \r
+Java implementation of signing transaction offline to bytomd and serializing transaction to submit.  \r
+  \r
+## Pre  \r
+  \r
+#### Get the source code  \r
+  \r
+```  \r
+$ git clone https://github.com/Bytom/bytom.git $GOPATH/src/github.com/bytom  \r
+```  \r
+  \r
+#### git checkout  \r
+  \r
+```  \r
+$ git checkout dev  \r
+```  \r
+  \r
+**Why need dev branch? Because you could call decode transaction api from dev branch and obtain tx_id and some inputs ids.**  \r
+  \r
+#### Build  \r
+  \r
+```  \r
+$ cd $GOPATH/src/github.com/bytom  \r
+$ make bytomd    # build bytomd  \r
+$ make bytomcli  # build bytomcli  \r
+```  \r
+  \r
+When successfully building the project, the `bytom` and `bytomcli` binary should be present in `cmd/bytomd` and `cmd/bytomcli` directory, respectively.  \r
+  \r
+#### Initialize  \r
+  \r
+First of all, initialize the node:  \r
+  \r
+```  \r
+$ cd ./cmd/bytomd  \r
+$ ./bytomd init --chain_id solonet  \r
+```  \r
+  \r
+#### launch  \r
+  \r
+```  \r
+$ ./bytomd node --mining  \r
+```  \r
+  \r
+## Usage  \r
+  \r
+#### Build jar  \r
+  \r
+1. first get source code  \r
+  \r
+   ```  \r
+   git clone https://github.com/Bytom/bytom-java-sdk.git  \r
+   ```  \r
+  \r
+2. get jar package  \r
+  \r
+   ```  \r
+   $ mvn assembly:assembly -Dmaven.test.skip=true  \r
+   ```  \r
+  \r
+   You can get a jar with dependencies, and you can use it in your project.  \r
+  \r
+#### Test cases  \r
+  \r
+Need 3 Parameters:  \r
+  \r
+- Private Keys Array  \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
 \r
 ```java\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
+//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
-\r
-```java\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
+Single-key Example :  \r
+  \r
+```java  \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 arbitrary = "77656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c";  \r
+  String retireControlProgram = "6a"+Integer.toString(Hex.decode(arbitrary).length,16)+arbitrary;  \r
+  String assetId1 = "207265909236260b30942a6b00e30ceb769e0e58156b6482bac64117619c9dcf"; \r
+   \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
+                .addOutput(new Transaction.AnnotatedOutput().setAssetId(assetId1).setAmount(100000000).setControlProgram(retireControlProgram ))  \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
-\r
-> Need an account has two or more keys.\r
-\r
-```java\r
+```  \r
+  \r
+Multi-keys Example:  \r
+  \r
+> Need an account has two or more keys.  \r
+  \r
+```java  \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
+  @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
 \r
-Submit-transaction:\r
+Submit-transaction:  \r
 ```java\r
-// submit rawTransaction\r
-@Test\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
+// submit rawTransaction  \r
+@Test  \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
+}\r
index 2050e9f..982d587 100644 (file)
                 </exclusion>
             </exclusions>
         </dependency>
+
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-ext-jdk15on</artifactId>
+            <version>1.55</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk15on</artifactId>
+            <version>1.59</version>
+        </dependency>
     </dependencies>
 </project>
\ No newline at end of file
index 296a0c3..349d33c 100755 (executable)
@@ -78,7 +78,7 @@ public class MapTransaction {
                 AssetAmount amount = new AssetAmount(new AssetID(output.assetId), output.amount);\r
                 ValueSource src = new ValueSource(muxID, amount, i);\r
                 Hash resultID;\r
-                if (output.controlProgram.startsWith("6a")) {\r
+                if (output.controlProgram.startsWith("6a")&&output.controlProgram.length()>0) {\r
                     Retirement retirement = new Retirement(src, i);\r
                     resultID = addEntry(entryMap, retirement);\r
                 } else {\r
index cd101f5..2cde88d 100755 (executable)
@@ -19,6 +19,10 @@ import java.security.SignatureException;
  * Created by liqiang on 2018/10/24.\r
  */\r
 public class SignTransaction {\r
+\r
+    private final String OP_TXSIGHASH = "ae";\r
+    private final String OP_CHECKMULTISIG  = "ad";\r
+\r
     public String serializeTransaction(Transaction tx) {\r
         String txSign = null;\r
         //开始序列化\r
@@ -170,7 +174,7 @@ public class SignTransaction {
     }\r
 \r
     //签名组装witness\r
-    public Transaction buildWitness(Transaction transaction, int index, String priKey) {\r
+    public Transaction buildWitness(Transaction transaction, int index, byte[] privateKeyBytes) {\r
 \r
         Transaction.AnnotatedInput input = transaction.inputs.get(index);\r
         if (null == input.witnessComponent)\r
@@ -179,15 +183,14 @@ public class SignTransaction {
                 try {\r
                     input.witnessComponent = new Transaction.InputWitnessComponent();\r
                     byte[] message = hashFn(Hex.decode(input.inputID), Hex.decode(transaction.txID));\r
-                    byte[] key = Hex.decode(priKey);\r
-                    byte[] expandedPrivateKey = ExpandedPrivateKey.ExpandedPrivateKey(key);\r
+                    byte[] expandedPrivateKey = ExpandedPrivateKey.ExpandedPrivateKey(privateKeyBytes);\r
                     byte[] sig = Signer.Ed25519InnerSign(expandedPrivateKey, message);\r
 \r
                     switch (input.type) {\r
                         case 1: {\r
                             input.witnessComponent.signatures = new String[2];\r
                             input.witnessComponent.signatures[0] = Hex.toHexString(sig);\r
-                            byte[] deriveXpub = DeriveXpub.deriveXpub(Hex.decode(priKey));\r
+                            byte[] deriveXpub = DeriveXpub.deriveXpub(privateKeyBytes);\r
                             String pubKey = Hex.toHexString(deriveXpub).substring(0, 64);\r
                             input.witnessComponent.signatures[1] = pubKey;\r
                             break;\r
@@ -208,7 +211,7 @@ public class SignTransaction {
         return transaction;\r
     }\r
 \r
-    //多签spend\r
+    //多签单输入\r
     public void buildWitness(Transaction transaction, int index, String[] privateKeys) {\r
         Transaction.AnnotatedInput input = transaction.inputs.get(index);\r
         if (null == input.witnessComponent)\r
@@ -216,21 +219,23 @@ public class SignTransaction {
         try {\r
 \r
             //TODO 多签issue\r
-            StringBuilder sb = new StringBuilder("ae");\r
+            StringBuilder sb = new StringBuilder(OP_TXSIGHASH);\r
             input.witnessComponent.signatures = new String[privateKeys.length + 1];\r
             for (int i = 0; i < privateKeys.length; i++) {\r
-                byte[] key = DerivePrivateKey.derivePrivateKey(privateKeys[i], 1, false, input.getControlProgramIndex());\r
+                System.out.println(input.isChange());\r
+                byte[] key = DerivePrivateKey.derivePrivateKey(privateKeys[i], 1, input.isChange(), input.getControlProgramIndex());\r
                 byte[] message = hashFn(Hex.decode(input.inputID), Hex.decode(transaction.txID));\r
                 byte[] expandedPrivateKey = ExpandedPrivateKey.ExpandedPrivateKey(key);\r
                 byte[] sig = Signer.Ed25519InnerSign(expandedPrivateKey, message);\r
                 input.witnessComponent.signatures[i] = Hex.toHexString(sig);\r
-                byte[] deriveXpub = DeriveXpub.deriveXpub(key);\r
+                byte[] deriveXpub = DeriveXpub.deriveXpub(expandedPrivateKey);\r
                 String publicKey = Hex.toHexString(deriveXpub).substring(0, 64);\r
-                sb.append("20").append(publicKey);\r
+                sb.append(Integer.toString(Hex.decode(publicKey).length,16)).append(publicKey);\r
             }\r
-            //签名数跟公钥数相同\r
             //TODO 签名数跟公钥数量不同\r
-            sb.append("5").append(privateKeys.length).append("5").append(privateKeys.length).append("ad");\r
+            sb.append(Utils.pushDataInt(privateKeys.length)); //should be nrequired\r
+            sb.append(Utils.pushDataInt(privateKeys.length));\r
+            sb.append(OP_CHECKMULTISIG);\r
             input.witnessComponent.signatures[privateKeys.length] = sb.toString();\r
 \r
         } catch (Exception e) {\r
@@ -239,7 +244,7 @@ public class SignTransaction {
 \r
     }\r
 \r
-    private byte[] hashFn(byte[] hashedInputHex, byte[] txID) {\r
+    public static byte[] hashFn(byte[] hashedInputHex, byte[] txID) {\r
 \r
         SHA3.Digest256 digest256 = new SHA3.Digest256();\r
         // data = hashedInputHex + txID\r
@@ -282,7 +287,7 @@ public class SignTransaction {
             } else {\r
                 privateChild = DerivePrivateKey.derivePrivateKey(rootPrivateKey, tx.inputs.get(i).getKeyIndex());\r
             }\r
-            buildWitness(tx, i, Hex.toHexString(privateChild));\r
+            buildWitness(tx, i, privateChild);\r
         }\r
         return serializeTransaction(tx);\r
     }\r
index 5cb937b..b4bb6f6 100755 (executable)
@@ -89,4 +89,16 @@ public class Utils {
         expandedKeys.setPubKey(Hex.toHexString(hashPubKey));\r
         return expandedKeys;\r
     }\r
+\r
+    public static String pushDataInt(int n) {\r
+        if (n==0){\r
+            return "00";\r
+        }else if (n>=1&&n<=15){\r
+            return "5"+Integer.toString(n,16);\r
+        }else if(n==16){\r
+            return "60";\r
+        }\r
+        return null;\r
+\r
+    }\r
 }\r
index 1ff2706..c1885e0 100755 (executable)
@@ -71,6 +71,7 @@ public class Asset {
     private String computeIssueProgram(String rootKey, int keyIndex) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {\r
         byte[] derivePrivateKey = DerivePrivateKey.derivePrivateKey(rootKey, keyIndex);\r
         byte[] deriveXpub = DeriveXpub.deriveXpub(derivePrivateKey);\r
+\r
         String issueProgram = "ae20" + Hex.toHexString(deriveXpub).substring(0, 64) + "5151ad";\r
         return issueProgram;\r
     }\r
index 6bf1fab..8dcd960 100755 (executable)
@@ -3,6 +3,7 @@ package io.bytom;
 import io.bytom.api.*;\r
 import io.bytom.exception.BytomException;\r
 import io.bytom.http.Client;\r
+import org.bouncycastle.util.encoders.Hex;\r
 import org.junit.Test;\r
 \r
 import java.security.InvalidKeyException;\r
@@ -21,7 +22,7 @@ public class AppTest {
 //                .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(49100000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b"))\r
                 .addOutput(new Transaction.AnnotatedOutput().setAssetId(btmAssetID).setAmount(10000000).setControlProgram("0020fa56ca7d47f8528e68e120d0e052885faeb9d090d238fa4266bdde21b137513c"))\r
                 .build(200000);\r
         io.bytom.api.Transaction transaction = MapTransaction.mapTx(Transaction);\r
@@ -37,12 +38,14 @@ public class AppTest {
         String issueAssetId = "a680606d49daae62ef9cb03263ca82a0b1e3184bb6311ea52a5189207f718789";\r
         String program = "ae204cae24c2cec15491e70fc554026469496e373df9b9970b23acac8b782da0822d5151ad";\r
         String assetDefine = "7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d";\r
+        Transaction.AnnotatedInput input = btmUtxoToInput();\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
+//                .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(issueAssetId).setAmount(100000000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b"))\r
-                .addOutput(new Transaction.AnnotatedOutput().setAssetId(btmAssetID).setAmount(870000000).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
@@ -54,15 +57,17 @@ public class AppTest {
     //retire asset\r
     @Test\r
     public void testRetire() throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {\r
-        String assetId1 = "8e962912423d8aea3409d1754782e7910da81b66c640aece14a6dac238f38e9b";\r
+        String arbitrary = "77656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c";\r
+        String retireControlProgram = "6a"+Integer.toString(Hex.decode(arbitrary).length,16)+arbitrary;\r
+        String assetId1 = "207265909236260b30942a6b00e30ceb769e0e58156b6482bac64117619c9dcf";\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 加在retire control program 后面\r
-                .addOutput(new Transaction.AnnotatedOutput().setAssetId(assetId1).setAmount(100000000).setControlProgram("6a"))\r
+                .addInput(new Transaction.AnnotatedInput().setType(1).setAssetId(btmAssetID).setAmount(289100000).setControlProgram("0014f1dc52048f439ac7fd74f8106a21da78f00de48f").\r
+                        setChange(true).setControlProgramIndex(41).setSourceId("0b2cff11d1d056d95237a5f2d06059e5395e86f60e69c1e8201ea624911c0c65").setSourcePosition(0))\r
+                .addInput(new Transaction.AnnotatedInput().setType(1).setAssetId(assetId1).setAmount(70000000000l).setControlProgram("0014bb8a039726df1b649738e9973db14a4b4fd4becf").\r
+                        setChange(true).setControlProgramIndex(26).setSourceId("be0ac837e832c34a02968e54dab4f95cbeceb9fb01cd378310f6ea32219ee29b").setSourcePosition(1))\r
+                .addOutput(new Transaction.AnnotatedOutput().setAssetId(btmAssetID).setAmount(279100000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b"))\r
+                .addOutput(new Transaction.AnnotatedOutput().setAssetId(assetId1).setAmount(10000000000l).setControlProgram(retireControlProgram))\r
+                .addOutput(new Transaction.AnnotatedOutput().setAssetId(assetId1).setAmount(60000000000l).setControlProgram("0014bb8a039726df1b649738e9973db14a4b4fd4becf"))\r
                 .build(2000000);\r
         MapTransaction.mapTx(transaction);\r
         SignTransaction sign = new SignTransaction();\r
@@ -73,20 +78,21 @@ public class AppTest {
 \r
     //utxo\r
     private Transaction.AnnotatedInput btmUtxoToInput() {\r
-        String utxoJson = "{\n" +\r
-                "  \"id\": \"cf2f5c7340490d33d535a680dc8d95bb66fcccbf1045706484621cc067b982ae\",\n" +\r
-                "  \"amount\": 70000000,\n" +\r
-                "  \"address\": \"tm1qf4g97wae3fsz973huwrjqnd68v530nmd7n2pc43zfpw9tvd30qfsd7jl8p\",\n" +\r
-                "  \"program\": \"00204d505f3bb98a6022fa37e387204dba3b2917cf6df4d41c5622485c55b1b17813\",\n" +\r
+        String utxoJson = "\n" +\r
+                "{\n" +\r
+                "  \"id\": \"687e3c3ca1ee8139e57f43697db6aaeac95b10c75b828ef2fad30abe7d047e6a\",\n" +\r
+                "  \"amount\": 10000000,\n" +\r
+                "  \"address\": \"tm1qznfky62w4napzrwzphk804ss6g35p72mcw53q7\",\n" +\r
+                "  \"program\": \"001414d362694eacfa110dc20dec77d610d22340f95b\",\n" +\r
                 "  \"change\": false,\n" +\r
-                "  \"highest\": 140925,\n" +\r
-                "  \"account_alias\": \"mutiaccout\",\n" +\r
+                "  \"highest\": 141905,\n" +\r
+                "  \"account_alias\": \"wyjbtm\",\n" +\r
                 "  \"asset_id\": \"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\",\n" +\r
                 "  \"asset_alias\": \"BTM\",\n" +\r
-                "  \"account_id\": \"0PCB0S1GG0A02\",\n" +\r
+                "  \"account_id\": \"0NNSS39M00A02\",\n" +\r
                 "  \"control_program_index\": 2,\n" +\r
-                "  \"source_id\": \"9b29c72a653f986d5c5a7bf16c0fe63a9f639a0d15f3faeabeb4c14df70bbd91\",\n" +\r
-                "  \"source_pos\": 0,\n" +\r
+                "  \"source_id\": \"535b88d3f6b449fdba678b00b84d4b516df1da73104d689d41f964389f5a9217\",\n" +\r
+                "  \"source_pos\": 1,\n" +\r
                 "  \"valid_height\": 0,\n" +\r
                 "  \"derive_rule\": 0\n" +\r
                 "}";\r
@@ -123,7 +129,7 @@ public class AppTest {
     @Test\r
     public void SubmitTransaction() throws BytomException {\r
         Client client = TestUtil.generateClient();\r
-        String raw = "0701c09a0c01016b01699b29c72a653f986d5c5a7bf16c0fe63a9f639a0d15f3faeabeb4c14df70bbd91ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bbb02100012200204d505f3bb98a6022fa37e387204dba3b2917cf6df4d41c5622485c55b1b17813ac020440290bc8593d429d5c7d02f96232cf8035d3776eebf2a7e855c906cdbcf35281f98575624e326fbf1f9e8de70a7047b5af2f43c1d102fcf632d1544cff46aa970540ff237b6d2c5760bf633b640e120600d06e57ab3119d192b33894967a74293531507df473235233033f12c493bc005c8d1e2f858524a431edc7d522891dfada04406ebebe5d380e129fb212a777aca0f971cfe38a2e54cd9b822459609664303aa2e10caa10f5cb8eae4a53688f895a9cbe13e5be085dd289251c63a7c86718730f67ae204e4fcad6d69dfbad1fa83c37e6fd2031476940b44a9165fa79084e5a4d9acaed20415a96ffead835222ee96eda7c16e99a4c87e8e5e43e54d2d493855f707baf78209613d3c8a4aa730bb24e0324a920b2e3c8db7260ded4527f6d6d7d14d86b64385353ad020148ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80e1eb17012200204d505f3bb98a6022fa37e387204dba3b2917cf6df4d41c5622485c55b1b1781300013cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80ade2040116001414d362694eacfa110dc20dec77d610d22340f95b00";\r
+        String raw = "070180897a020160015e0b2cff11d1d056d95237a5f2d06059e5395e86f60e69c1e8201ea624911c0c65ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0a1ed89010001160014f1dc52048f439ac7fd74f8106a21da78f00de48f6302401660121218ab96d9f22cce712541ca34c53f4da40450669854341ca9624ad1cf10d1bfc96449fad5406224afd253ccfbdeab683f7ec7f9ee8f45e47a0c58500f2031ecc1bdd5fb9b40016358340b87646ea39faf55c0c105205cfdfdc6184725f40161015fbe0ac837e832c34a02968e54dab4f95cbeceb9fb01cd378310f6ea32219ee29b207265909236260b30942a6b00e30ceb769e0e58156b6482bac64117619c9dcf80f8cce284020101160014bb8a039726df1b649738e9973db14a4b4fd4becf630240d7b7f1c2ca1048fd6798234f2a1e895762f83e802507a008eff52605611b67390a74eaf228b76f5589ff109b2c20eaa65fad6de2e5ab8a25b54267b607df970b20a71547e1064b5edaad92cdce6b0ace832836ba28fdeaf0b83010bed247fe927c03013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f48a85010116001414d362694eacfa110dc20dec77d610d22340f95b00014b207265909236260b30942a6b00e30ceb769e0e58156b6482bac64117619c9dcf80c8afa02501246a2277656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c00013e207265909236260b30942a6b00e30ceb769e0e58156b6482bac64117619c9dcf80b09dc2df0101160014bb8a039726df1b649738e9973db14a4b4fd4becf00";\r
         SubmitTransaction.SubmitResponse submitResponse = SubmitTransaction.submitRawTransaction(client, raw);\r
         System.out.println(submitResponse.tx_id);\r
     }\r
@@ -137,7 +143,7 @@ public class AppTest {
 //                .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(80000000).setControlProgram("00204d505f3bb98a6022fa37e387204dba3b2917cf6df4d41c5622485c55b1b17813"))\r
                 .addOutput(new Transaction.AnnotatedOutput().setAssetId(btmAssetID).setAmount(10000000).setControlProgram("001414d362694eacfa110dc20dec77d610d22340f95b"))\r
                 .build(200000);\r
         Transaction transaction = MapTransaction.mapTx(Transaction);\r
index 52ef740..d5dee51 100755 (executable)
@@ -1,5 +1,8 @@
 package io.bytom.api;\r
 \r
+import io.bytom.common.DerivePrivateKey;\r
+import io.bytom.common.DeriveXpub;\r
+import io.bytom.common.ExpandedPrivateKey;\r
 import org.bouncycastle.util.encoders.Hex;\r
 import org.junit.Test;\r
 \r
@@ -17,8 +20,6 @@ public class SignerTest {
         String hashedMessage = "99ab9ebdba106466371467b036d56a0e54ad2a6035e365a6103ba97ab553fd52";\r
         byte[] sig = Signer.Ed25519InnerSign(Hex.decode(expandedXprv), Hex.decode(hashedMessage));\r
         System.out.println("sig:" + Hex.toHexString(sig));\r
-        //expected: 38b11090e8dd5372018acc24ea4db2c3d82cf01ed5c69a0fae95bff2379c1630f8c8f96937b22685142b4181e6ef5072e7945c101eb81814a20d90cb1d1f0c08\r
-        //          38b11090e8dd5372018acc24ea4db2c3d82cf01ed5c69a0fae95bff2379c1630f8c8f96937b22685142b4181e6ef5072e7945c101eb81814a20d90cb1d1f0c08\r
+        //expected: e628e980c690d9ef4ca8a2edee1654a6b401edc4f1af7bda3ffd97fe412522c3bab671dd4e51d0aeeb64f8d761fbdb03e296ab0c1dcbed4eafa504f412a98100\r
     }\r
-\r
 }
\ No newline at end of file