OSDN Git Service

refactor
[bytom/bytom-java-sdk.git] / tx-signer / src / main / java / io / bytom / api / SignTransaction.java
diff --git a/tx-signer/src/main/java/io/bytom/api/SignTransaction.java b/tx-signer/src/main/java/io/bytom/api/SignTransaction.java
deleted file mode 100755 (executable)
index 2cde88d..0000000
+++ /dev/null
@@ -1,310 +0,0 @@
-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 io.bytom.common.Utils;\r
-import org.bouncycastle.jcajce.provider.digest.SHA3;\r
-import org.bouncycastle.util.encoders.Hex;\r
-\r
-import java.io.ByteArrayOutputStream;\r
-import java.io.IOException;\r
-import java.math.BigInteger;\r
-import java.security.InvalidKeyException;\r
-import java.security.NoSuchAlgorithmException;\r
-import java.security.SignatureException;\r
-\r
-\r
-/**\r
- * 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
-        ByteArrayOutputStream stream = new ByteArrayOutputStream();\r
-        try {\r
-            stream.write(7);\r
-            // version\r
-            if (null != tx.version)\r
-                Utils.writeVarint(tx.version, stream);\r
-            if (null != tx.timeRange)\r
-                Utils.writeVarint(tx.timeRange, stream);\r
-            //inputs\r
-            if (null != tx.inputs && tx.inputs.size() > 0) {\r
-                Utils.writeVarint(tx.inputs.size(), stream);\r
-                for (Transaction.AnnotatedInput input : tx.inputs) {\r
-                    if (input.type == 1) {\r
-                        //assertVersion\r
-                        Utils.writeVarint(tx.version, stream); //AssetVersion是否默认为1\r
-\r
-                        //inputCommitment\r
-                        ByteArrayOutputStream inputCommitStream = new ByteArrayOutputStream();\r
-                        //spend type flag\r
-                        Utils.writeVarint(input.type, inputCommitStream);\r
-                        //spendCommitment\r
-                        ByteArrayOutputStream spendCommitSteam = new ByteArrayOutputStream();\r
-                        spendCommitSteam.write(Hex.decode(input.sourceId)); //计算muxID\r
-                        spendCommitSteam.write(Hex.decode(input.assetId));\r
-                        Utils.writeVarint(input.amount, spendCommitSteam);\r
-                        //sourcePosition\r
-                        Utils.writeVarint(input.sourcePosition, spendCommitSteam); //db中获取position\r
-                        //vmVersion\r
-                        Utils.writeVarint(1, spendCommitSteam); //db中获取vm_version\r
-                        //controlProgram\r
-                        Utils.writeVarStr(Hex.decode(input.controlProgram), spendCommitSteam);\r
-\r
-                        byte[] dataSpendCommit = spendCommitSteam.toByteArray();\r
-\r
-                        Utils.writeVarint(dataSpendCommit.length, inputCommitStream);\r
-                        inputCommitStream.write(dataSpendCommit);\r
-                        byte[] dataInputCommit = inputCommitStream.toByteArray();\r
-                        //inputCommit的length\r
-                        Utils.writeVarint(dataInputCommit.length, stream);\r
-                        stream.write(dataInputCommit);\r
-\r
-                        //inputWitness\r
-                        if (null != input.witnessComponent) {\r
-                            ByteArrayOutputStream witnessStream = new ByteArrayOutputStream();\r
-                            //arguments\r
-                            int lenSigs = input.witnessComponent.signatures.length;\r
-                            //arguments的length\r
-                            Utils.writeVarint(lenSigs, witnessStream);\r
-                            for (int i = 0; i < lenSigs; i++) {\r
-                                String sig = input.witnessComponent.signatures[i];\r
-                                Utils.writeVarStr(Hex.decode(sig), witnessStream);\r
-                            }\r
-                            byte[] dataWitnessComponets = witnessStream.toByteArray();\r
-                            //witness的length\r
-                            Utils.writeVarint(dataWitnessComponets.length, stream);\r
-                            stream.write(dataWitnessComponets);\r
-                        }\r
-                    }\r
-                    if (input.type == 0) {\r
-                        //assetVersion\r
-                        Utils.writeVarint(01, stream);\r
-                        //写入 type nonce assetId amount\r
-                        ByteArrayOutputStream issueInfo = new ByteArrayOutputStream();\r
-                        //写入 input.type==00 issue\r
-                        Utils.writeVarint(input.type, issueInfo);\r
-                        //写入 8个字节的随机数\r
-                        Utils.writeVarStr(Hex.decode(input.nonce), issueInfo);\r
-                        issueInfo.write(Hex.decode(input.assetId));\r
-                        Utils.writeVarint(input.amount, issueInfo);\r
-                        stream.write(issueInfo.toByteArray().length);\r
-                        stream.write(issueInfo.toByteArray());\r
-\r
-                        ByteArrayOutputStream issueInfo1 = new ByteArrayOutputStream();\r
-                        //未知\r
-                        Utils.writeVarint(1, issueInfo1);\r
-                        //写入assetDefine\r
-                        Utils.writeVarStr(Hex.decode(input.assetDefinition), issueInfo1);\r
-                        //vm.version\r
-                        Utils.writeVarint(1, issueInfo1);\r
-                        //controlProgram\r
-                        Utils.writeVarStr(Hex.decode(input.controlProgram), issueInfo1);\r
-\r
-                        //inputWitness\r
-                        if (null != input.witnessComponent) {\r
-                            ByteArrayOutputStream witnessStream = new ByteArrayOutputStream();\r
-                            //arguments\r
-                            int lenSigs = input.witnessComponent.signatures.length;\r
-                            //arguments的length\r
-                            Utils.writeVarint(lenSigs, witnessStream);\r
-                            for (int i = 0; i < lenSigs; i++) {\r
-                                String sig = input.witnessComponent.signatures[i];\r
-                                Utils.writeVarStr(Hex.decode(sig), witnessStream);\r
-                            }\r
-//                            byte[] dataWitnessComponets = witnessStream.toByteArray();\r
-                            //witness的length\r
-//                            Utils.writeVarint(dataWitnessComponets.length, issueInfo1);\r
-\r
-                            issueInfo1.write(witnessStream.toByteArray());\r
-                        }\r
-                        stream.write(issueInfo1.toByteArray().length - 1);\r
-                        stream.write(issueInfo1.toByteArray());\r
-\r
-                    }\r
-                }\r
-            }\r
-\r
-            //outputs\r
-            if (null != tx.outputs && tx.outputs.size() > 0) {\r
-                Utils.writeVarint(tx.outputs.size(), stream);\r
-                for (Transaction.AnnotatedOutput output : tx.outputs) {\r
-                    //assertVersion\r
-                    Utils.writeVarint(tx.version, stream); //AssetVersion是否默认为1\r
-                    //outputCommit\r
-                    ByteArrayOutputStream outputCommitSteam = new ByteArrayOutputStream();\r
-                    //assetId\r
-                    outputCommitSteam.write(Hex.decode(output.assetId));\r
-                    //amount\r
-                    Utils.writeVarint(output.amount, outputCommitSteam);\r
-                    //vmVersion\r
-                    Utils.writeVarint(1, outputCommitSteam); //db中获取vm_version\r
-                    //controlProgram\r
-                    Utils.writeVarStr(Hex.decode(output.controlProgram), outputCommitSteam);\r
-\r
-                    byte[] dataOutputCommit = outputCommitSteam.toByteArray();\r
-                    //outputCommit的length\r
-                    Utils.writeVarint(dataOutputCommit.length, stream);\r
-                    stream.write(dataOutputCommit);\r
-\r
-                    //outputWitness\r
-                    Utils.writeVarint(0, stream);\r
-                }\r
-            }\r
-\r
-            byte[] data = stream.toByteArray();\r
-            txSign = Hex.toHexString(data);\r
-\r
-        } catch (IOException e) {\r
-            throw new RuntimeException(e);\r
-        }\r
-        return txSign;\r
-    }\r
-\r
-    public Integer getTransactionSize(Transaction tx) {\r
-        String result = serializeTransaction(tx);\r
-        return Hex.decode(result).length;\r
-    }\r
-\r
-    //签名组装witness\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
-\r
-            if (null != input) {\r
-                try {\r
-                    input.witnessComponent = new Transaction.InputWitnessComponent();\r
-                    byte[] message = hashFn(Hex.decode(input.inputID), Hex.decode(transaction.txID));\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(privateKeyBytes);\r
-                            String pubKey = Hex.toHexString(deriveXpub).substring(0, 64);\r
-                            input.witnessComponent.signatures[1] = pubKey;\r
-                            break;\r
-                        }\r
-                        case 0: {\r
-                            input.witnessComponent.signatures = new String[1];\r
-                            input.witnessComponent.signatures[0] = Hex.toHexString(sig);\r
-                            break;\r
-                        }\r
-                    }\r
-\r
-                } catch (Exception e) {\r
-                    throw new RuntimeException(e);\r
-                }\r
-            } else {\r
-                System.out.println("build witness failed.");\r
-            }\r
-        return transaction;\r
-    }\r
-\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
-            input.witnessComponent = new Transaction.InputWitnessComponent();\r
-        try {\r
-\r
-            //TODO 多签issue\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
-                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(expandedPrivateKey);\r
-                String publicKey = Hex.toHexString(deriveXpub).substring(0, 64);\r
-                sb.append(Integer.toString(Hex.decode(publicKey).length,16)).append(publicKey);\r
-            }\r
-            //TODO 签名数跟公钥数量不同\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
-            throw new RuntimeException(e);\r
-        }\r
-\r
-    }\r
-\r
-    public static byte[] hashFn(byte[] hashedInputHex, byte[] txID) {\r
-\r
-        SHA3.Digest256 digest256 = new SHA3.Digest256();\r
-        // data = hashedInputHex + txID\r
-        ByteArrayOutputStream out = new ByteArrayOutputStream();\r
-        out.write(hashedInputHex, 0, hashedInputHex.length);\r
-        out.write(txID, 0, txID.length);\r
-        byte[] data = out.toByteArray();\r
-        return digest256.digest(data);\r
-    }\r
-\r
-\r
-    public Transaction generateSignatures(Transaction Transaction, BigInteger[] keys) {\r
-        Transaction.AnnotatedInput input = Transaction.inputs.get(0);\r
-        input.witnessComponent.signatures = new String[keys.length];\r
-        for (int i = 0; i < keys.length; i++) {\r
-            if (null != input) {\r
-                try {\r
-                    byte[] message = hashFn(Hex.decode(input.inputID), Hex.decode(Transaction.txID));\r
-                    byte[] expandedPrv = Utils.BigIntegerToBytes(keys[i]);\r
-                    byte[] priKey = ExpandedPrivateKey.ExpandedPrivateKey(expandedPrv);\r
-                    byte[] sig = Signer.Ed25519InnerSign(priKey, message);\r
-                    input.witnessComponent.signatures[i] = Hex.toHexString(sig);\r
-\r
-                } catch (Exception e) {\r
-                    e.printStackTrace();\r
-                }\r
-            } else {\r
-                System.out.println("generate signatures failed.");\r
-            }\r
-        }\r
-        return Transaction;\r
-    }\r
-\r
-    //根据主私钥对交易签名,生成序列化的rawTransaction\r
-    public String rawTransaction(String rootPrivateKey, Transaction tx) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {\r
-        byte[] privateChild;\r
-        for (int i = 0; i < tx.inputs.size(); i++) {\r
-            if (tx.inputs.get(i).type == 1) {\r
-                privateChild = DerivePrivateKey.derivePrivateKey(rootPrivateKey, 1, tx.inputs.get(i).isChange(), tx.inputs.get(i).getControlProgramIndex());\r
-            } else {\r
-                privateChild = DerivePrivateKey.derivePrivateKey(rootPrivateKey, tx.inputs.get(i).getKeyIndex());\r
-            }\r
-            buildWitness(tx, i, privateChild);\r
-        }\r
-        return serializeTransaction(tx);\r
-    }\r
-\r
-    //多签\r
-    public String rawTransaction(String[] rootPrivateKey, Transaction tx) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {\r
-        String privateChild;\r
-        for (int i = 0; i < tx.inputs.size(); i++) {\r
-            if (tx.inputs.get(i).controlProgram.length() != 44) {\r
-                buildWitness(tx, i, rootPrivateKey);\r
-            }\r
-\r
-        }\r
-        return serializeTransaction(tx);\r
-    }\r
-\r
-\r
-}\r
-\r
-\r