OSDN Git Service

refactor
[bytom/bytom-java-sdk.git] / tx-signer / README.md
index d26e3cd..ccf052c 100755 (executable)
-# tx_signer\r
 \r
-Java implementation of signing transaction offline to bytomd.\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/successli/tx_signer.git\r
-   ```\r
-\r
-2. get jar package\r
-\r
-   ```\r
-   $ mvn assembly:assembly -Dmaven.test.skip=true\r
+# tx-signer  \r
+  \r
+Java implementation of signing transaction offline.\r
+  \r
+## Pre  \r
+  \r
+#### Add dependency to your project \r
+  \r
+1. first get source code  \r
+  \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
-- 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
-\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
-\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
+   git clone https://github.com/Bytom/bytom-java-sdk.git  \r
+   ```  \r
+  \r
+2. install to maven repository\r
+  \r
+   ```  \r
+   $ mvn clean install -DskipTests  \r
+   ```  \r
+  \r
+3. add dependency\r
+    ```xml\r
+    <dependency>\r
+        <groupId>io.bytom</groupId>\r
+        <artifactId>tx-signer</artifactId>\r
+        <version>1.0.0</version>\r
+    </dependency>\r
+    ```\r
+  \r
+## Example\r
+\r
+#### build transaction with spend input\r
 ```\r
-\r
-Multi-keys Example:\r
-\r
-> 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
+        String btmAssetID = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";\r
+        \r
+        // create spend input\r
+        SpendInput input = new SpendInput();\r
+        input.setAssetId(btmAssetID);\r
+        input.setAmount(9800000000L);\r
+        \r
+        // control program of spend utxo\r
+        input.setProgram("0014cb9f2391bafe2bc1159b2c4c8a0f17ba1b4dd94e");\r
+        \r
+        // source position of spend utxo\r
+        input.setSourcePosition(2);\r
+        \r
+        // source id of spend utxo\r
+        input.setSourceID("4b5cb973f5bef4eadde4c89b92ee73312b940e84164da0594149554cc8a2adea");\r
+        \r
+        // is the spend utxo used for change\r
+        input.setChange(true);\r
+        \r
+        // BIP protocol for derived paths, default BIP44\r
+        input.setBipProtocol(BIPProtocol.BIP32);\r
+        \r
+        // contorl program index of spend utxo\r
+        input.setControlProgramIndex(457);\r
+        \r
+        // account index\r
+        input.setKeyIndex(1);\r
+        \r
+        // provide a root private key for signing\r
+        input.setRootPrivateKey("4864bae85cf38bfbb347684abdbc01e311a24f99e2c7fe94f3c071d9c83d8a5a349722316972e382c339b79b7e1d83a565c6b3e7cf46847733a47044ae493257");\r
+\r
+        // build transaction with signature\r
+        Transaction tx = new Transaction.Builder()\r
+                .addInput(input)\r
+                .addOutput(new Output(btmAssetID, 8800000000L, "0014a82f02bc37bc5ed87d5f9fca02f8a6a7d89cdd5c"))\r
+                .addOutput(new Output(btmAssetID, 900000000L, "00200824e931fb806bd77fdcd291aad3bd0a4493443a4120062bd659e64a3e0bac66"))\r
+                .setTimeRange(0)\r
+                .build();\r
+\r
+        String rawTransaction = tx.rawTransaction();\r
 ```\r
-Multi-keys and Multi-inputs Example:\r
-\r
-```java\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
+#### build transaction with issuance input\r
 ```\r
-\r
+        IssuanceInput issuanceInput = new IssuanceInput();\r
+        issuanceInput.setAssetId("7b38dc897329a288ea31031724f5c55bcafec80468a546955023380af2faad14");\r
+        issuanceInput.setAmount(100000000000L);\r
+        \r
+        // issuance program\r
+        issuanceInput.setProgram("ae2054a71277cc162eb3eb21b5bd9fe54402829a53b294deaed91692a2cd8a081f9c5151ad");\r
+        issuanceInput.setNonce("ac9d5a527f5ab00a");\r
+        \r
+        // asset index\r
+        issuanceInput.setKeyIndex(5);\r
+        \r
+        // raw asset definition\r
+        issuanceInput.setRawAssetDefinition("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d");\r
+        \r
+        // provide a root private key for signing\r
+        issuanceInput.setRootPrivateKey("4864bae85cf38bfbb347684abdbc01e311a24f99e2c7fe94f3c071d9c83d8a5a349722316972e382c339b79b7e1d83a565c6b3e7cf46847733a47044ae493257");\r
+\r
+        SpendInput spendInput = new SpendInput();\r
+        spendInput.setAssetId(btmAssetID);\r
+        spendInput.setAmount(9800000000L);\r
+        spendInput.setProgram("0014cb9f2391bafe2bc1159b2c4c8a0f17ba1b4dd94e");\r
+        spendInput.setKeyIndex(1);\r
+        spendInput.setChange(true);\r
+        spendInput.setSourceID("4b5cb973f5bef4eadde4c89b92ee73312b940e84164da0594149554cc8a2adea");\r
+        spendInput.setSourcePosition(2);\r
+        spendInput.setControlProgramIndex(457);\r
+        spendInput.setRootPrivateKey("4864bae85cf38bfbb347684abdbc01e311a24f99e2c7fe94f3c071d9c83d8a5a349722316972e382c339b79b7e1d83a565c6b3e7cf46847733a47044ae493257");\r
+\r
+        Transaction tx = new Transaction.Builder()\r
+                .addInput(issuanceInput)\r
+                .addInput(spendInput)\r
+                .addOutput(new Output("7b38dc897329a288ea31031724f5c55bcafec80468a546955023380af2faad14", 100000000000L, "001437e1aec83a4e6587ca9609e4e5aa728db7007449"))\r
+                .addOutput(new Output(btmAssetID, 9700000000L, "00148be1104e04734e5edaba5eea2e85793896b77c56"))\r
+                .setTimeRange(0)\r
+                .build();\r
+\r
+        String rawTx = tx.rawTransaction();\r
+\r
+```
\ No newline at end of file