OSDN Git Service

perfect exception process
authorshenao78 <shenao.78@163.com>
Wed, 20 Mar 2019 09:01:15 +0000 (17:01 +0800)
committershenao78 <shenao.78@163.com>
Wed, 20 Mar 2019 09:01:15 +0000 (17:01 +0800)
19 files changed:
pom.xml
tx-signer/src/main/java/io/bytom/api/BaseInput.java
tx-signer/src/main/java/io/bytom/api/IssuanceInput.java
tx-signer/src/main/java/io/bytom/api/Output.java
tx-signer/src/main/java/io/bytom/api/SpendInput.java
tx-signer/src/main/java/io/bytom/api/Transaction.java
tx-signer/src/main/java/io/bytom/api/TransactionSigner.java [deleted file]
tx-signer/src/main/java/io/bytom/api/UTXO.java [deleted file]
tx-signer/src/main/java/io/bytom/common/ExpandedPrivateKey.java
tx-signer/src/main/java/io/bytom/common/FindDst.java [deleted file]
tx-signer/src/main/java/io/bytom/common/NonHardenedChild.java
tx-signer/src/main/java/io/bytom/common/ParameterizedTypeImpl.java [deleted file]
tx-signer/src/main/java/io/bytom/common/Signer.java [moved from tx-signer/src/main/java/io/bytom/api/Signer.java with 92% similarity]
tx-signer/src/main/java/io/bytom/exception/MapTransactionException.java [new file with mode: 0644]
tx-signer/src/main/java/io/bytom/exception/SerializeTransactionException.java [new file with mode: 0644]
tx-signer/src/main/java/io/bytom/exception/SignTransactionException.java [new file with mode: 0644]
tx-signer/src/test/java/io/bytom/AppTest.java
tx-signer/src/test/java/io/bytom/api/SignerTest.java
tx-signer/src/test/java/io/bytom/api/UTXOTest.java [deleted file]

diff --git a/pom.xml b/pom.xml
index 699501d..0daba5d 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -59,6 +59,8 @@
 
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <maven.compiler.target>1.8</maven.compiler.target>
+        <maven.compiler.source>1.8</maven.compiler.source>
     </properties>
 
     <dependencies>
index 1fb421d..30927ef 100644 (file)
@@ -7,15 +7,18 @@ import java.util.Map;
 
 public abstract class BaseInput {
 
-    public static final int ISSUANCE_INPUT_TYPE = 0;
-    public static final int SPEND_INPUT_TYPE = 1;
+    static final int ISSUANCE_INPUT_TYPE = 0;
+    static final int SPEND_INPUT_TYPE = 1;
+
+    static final byte AssetKeySpace = 0;
+    static final byte AccountKeySpace = 1;
 
     private String inputID;
 
     /**
      * The number of units of the asset being issued or spent.
      */
-    private long amount;
+    private Long amount;
 
     /**
      * The id of the asset being issued or spent.
@@ -24,25 +27,41 @@ public abstract class BaseInput {
 
     /**
      * The program which must be satisfied to transfer this output.
+     * it represents control program when is SpendInput, it represents issuance program when is IssuanceInput
      */
     private String program;
 
-    private int vmVersion;
+    private int vmVersion = 1;
 
-    private int keyIndex;
+    /**
+     * used for bip32 derived path.
+     * it represents accountIndex when is SpendInput, it represents assetIndex when is IssuanceInput
+     */
+    private Integer keyIndex;
 
-    private WitnessComponent witnessComponent = new WitnessComponent();
+    WitnessComponent witnessComponent = new WitnessComponent();
 
-    public BaseInput() {
-        this.vmVersion = 1;
-    }
+    public BaseInput() {}
 
     public abstract InputEntry convertInputEntry(Map<Hash, Entry> entryMap, int index);
-
     public abstract byte[] serializeInput() throws IOException;
-
     public abstract void buildWitness(String txID) throws Exception;
 
+    public void validate() {
+        if (assetId == null) {
+            throw new IllegalArgumentException("the asset id of input must be specified.");
+        }
+        if (amount == null) {
+            throw new IllegalArgumentException("the amount id of input must be specified.");
+        }
+        if (program == null) {
+            throw new IllegalArgumentException("the program id of input must be specified.");
+        }
+        if (witnessComponent.getRootPrivateKey() == null) {
+            throw new IllegalArgumentException("the root private key of input must be specified.");
+        }
+    }
+
     @Override
     public String toString() {
         return Utils.serializer.toJson(this);
@@ -61,47 +80,47 @@ public abstract class BaseInput {
         return inputID;
     }
 
-    public int getKeyIndex() {
-        return keyIndex;
+    public void setInputID(String inputID) {
+        this.inputID = inputID;
     }
 
-    public int getVmVersion() {
-        return vmVersion;
+    public long getAmount() {
+        return amount;
     }
 
-    public String getProgram() {
-        return program;
+    public void setAmount(long amount) {
+        this.amount = amount;
     }
 
     public String getAssetId() {
         return assetId;
     }
 
-    public long getAmount() {
-        return amount;
+    public void setAssetId(String assetId) {
+        this.assetId = assetId;
     }
 
-    public void setInputID(String inputID) {
-        this.inputID = inputID;
+    public String getProgram() {
+        return program;
     }
 
-    public void setAmount(long amount) {
-        this.amount = amount;
+    public void setProgram(String program) {
+        this.program = program;
     }
 
-    public void setAssetId(String assetId) {
-        this.assetId = assetId;
+    public int getVmVersion() {
+        return vmVersion;
     }
 
-    public void setProgram(String program) {
-        this.program = program;
+    public void setVmVersion(int vmVersion) {
+        this.vmVersion = vmVersion;
     }
 
-    public void setKeyIndex(int keyIndex) {
-        this.keyIndex = keyIndex;
+    public int getKeyIndex() {
+        return keyIndex;
     }
 
-    public WitnessComponent getWitnessComponent() {
-        return witnessComponent;
+    public void setKeyIndex(int keyIndex) {
+        this.keyIndex = keyIndex;
     }
 }
index cc3e90f..a8befee 100644 (file)
@@ -2,6 +2,7 @@ package io.bytom.api;
 
 import io.bytom.common.DerivePrivateKey;
 import io.bytom.common.ExpandedPrivateKey;
+import io.bytom.common.Signer;
 import io.bytom.common.Utils;
 import io.bytom.types.*;
 import io.bytom.util.SHA3Util;
@@ -15,10 +16,22 @@ public class IssuanceInput extends BaseInput {
 
     private String nonce;
 
-    private String assetDefinition;
+    private String rawAssetDefinition;
 
     public IssuanceInput() {}
 
+    public IssuanceInput(String assetID, Long amount, String issuanceProgram) {
+        this.setAssetId(assetID);
+        this.setAmount(amount);
+        this.setProgram(issuanceProgram);
+    }
+
+    public IssuanceInput(String assetID, Long amount, String issuanceProgram, String nonce, String rawAssetDefinition) {
+        this(assetID, amount, issuanceProgram);
+        this.nonce = nonce;
+        this.rawAssetDefinition = rawAssetDefinition;
+    }
+
     @Override
     public InputEntry convertInputEntry(Map<Hash, Entry> entryMap, int index) {
         if (this.nonce == null) {
@@ -29,7 +42,7 @@ public class IssuanceInput extends BaseInput {
         }
 
         Hash nonceHash = new Hash(SHA3Util.hashSha256(Hex.decode(this.nonce)));
-        Hash assetDefHash = new Hash(this.assetDefinition);
+        Hash assetDefHash = new Hash(this.rawAssetDefinition);
         AssetAmount value = this.getAssetAmount();
 
         Issue issuance = new Issue(nonceHash, value, index);
@@ -58,25 +71,23 @@ public class IssuanceInput extends BaseInput {
         //未知
         Utils.writeVarint(1, issueInfo1);
         //写入assetDefine
-        Utils.writeVarStr(Hex.decode(assetDefinition), issueInfo1);
+        Utils.writeVarStr(Hex.decode(rawAssetDefinition), issueInfo1);
         //vm.version
         Utils.writeVarint(1, issueInfo1);
         //controlProgram
         Utils.writeVarStr(Hex.decode(getProgram()), issueInfo1);
 
         //inputWitness
-        if (null != getWitnessComponent()) {
-            ByteArrayOutputStream witnessStream = new ByteArrayOutputStream();
-            //arguments
-            int witnessSize = getWitnessComponent().size();
-            //arguments的length
-            Utils.writeVarint(witnessSize, witnessStream);
-            for (int i = 0; i < witnessSize; i++) {
-                String witness = getWitnessComponent().getWitness(i);
-                Utils.writeVarStr(Hex.decode(witness), witnessStream);
-            }
-            issueInfo1.write(witnessStream.toByteArray());
+        ByteArrayOutputStream witnessStream = new ByteArrayOutputStream();
+        //arguments
+        int witnessSize = witnessComponent.size();
+        //arguments的length
+        Utils.writeVarint(witnessSize, witnessStream);
+        for (int i = 0; i < witnessSize; i++) {
+            String witness = witnessComponent.getWitness(i);
+            Utils.writeVarStr(Hex.decode(witness), witnessStream);
         }
+        issueInfo1.write(witnessStream.toByteArray());
         stream.write(issueInfo1.toByteArray().length - 1);
         stream.write(issueInfo1.toByteArray());
         return stream.toByteArray();
@@ -84,21 +95,40 @@ public class IssuanceInput extends BaseInput {
 
     @Override
     public void buildWitness(String txID) throws Exception {
-        String rootPrivateKey = getWitnessComponent().getRootPrivateKey();
-        byte[] childPrivateKey = DerivePrivateKey.bip32derivePrvKey(rootPrivateKey, getKeyIndex(), TransactionSigner.AssetKeySpace);
+        String rootPrivateKey = witnessComponent.getRootPrivateKey();
+        byte[] childPrivateKey = DerivePrivateKey.bip32derivePrvKey(rootPrivateKey, getKeyIndex(), AssetKeySpace);
 
         byte[] message = Utils.hashFn(Hex.decode(getInputID()), Hex.decode(txID));
         byte[] expandedPrivateKey = ExpandedPrivateKey.expandedPrivateKey(childPrivateKey);
         byte[] sig = Signer.ed25519InnerSign(expandedPrivateKey, message);
 
-        getWitnessComponent().appendWitness(Hex.toHexString(sig));
+        witnessComponent.appendWitness(Hex.toHexString(sig));
+    }
+
+    @Override
+    public void validate() {
+        super.validate();
+        if (nonce == null) {
+            throw new IllegalArgumentException("the nonce of issuance input must be specified.");
+        }
+        if (rawAssetDefinition == null) {
+            throw new IllegalArgumentException("the nonce of issuance input must be specified.");
+        }
+    }
+
+    public String getNonce() {
+        return nonce;
     }
 
     public void setNonce(String nonce) {
         this.nonce = nonce;
     }
 
-    public void setAssetDefinition(String assetDefinition) {
-        this.assetDefinition = assetDefinition;
+    public String getRawAssetDefinition() {
+        return rawAssetDefinition;
+    }
+
+    public void setRawAssetDefinition(String rawAssetDefinition) {
+        this.rawAssetDefinition = rawAssetDefinition;
     }
 }
index 7d3d4ba..5c82dc4 100644 (file)
@@ -4,24 +4,13 @@ import io.bytom.common.Utils;
 import org.bouncycastle.util.encoders.Hex;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.util.Map;
 
 public class Output {
 
     /**
-     * address
-     */
-    public String address;
-
-    /**
      * The number of units of the asset being controlled.
      */
-    public long amount;
-
-    /**
-     * The definition of the asset being controlled (possibly null).
-     */
-    public Map<String, Object> assetDefinition;
+    public Long amount;
 
     /**
      * The id of the asset being controlled.
@@ -43,7 +32,7 @@ public class Output {
      */
     public Integer position;
 
-    public Output(String assetId, long amount, String controlProgram) {
+    public Output(String assetId, Long amount, String controlProgram) {
         this.assetId = assetId;
         this.amount = amount;
         this.controlProgram = controlProgram;
@@ -75,34 +64,39 @@ public class Output {
         return stream.toByteArray();
     }
 
-    /**
-     * The type the output.<br>
-     * Possible values are "control" and "retire".
-     */
-    public String type;
-
-    public Output setAddress(String address) {
-        this.address = address;
-        return this;
+    public Long getAmount() {
+        return amount;
     }
 
-    public Output setAmount(long amount) {
+    public void setAmount(Long amount) {
         this.amount = amount;
-        return this;
     }
 
-    public Output setAssetId(String assetId) {
+    public String getAssetId() {
+        return assetId;
+    }
+
+    public void setAssetId(String assetId) {
         this.assetId = assetId;
-        return this;
     }
 
-    public Output setControlProgram(String controlProgram) {
+    public String getControlProgram() {
+        return controlProgram;
+    }
+
+    public void setControlProgram(String controlProgram) {
         this.controlProgram = controlProgram;
-        return this;
     }
 
-    public Output setPosition(Integer position) {
+    public String getId() {
+        return id;
+    }
+
+    public Integer getPosition() {
+        return position;
+    }
+
+    public void setPosition(Integer position) {
         this.position = position;
-        return this;
     }
 }
index 7d1fa68..e6f407c 100644 (file)
@@ -9,15 +9,15 @@ import java.util.Map;
 
 public class SpendInput extends BaseInput {
 
-    private String sourceId;
+    private String sourceID;
 
-    private long sourcePosition;
+    private Integer sourcePosition;
 
-    private boolean change;
+    private Boolean change;
 
-    private int controlProgramIndex;
+    private Integer controlProgramIndex;
 
-    private BIPProtocol bipProtocol;
+    private BIPProtocol bipProtocol = BIPProtocol.BIP44;
 
     public SpendInput() {}
 
@@ -25,14 +25,19 @@ public class SpendInput extends BaseInput {
         this.setAssetId(assetID);
         this.setAmount(amount);
         this.setProgram(controlProgram);
-        this.bipProtocol = BIPProtocol.BIP44;
+    }
+
+    public SpendInput(String assetID, long amount, String controlProgram, String sourceID, Integer sourcePosition) {
+        this(assetID, amount, controlProgram);
+        this.sourceID = sourceID;
+        this.sourcePosition = sourcePosition;
     }
 
     @Override
     public InputEntry convertInputEntry(Map<Hash, Entry> entryMap, int index) {
         Program pro = new Program(this.getVmVersion(), Hex.decode(this.getProgram()));
         AssetAmount assetAmount = this.getAssetAmount();
-        Hash sourceID = new Hash(this.sourceId);
+        Hash sourceID = new Hash(this.sourceID);
         ValueSource src = new ValueSource(sourceID, assetAmount, this.sourcePosition);
 
         OutputEntry prevout = new OutputEntry(src, pro, 0);
@@ -53,7 +58,7 @@ public class SpendInput extends BaseInput {
         Utils.writeVarint(SPEND_INPUT_TYPE, inputCommitStream);
         //spendCommitment
         ByteArrayOutputStream spendCommitSteam = new ByteArrayOutputStream();
-        spendCommitSteam.write(Hex.decode(sourceId)); //计算muxID
+        spendCommitSteam.write(Hex.decode(sourceID)); //计算muxID
         spendCommitSteam.write(Hex.decode(getAssetId()));
         Utils.writeVarint(getAmount(), spendCommitSteam);
         //sourcePosition
@@ -73,52 +78,67 @@ public class SpendInput extends BaseInput {
         stream.write(dataInputCommit);
 
         //inputWitness
-        if (null != getWitnessComponent()) {
-            ByteArrayOutputStream witnessStream = new ByteArrayOutputStream();
-            //arguments
-            int witnessSize = getWitnessComponent().size();
-            //arguments的length
-            Utils.writeVarint(witnessSize, witnessStream);
-            for (int i = 0; i < witnessSize; i++) {
-                String witness = getWitnessComponent().getWitness(i);
-                Utils.writeVarStr(Hex.decode(witness), witnessStream);
-            }
-            byte[] dataWitnessComponents = witnessStream.toByteArray();
-            //witness的length
-            Utils.writeVarint(dataWitnessComponents.length, stream);
-            stream.write(dataWitnessComponents);
+        ByteArrayOutputStream witnessStream = new ByteArrayOutputStream();
+        //arguments
+        int witnessSize = witnessComponent.size();
+        //arguments的length
+        Utils.writeVarint(witnessSize, witnessStream);
+        for (int i = 0; i < witnessSize; i++) {
+            String witness = witnessComponent.getWitness(i);
+            Utils.writeVarStr(Hex.decode(witness), witnessStream);
         }
+        byte[] dataWitnessComponents = witnessStream.toByteArray();
+        //witness的length
+        Utils.writeVarint(dataWitnessComponents.length, stream);
+        stream.write(dataWitnessComponents);
         return stream.toByteArray();
     }
 
     @Override
     public void buildWitness(String txID) throws Exception {
-        String rootPrvKey = getWitnessComponent().getRootPrivateKey();
+        String rootPrvKey = witnessComponent.getRootPrivateKey();
 
         byte[] privateChild;
         if (bipProtocol == BIPProtocol.BIP44) {
-            privateChild = DerivePrivateKey.bip44derivePrvKey(rootPrvKey, TransactionSigner.AccountKeySpace, change, controlProgramIndex);
+            privateChild = DerivePrivateKey.bip44derivePrvKey(rootPrvKey, AccountKeySpace, change, controlProgramIndex);
         } else {
-            privateChild = DerivePrivateKey.bip32derivePrvKey(rootPrvKey, getKeyIndex(), TransactionSigner.AccountKeySpace, controlProgramIndex);
+            privateChild = DerivePrivateKey.bip32derivePrvKey(rootPrvKey, getKeyIndex(), AccountKeySpace, controlProgramIndex);
         }
 
         byte[] message = Utils.hashFn(Hex.decode(getInputID()), Hex.decode(txID));
         byte[] expandedPrivateKey = ExpandedPrivateKey.expandedPrivateKey(privateChild);
         byte[] sig = Signer.ed25519InnerSign(expandedPrivateKey, message);
 
-        getWitnessComponent().appendWitness(Hex.toHexString(sig));
+        witnessComponent.appendWitness(Hex.toHexString(sig));
 
         byte[] deriveXpub = DeriveXpub.deriveXpub(privateChild);
         String pubKey = Hex.toHexString(deriveXpub).substring(0, 64);
 
-        getWitnessComponent().appendWitness(pubKey);
+        witnessComponent.appendWitness(pubKey);
+    }
+
+    @Override
+    public void validate() {
+        super.validate();
+        if (sourceID == null) {
+            throw new IllegalArgumentException("the source id of spend input must be specified.");
+        }
+        if (sourcePosition == null) {
+            throw new IllegalArgumentException("the source position of spend input must be specified.");
+        }
+        if (change == null) {
+            throw new IllegalArgumentException("the change of spend input must be specified.");
+        }
+        if (controlProgramIndex == null) {
+            throw new IllegalArgumentException("the control program index of spend input must be specified.");
+        }
     }
 
-    public void setSourceId(String sourceId) {
-        this.sourceId = sourceId;
+    public void setSourceID(String sourceID) {
+        this.sourceID = sourceID;
     }
 
-    public void setSourcePosition(long sourcePosition) {
+    public void setSourcePosition(int sourcePosition) {
         this.sourcePosition = sourcePosition;
     }
 
index 48e9bd5..85b5881 100755 (executable)
@@ -1,9 +1,11 @@
 package io.bytom.api;\r
 \r
 import io.bytom.common.Utils;\r
+import io.bytom.exception.MapTransactionException;\r
+import io.bytom.exception.SerializeTransactionException;\r
+import io.bytom.exception.SignTransactionException;\r
 import io.bytom.types.*;\r
 import org.bouncycastle.util.encoders.Hex;\r
-\r
 import java.io.ByteArrayOutputStream;\r
 import java.io.IOException;\r
 import java.util.ArrayList;\r
@@ -17,29 +19,29 @@ import java.util.Map;
 \r
 public class Transaction {\r
 \r
-    public String txID;\r
+    private String txID;\r
     /**\r
      * version\r
      */\r
-    public Integer version;\r
+    private Integer version;\r
     /**\r
      * size\r
      */\r
-    public Integer size;\r
+    private Integer size;\r
     /**\r
      * time_range\r
      */\r
-    public Integer timeRange;\r
+    private Integer timeRange;\r
 \r
     /**\r
      * List of specified inputs for a transaction.\r
      */\r
-    public List<BaseInput> inputs;\r
+    private List<BaseInput> inputs;\r
 \r
     /**\r
      * List of specified outputs for a transaction.\r
      */\r
-    public List<Output> outputs;\r
+    private List<Output> outputs;\r
 \r
     public Transaction(Builder builder) {\r
         this.inputs = builder.inputs;\r
@@ -47,14 +49,14 @@ public class Transaction {
         this.version = builder.version;\r
         this.size = builder.size;\r
         this.timeRange = builder.timeRange;\r
-        mapTx();\r
-        sign();\r
+\r
+        this.validate();\r
+        this.mapTransaction();\r
+        this.sign();\r
     }\r
 \r
     public static class Builder {\r
 \r
-        private String txID;\r
-\r
         private Integer version = 1;\r
 \r
         private Integer size = 0;\r
@@ -95,47 +97,51 @@ public class Transaction {
                 input.buildWitness(txID);\r
             } catch (Exception e) {\r
                 e.printStackTrace();\r
-                throw new RuntimeException(e);\r
+                throw new SignTransactionException(e);\r
             }\r
         }\r
     }\r
 \r
     public String rawTransaction() {\r
-        String rawTransaction;\r
-        //开始序列化\r
         ByteArrayOutputStream stream = new ByteArrayOutputStream();\r
         try {\r
             stream.write(7);\r
-            // version\r
-            if (null != version)\r
-                Utils.writeVarint(version, stream);\r
-            if (null != timeRange)\r
-                Utils.writeVarint(timeRange, stream);\r
-            //inputs\r
-            if (null != inputs && inputs.size() > 0) {\r
-                Utils.writeVarint(inputs.size(), stream);\r
-                for (BaseInput input : inputs) {\r
-                    System.out.println(Hex.toHexString(input.serializeInput()));\r
-                    stream.write(input.serializeInput());\r
-                }\r
+\r
+            Utils.writeVarint(version, stream);\r
+\r
+            Utils.writeVarint(timeRange, stream);\r
+\r
+            Utils.writeVarint(inputs.size(), stream);\r
+            for (BaseInput input : inputs) {\r
+                stream.write(input.serializeInput());\r
             }\r
 \r
-            //outputs\r
-            if (null != outputs && outputs.size() > 0) {\r
-                Utils.writeVarint(outputs.size(), stream);\r
-                for (Output output : outputs) {\r
-                    stream.write(output.serializeOutput());\r
-                }\r
+            Utils.writeVarint(outputs.size(), stream);\r
+            for (Output output : outputs) {\r
+                stream.write(output.serializeOutput());\r
             }\r
-            byte[] data = stream.toByteArray();\r
-            rawTransaction = Hex.toHexString(data);\r
         } catch (IOException e) {\r
-            throw new RuntimeException(e);\r
+            e.printStackTrace();\r
+            throw new SerializeTransactionException(e);\r
+        }\r
+        return Hex.toHexString(stream.toByteArray());\r
+    }\r
+\r
+    private void validate() {\r
+        if (version == null) {\r
+            throw new IllegalArgumentException("the version of transaction must be specified.");\r
+        }\r
+        if (timeRange == null) {\r
+            throw new IllegalArgumentException("the time range of transaction must be specified.");\r
+        }\r
+        if (size == null) {\r
+            throw new IllegalArgumentException("the size range of transaction must be specified.");\r
         }\r
-        return rawTransaction;\r
+\r
+        inputs.forEach(BaseInput::validate);\r
     }\r
 \r
-    private void mapTx() {\r
+    private void mapTransaction() {\r
         Map<Hash, Entry> entryMap = new HashMap<>();\r
         ValueSource[] muxSources = new ValueSource[inputs.size()];\r
         List<InputEntry> inputEntries = new ArrayList<>();\r
@@ -186,7 +192,7 @@ public class Transaction {
             this.txID = txID.toString();\r
 \r
         } catch (Exception e) {\r
-            throw new RuntimeException(e);\r
+            throw new MapTransactionException(e);\r
         }\r
     }\r
 \r
@@ -195,4 +201,28 @@ public class Transaction {
         entryMap.put(id, entry);\r
         return id;\r
     }\r
+\r
+    public String getTxID() {\r
+        return txID;\r
+    }\r
+\r
+    public Integer getVersion() {\r
+        return version;\r
+    }\r
+\r
+    public Integer getSize() {\r
+        return size;\r
+    }\r
+\r
+    public Integer getTimeRange() {\r
+        return timeRange;\r
+    }\r
+\r
+    public List<BaseInput> getInputs() {\r
+        return inputs;\r
+    }\r
+\r
+    public List<Output> getOutputs() {\r
+        return outputs;\r
+    }\r
 }\r
diff --git a/tx-signer/src/main/java/io/bytom/api/TransactionSigner.java b/tx-signer/src/main/java/io/bytom/api/TransactionSigner.java
deleted file mode 100755 (executable)
index 5215c2d..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-package io.bytom.api;\r
-\r
-/**\r
- * Created by liqiang on 2018/10/24.\r
- */\r
-public class TransactionSigner {\r
-\r
-    public static final byte AssetKeySpace = 0;\r
-    public static final byte AccountKeySpace = 1;\r
-}\r
-\r
-\r
diff --git a/tx-signer/src/main/java/io/bytom/api/UTXO.java b/tx-signer/src/main/java/io/bytom/api/UTXO.java
deleted file mode 100755 (executable)
index 1042073..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-package io.bytom.api;\r
-\r
-import com.google.gson.annotations.SerializedName;\r
-import io.bytom.common.Utils;\r
-\r
-public class UTXO {\r
-    /**\r
-     * id : fda38648c553386c56b2f1276b908061b5d812341f0a96921abad8b2b2f28044\r
-     * amount : 1700000\r
-     * address : tm1qhw9q89exmudkf9ecaxtnmv22fd8af0k07jq7u5\r
-     * program : 0014bb8a039726df1b649738e9973db14a4b4fd4becf\r
-     * change : true\r
-     * highest : 139744\r
-     * account_alias : wyjbtm\r
-     * asset_id : ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\r
-     * asset_alias : BTM\r
-     * account_id : 0NNSS39M00A02\r
-     * control_program_index : 26\r
-     * source_id : 34bc595dff3d40c2bd644e0ea0234e843ef8e3aa0720013a2cb712362cc5933f\r
-     * source_pos : 0\r
-     * valid_height : 0\r
-     * derive_rule : 0\r
-     */\r
-\r
-    @SerializedName("id")\r
-    public String id;\r
-    @SerializedName("amount")\r
-    public long amount;\r
-    @SerializedName("address")\r
-    public String address;\r
-    @SerializedName("program")\r
-    public String program;\r
-    @SerializedName("change")\r
-    public boolean change;\r
-    @SerializedName("highest")\r
-    public int highest;\r
-    @SerializedName("account_alias")\r
-    public String accountAlias;\r
-    @SerializedName("asset_id")\r
-    public String assetId;\r
-    @SerializedName("asset_alias")\r
-    public String assetAlias;\r
-    @SerializedName("account_id")\r
-    public String accountId;\r
-    @SerializedName("control_program_index")\r
-    public int controlProgramIndex;\r
-    @SerializedName("source_id")\r
-    public String sourceId;\r
-    @SerializedName("source_pos")\r
-    public int sourcePos;\r
-    @SerializedName("valid_height")\r
-    public int validHeight;\r
-    @SerializedName("derive_rule")\r
-    public int deriveRule;\r
-\r
-    public String toJson() {\r
-        return Utils.serializer.toJson(this);\r
-    }\r
-\r
-    public static UTXO fromJson(String json) {\r
-        return Utils.serializer.fromJson(json, UTXO.class);\r
-    }\r
-\r
-    public SpendInput toSpendAnnotatedInput() {\r
-        SpendInput spendInput = new SpendInput();\r
-        spendInput.setAmount(amount);\r
-        spendInput.setProgram(program);\r
-        spendInput.setChange(change);\r
-        spendInput.setAssetId(assetId);\r
-        spendInput.setControlProgramIndex(controlProgramIndex);\r
-        spendInput.setSourceId(sourceId);\r
-        spendInput.setSourcePosition(sourcePos);\r
-        return spendInput;\r
-    }\r
-}\r
index a941efa..9094929 100755 (executable)
@@ -1,24 +1,20 @@
 package io.bytom.common;\r
 \r
 import org.bouncycastle.util.encoders.Hex;\r
-\r
 import javax.crypto.Mac;\r
 import javax.crypto.spec.SecretKeySpec;\r
 import java.security.InvalidKeyException;\r
 import java.security.NoSuchAlgorithmException;\r
-import java.security.SignatureException;\r
 \r
 public class ExpandedPrivateKey {\r
-    public static byte[] hmacSha512(byte[] data, byte[] key)\r
-            throws SignatureException, NoSuchAlgorithmException, InvalidKeyException {\r
+    public static byte[] hmacSha512(byte[] data, byte[] key) throws NoSuchAlgorithmException, InvalidKeyException {\r
         SecretKeySpec signingKey = new SecretKeySpec(key, "HmacSHA512");\r
         Mac mac = Mac.getInstance("HmacSHA512");\r
         mac.init(signingKey);\r
         return mac.doFinal(data);\r
     }\r
 \r
-    public static byte[] expandedPrivateKey(byte[] data)\r
-            throws SignatureException, NoSuchAlgorithmException, InvalidKeyException {\r
+    public static byte[] expandedPrivateKey(byte[] data) throws NoSuchAlgorithmException, InvalidKeyException {\r
         // "457870616e64" is "Expand" hex.\r
         byte[] res = hmacSha512(data, Hex.decode("457870616e64"));\r
         for (int i = 0; i <= 31; i++) {\r
diff --git a/tx-signer/src/main/java/io/bytom/common/FindDst.java b/tx-signer/src/main/java/io/bytom/common/FindDst.java
deleted file mode 100755 (executable)
index 4bfd4d5..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package io.bytom.common;\r
-\r
-import org.apache.log4j.Logger;\r
-import org.bouncycastle.util.encoders.Hex;\r
-\r
-public class FindDst {\r
-\r
-    public static Logger logger = Logger.getLogger(FindDst.class);\r
-\r
-    public static int find(String[] privateKeys, String xpub) throws Exception {\r
-        // 多签情况下,找到xpub对应的private key的下标 dst\r
-        int dst = -1;\r
-        for (int k = 0; k < privateKeys.length; k++) {\r
-            byte[] tempXpub = DeriveXpub.deriveXpub(Hex.decode(privateKeys[k]));\r
-            if (xpub.equals(Hex.toHexString(tempXpub))) {\r
-                dst = k;\r
-                logger.info("private[dst]: " + privateKeys[dst]);\r
-                break;\r
-            }\r
-        }\r
-        if (dst == -1) {\r
-            throw new Exception("Not a proper private key to sign transaction.");\r
-        }\r
-        return dst;\r
-    }\r
-}\r
index 05b79c5..1fdf13b 100755 (executable)
@@ -7,7 +7,6 @@ import javax.crypto.spec.SecretKeySpec;
 import java.io.ByteArrayOutputStream;\r
 import java.security.InvalidKeyException;\r
 import java.security.NoSuchAlgorithmException;\r
-import java.security.SignatureException;\r
 \r
 public class NonHardenedChild {\r
 \r
@@ -19,7 +18,7 @@ public class NonHardenedChild {
         return mac.doFinal(data);\r
     }\r
 \r
-    public static byte[] nhChild(byte[] path, byte[] xprv, byte[] xpub) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {\r
+    public static byte[] nhChild(byte[] path, byte[] xprv, byte[] xpub) throws NoSuchAlgorithmException, InvalidKeyException {\r
         // begin build data\r
         ByteArrayOutputStream out = new ByteArrayOutputStream();\r
         out.write('N');\r
@@ -68,7 +67,7 @@ public class NonHardenedChild {
         return f;\r
     }\r
 \r
-    public static byte[] child(byte[] xprv, String[] hpaths) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {\r
+    public static byte[] child(byte[] xprv, String[] hpaths) throws NoSuchAlgorithmException, InvalidKeyException {\r
         byte[][] paths = new byte[][]{\r
                 Hex.decode(hpaths[0]),\r
                 Hex.decode(hpaths[1])\r
diff --git a/tx-signer/src/main/java/io/bytom/common/ParameterizedTypeImpl.java b/tx-signer/src/main/java/io/bytom/common/ParameterizedTypeImpl.java
deleted file mode 100755 (executable)
index 741b792..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-package io.bytom.common;\r
-\r
-import java.lang.reflect.ParameterizedType;\r
-import java.lang.reflect.Type;\r
-\r
-public class ParameterizedTypeImpl implements ParameterizedType {\r
-\r
-    private final Class raw;\r
-    private final Type[] args;\r
-\r
-    public ParameterizedTypeImpl(Class raw, Type[] args) {\r
-        this.raw = raw;\r
-        this.args = args != null ? args : new Type[0];\r
-    }\r
-\r
-    @Override\r
-    public Type[] getActualTypeArguments() {\r
-        return args;\r
-    }\r
-\r
-    @Override\r
-    public Type getRawType() {\r
-        return raw;\r
-    }\r
-\r
-    @Override\r
-    public Type getOwnerType() {\r
-        return null;\r
-    }\r
-}\r
@@ -1,11 +1,7 @@
-package io.bytom.api;\r
+package io.bytom.common;\r
 \r
-import io.bytom.common.DeriveXpub;\r
-\r
-import java.security.InvalidKeyException;\r
 import java.security.MessageDigest;\r
 import java.security.NoSuchAlgorithmException;\r
-import java.security.SignatureException;\r
 import java.util.Arrays;\r
 \r
 public class Signer {\r
diff --git a/tx-signer/src/main/java/io/bytom/exception/MapTransactionException.java b/tx-signer/src/main/java/io/bytom/exception/MapTransactionException.java
new file mode 100644 (file)
index 0000000..06c7d40
--- /dev/null
@@ -0,0 +1,21 @@
+package io.bytom.exception;
+
+public class MapTransactionException extends RuntimeException {
+
+    public MapTransactionException() {
+        super();
+    }
+
+    public MapTransactionException(String message) {
+        super(message);
+    }
+
+    public MapTransactionException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+
+    public MapTransactionException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/tx-signer/src/main/java/io/bytom/exception/SerializeTransactionException.java b/tx-signer/src/main/java/io/bytom/exception/SerializeTransactionException.java
new file mode 100644 (file)
index 0000000..86b1017
--- /dev/null
@@ -0,0 +1,21 @@
+package io.bytom.exception;
+
+public class SerializeTransactionException extends RuntimeException {
+
+    public SerializeTransactionException() {
+        super();
+    }
+
+    public SerializeTransactionException(String message) {
+        super(message);
+    }
+
+    public SerializeTransactionException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+
+    public SerializeTransactionException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/tx-signer/src/main/java/io/bytom/exception/SignTransactionException.java b/tx-signer/src/main/java/io/bytom/exception/SignTransactionException.java
new file mode 100644 (file)
index 0000000..d9a7ac5
--- /dev/null
@@ -0,0 +1,21 @@
+package io.bytom.exception;
+
+public class SignTransactionException extends RuntimeException {
+
+    public SignTransactionException() {
+        super();
+    }
+
+    public SignTransactionException(String message) {
+        super(message);
+    }
+
+    public SignTransactionException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+
+    public SignTransactionException(Throwable cause) {
+        super(cause);
+    }
+}
index ccfc2c3..0569c76 100755 (executable)
@@ -13,7 +13,7 @@ public class AppTest {
     public void testSpendBIP44() {\r
         SpendInput input = new SpendInput(btmAssetID, 9800000000L, "0014cb9f2391bafe2bc1159b2c4c8a0f17ba1b4dd94e");\r
         input.setSourcePosition(2);\r
-        input.setSourceId("4b5cb973f5bef4eadde4c89b92ee73312b940e84164da0594149554cc8a2adea");\r
+        input.setSourceID("4b5cb973f5bef4eadde4c89b92ee73312b940e84164da0594149554cc8a2adea");\r
         input.setChange(true);\r
         input.setControlProgramIndex(457);\r
         input.setKeyIndex(1);\r
@@ -33,7 +33,7 @@ public class AppTest {
     @Test\r
     public void testSpendBIP32() {\r
         SpendInput input = new SpendInput(btmAssetID, 11718900000L, "0014085a02ecdf934a56343aa59a3dec9d9feb86ee43");\r
-        input.setSourceId("5ac79a73db78e5c9215b37cb752f0147d1157c542bb4884908ceb97abc33fe0a");\r
+        input.setSourceID("5ac79a73db78e5c9215b37cb752f0147d1157c542bb4884908ceb97abc33fe0a");\r
         input.setSourcePosition(0);\r
         input.setRootPrivateKey("4864bae85cf38bfbb347684abdbc01e311a24f99e2c7fe94f3c071d9c83d8a5a349722316972e382c339b79b7e1d83a565c6b3e7cf46847733a47044ae493257");\r
         input.setChange(true);\r
@@ -61,14 +61,14 @@ public class AppTest {
         issuanceInput.setProgram("ae2054a71277cc162eb3eb21b5bd9fe54402829a53b294deaed91692a2cd8a081f9c5151ad");\r
         issuanceInput.setNonce("ac9d5a527f5ab00a");\r
         issuanceInput.setKeyIndex(5);\r
-        issuanceInput.setAssetDefinition("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d");\r
+        issuanceInput.setRawAssetDefinition("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d");\r
         issuanceInput.setRootPrivateKey("4864bae85cf38bfbb347684abdbc01e311a24f99e2c7fe94f3c071d9c83d8a5a349722316972e382c339b79b7e1d83a565c6b3e7cf46847733a47044ae493257");\r
 \r
         SpendInput spendInput = new SpendInput(btmAssetID, 9800000000L, "0014cb9f2391bafe2bc1159b2c4c8a0f17ba1b4dd94e");\r
         spendInput.setBipProtocol(BIPProtocol.BIP32);\r
         spendInput.setKeyIndex(1);\r
         spendInput.setChange(true);\r
-        spendInput.setSourceId("4b5cb973f5bef4eadde4c89b92ee73312b940e84164da0594149554cc8a2adea");\r
+        spendInput.setSourceID("4b5cb973f5bef4eadde4c89b92ee73312b940e84164da0594149554cc8a2adea");\r
         spendInput.setSourcePosition(2);\r
         spendInput.setControlProgramIndex(457);\r
         spendInput.setRootPrivateKey("4864bae85cf38bfbb347684abdbc01e311a24f99e2c7fe94f3c071d9c83d8a5a349722316972e382c339b79b7e1d83a565c6b3e7cf46847733a47044ae493257");\r
@@ -93,21 +93,21 @@ public class AppTest {
         String retireControlProgram = "6a"+Integer.toString(Hex.decode(arbitrary).length,16)+arbitrary;\r
         String assetId1 = "207265909236260b30942a6b00e30ceb769e0e58156b6482bac64117619c9dcf";\r
 \r
-        SpendInput input1 = new SpendInput(btmAssetID, 289100000, "0014f1dc52048f439ac7fd74f8106a21da78f00de48f");\r
+        SpendInput input1 = new SpendInput(btmAssetID, 289100000L, "0014f1dc52048f439ac7fd74f8106a21da78f00de48f");\r
         input1.setRootPrivateKey(rootKey);\r
         input1.setChange(true);\r
         input1.setControlProgramIndex(41);\r
-        input1.setSourceId("0b2cff11d1d056d95237a5f2d06059e5395e86f60e69c1e8201ea624911c0c65");\r
+        input1.setSourceID("0b2cff11d1d056d95237a5f2d06059e5395e86f60e69c1e8201ea624911c0c65");\r
         input1.setSourcePosition(0);\r
 \r
         SpendInput input2 = new SpendInput(assetId1, 70000000000L, "0014bb8a039726df1b649738e9973db14a4b4fd4becf");\r
         input2.setRootPrivateKey(rootKey);\r
         input2.setChange(true);\r
         input2.setControlProgramIndex(26);\r
-        input2.setSourceId("be0ac837e832c34a02968e54dab4f95cbeceb9fb01cd378310f6ea32219ee29b");\r
+        input2.setSourceID("be0ac837e832c34a02968e54dab4f95cbeceb9fb01cd378310f6ea32219ee29b");\r
         input2.setSourcePosition(1);\r
 \r
-        Output output1 = new Output(btmAssetID, 279100000, "001414d362694eacfa110dc20dec77d610d22340f95b");\r
+        Output output1 = new Output(btmAssetID, 279100000L, "001414d362694eacfa110dc20dec77d610d22340f95b");\r
         Output output2 = new Output(assetId1, 10000000000L, retireControlProgram);\r
         Output output3 = new Output(assetId1, 60000000000L, "0014bb8a039726df1b649738e9973db14a4b4fd4becf");\r
 \r
@@ -123,29 +123,4 @@ public class AppTest {
         String rawTransaction = transaction.rawTransaction();\r
         assert  rawTransaction.equals("070180897a020160015e0b2cff11d1d056d95237a5f2d06059e5395e86f60e69c1e8201ea624911c0c65ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0a1ed89010001160014f1dc52048f439ac7fd74f8106a21da78f00de48f6302401660121218ab96d9f22cce712541ca34c53f4da40450669854341ca9624ad1cf10d1bfc96449fad5406224afd253ccfbdeab683f7ec7f9ee8f45e47a0c58500f2031ecc1bdd5fb9b40016358340b87646ea39faf55c0c105205cfdfdc6184725f40161015fbe0ac837e832c34a02968e54dab4f95cbeceb9fb01cd378310f6ea32219ee29b207265909236260b30942a6b00e30ceb769e0e58156b6482bac64117619c9dcf80f8cce284020101160014bb8a039726df1b649738e9973db14a4b4fd4becf630240d7b7f1c2ca1048fd6798234f2a1e895762f83e802507a008eff52605611b67390a74eaf228b76f5589ff109b2c20eaa65fad6de2e5ab8a25b54267b607df970b20a71547e1064b5edaad92cdce6b0ace832836ba28fdeaf0b83010bed247fe927c03013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f48a85010116001414d362694eacfa110dc20dec77d610d22340f95b00014b207265909236260b30942a6b00e30ceb769e0e58156b6482bac64117619c9dcf80c8afa02501246a2277656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c00013e207265909236260b30942a6b00e30ceb769e0e58156b6482bac64117619c9dcf80b09dc2df0101160014bb8a039726df1b649738e9973db14a4b4fd4becf00");\r
     }\r
-\r
-\r
-    //utxo\r
-    private SpendInput btmUtxoToInput() {\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\": 141905,\n" +\r
-                "  \"account_alias\": \"wyjbtm\",\n" +\r
-                "  \"asset_id\": \"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\",\n" +\r
-                "  \"asset_alias\": \"BTM\",\n" +\r
-                "  \"account_id\": \"0NNSS39M00A02\",\n" +\r
-                "  \"control_program_index\": 2,\n" +\r
-                "  \"source_id\": \"535b88d3f6b449fdba678b00b84d4b516df1da73104d689d41f964389f5a9217\",\n" +\r
-                "  \"source_pos\": 1,\n" +\r
-                "  \"valid_height\": 0,\n" +\r
-                "  \"derive_rule\": 0\n" +\r
-                "}";\r
-        UTXO utxo = UTXO.fromJson(utxoJson);\r
-        return utxo.toSpendAnnotatedInput();\r
-    }\r
 }\r
index 8117852..21b64fb 100755 (executable)
@@ -1,5 +1,6 @@
 package io.bytom.api;\r
 \r
+import io.bytom.common.Signer;\r
 import org.bouncycastle.util.encoders.Hex;\r
 import org.junit.Test;\r
 \r
diff --git a/tx-signer/src/test/java/io/bytom/api/UTXOTest.java b/tx-signer/src/test/java/io/bytom/api/UTXOTest.java
deleted file mode 100755 (executable)
index 11249a2..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-package io.bytom.api;\r
-\r
-import org.junit.Test;\r
-\r
-import java.security.InvalidKeyException;\r
-import java.security.NoSuchAlgorithmException;\r
-import java.security.SignatureException;\r
-\r
-public class UTXOTest {\r
-    @Test\r
-    public void testJson() throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {\r
-        String json = "{\n" +\r
-                "  \"id\": \"fda38648c553386c56b2f1276b908061b5d812341f0a96921abad8b2b2f28044\",\n" +\r
-                "  \"amount\": 1700000,\n" +\r
-                "  \"address\": \"tm1qhw9q89exmudkf9ecaxtnmv22fd8af0k07jq7u5\",\n" +\r
-                "  \"program\": \"0014bb8a039726df1b649738e9973db14a4b4fd4becf\",\n" +\r
-                "  \"change\": true,\n" +\r
-                "  \"highest\": 139744,\n" +\r
-                "  \"account_alias\": \"wyjbtm\",\n" +\r
-                "  \"asset_id\": \"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\",\n" +\r
-                "  \"asset_alias\": \"BTM\",\n" +\r
-                "  \"account_id\": \"0NNSS39M00A02\",\n" +\r
-                "  \"control_program_index\": 26,\n" +\r
-                "  \"source_id\": \"34bc595dff3d40c2bd644e0ea0234e843ef8e3aa0720013a2cb712362cc5933f\",\n" +\r
-                "  \"source_pos\": 0,\n" +\r
-                "  \"valid_height\": 0,\n" +\r
-                "  \"derive_rule\": 0\n" +\r
-                "}";\r
-\r
-        UTXO utxo = UTXO.fromJson(json);\r
-        System.out.println(utxo.toJson());\r
-    }\r
-\r
-\r
-}\r