• R/O
  • HTTP
  • SSH
  • HTTPS

bytom-java-sdk: Commit

Official Java SDK for Bytom


Commit MetaInfo

Révision44fc5c26e55aefe6f5647f5d637903b060b52a92 (tree)
l'heure2021-07-13 18:42:14
Auteurdoraemon <wyjDoraemon@163....>
Commiterdoraemon

Message de Log

offine signer

Change Summary

Modification

--- a/tx-signer/src/main/java/io/bytom/offline/api/BaseInput.java
+++ b/tx-signer/src/main/java/io/bytom/offline/api/BaseInput.java
@@ -11,6 +11,8 @@ public abstract class BaseInput {
1111
1212 static final int ISSUANCE_INPUT_TYPE = 0;
1313 static final int SPEND_INPUT_TYPE = 1;
14+ static final int Coinbase_INPUT_TYPE = 2;
15+ static final int Veto_INPUT_TYPE = 3;
1416
1517 static final byte AssetKeySpace = 0;
1618 static final byte AccountKeySpace = 1;
@@ -52,7 +54,7 @@ public abstract class BaseInput {
5254
5355 public byte[] serializeInput() throws IOException {
5456 ByteArrayOutputStream stream = new ByteArrayOutputStream();
55- // assert version
57+ // asset version
5658 Utils.writeVarint(1, stream);
5759 Utils.writeExtensibleString(serializeInputCommitment(), stream);
5860 Utils.writeExtensibleString(serializeInputWitness(), stream);
@@ -133,4 +135,8 @@ public abstract class BaseInput {
133135 public void setKeyIndex(int keyIndex) {
134136 this.keyIndex = keyIndex;
135137 }
138+
139+ public void appendWitnessComponent(String witness){
140+ witnessComponent.appendWitness(witness);
141+ }
136142 }
--- /dev/null
+++ b/tx-signer/src/main/java/io/bytom/offline/api/BaseOutput.java
@@ -0,0 +1,55 @@
1+package io.bytom.offline.api;
2+
3+import io.bytom.offline.common.Utils;
4+import io.bytom.offline.types.*;
5+import org.bouncycastle.util.encoders.Hex;
6+
7+import java.io.ByteArrayOutputStream;
8+import java.io.IOException;
9+import java.util.Map;
10+
11+public abstract class BaseOutput {
12+ /**
13+ * The number of units of the asset being controlled.
14+ */
15+ private Long amount;
16+
17+ /**
18+ * The id of the asset being controlled.
19+ */
20+ private String assetId;
21+
22+ /**
23+ * The control program which must be satisfied to transfer this output.
24+ */
25+ private String controlProgram;
26+
27+ /**
28+ * The id of the output.
29+ */
30+ private String id;
31+
32+ StateData stateData = new StateData();
33+
34+ public BaseOutput() {
35+ }
36+
37+ public BaseOutput(String assetID, long amount, String controlProgram) {
38+ this.assetId = assetID;
39+ this.amount = amount;
40+ this.controlProgram = controlProgram;
41+ }
42+
43+
44+ public abstract byte[] serializeOutputCommitment() throws IOException;
45+
46+
47+ public byte[] serializeOutput() throws IOException {
48+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
49+ // asset version
50+ Utils.writeVarint(1, stream);
51+ Utils.writeExtensibleString(serializeOutputCommitment(), stream);
52+ return stream.toByteArray();
53+ }
54+
55+}
\ No newline at end of file
--- /dev/null
+++ b/tx-signer/src/main/java/io/bytom/offline/api/CoinbaseInput.java
@@ -0,0 +1,48 @@
1+package io.bytom.offline.api;
2+
3+import io.bytom.offline.common.Utils;
4+import io.bytom.offline.types.*;
5+import org.bouncycastle.util.encoders.Hex;
6+
7+import java.io.ByteArrayOutputStream;
8+import java.io.IOException;
9+import java.util.Map;
10+
11+public class CoinbaseInput extends BaseInput{
12+ private String arbitrary;
13+
14+ @Override
15+ public InputEntry toInputEntry(Map<Hash, Entry> entryMap, int index) {
16+ Coinbase coinbase = new Coinbase(arbitrary);
17+
18+ Hash prevOutID = coinbase.entryID();
19+ entryMap.put(prevOutID, coinbase);
20+ return new Coinbase(prevOutID,index);
21+ }
22+
23+ @Override
24+ public void buildWitness(String txID) throws Exception {
25+
26+ }
27+
28+ @Override
29+ public byte[] serializeInputCommitment() throws IOException {
30+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
31+ Utils.writeVarint(Coinbase_INPUT_TYPE, stream);
32+ Utils.writeVarStr(Hex.decode(this.arbitrary),stream);
33+ return stream.toByteArray();
34+ }
35+
36+ @Override
37+ public byte[] serializeInputWitness() throws IOException {
38+ return new byte[0];
39+ }
40+
41+ public String getArbitrary() {
42+ return arbitrary;
43+ }
44+
45+ public void setArbitrary(String arbitrary) {
46+ this.arbitrary = arbitrary;
47+ }
48+}
--- a/tx-signer/src/main/java/io/bytom/offline/api/IssuanceInput.java
+++ b/tx-signer/src/main/java/io/bytom/offline/api/IssuanceInput.java
@@ -5,6 +5,7 @@ import io.bytom.offline.common.ExpandedPrivateKey;
55 import io.bytom.offline.common.Signer;
66 import io.bytom.offline.common.Utils;
77 import io.bytom.offline.types.*;
8+import io.bytom.offline.util.AssetIdUtil;
89 import io.bytom.offline.util.SHA3Util;
910 import org.bouncycastle.util.encoders.Hex;
1011 import java.io.ByteArrayOutputStream;
@@ -18,7 +19,15 @@ public class IssuanceInput extends BaseInput {
1819
1920 private String rawAssetDefinition;
2021
21- public IssuanceInput() {}
22+ public IssuanceInput(){
23+
24+ }
25+
26+ public IssuanceInput(String rawAssetDefinition,String issuanceProgram) {
27+ this.rawAssetDefinition = rawAssetDefinition;
28+ this.setProgram(issuanceProgram);
29+ this.setAssetId(AssetIdUtil.computeAssetID(rawAssetDefinition,issuanceProgram));
30+ }
2231
2332 public IssuanceInput(String assetID, Long amount, String issuanceProgram) {
2433 this.setAssetId(assetID);
@@ -66,7 +75,10 @@ public class IssuanceInput extends BaseInput {
6675 ByteArrayOutputStream stream = new ByteArrayOutputStream();
6776 Utils.writeVarint(ISSUANCE_INPUT_TYPE, stream);
6877 Utils.writeVarStr(Hex.decode(nonce), stream);
69- stream.write(Hex.decode(getAssetId()));
78+ if (this.getAssetId()==null){
79+ this.setAssetId(AssetIdUtil.computeAssetID(rawAssetDefinition,this.getProgram()));
80+ }
81+ stream.write(Hex.decode(this.getAssetId()));
7082 Utils.writeVarint(getAmount(), stream);
7183 return stream.toByteArray();
7284 }
@@ -84,13 +96,16 @@ public class IssuanceInput extends BaseInput {
8496
8597 @Override
8698 public void validate() {
87- super.validate();
8899 if (nonce == null) {
89100 throw new IllegalArgumentException("the nonce of issuance input must be specified.");
90101 }
91102 if (rawAssetDefinition == null) {
92103 throw new IllegalArgumentException("the nonce of issuance input must be specified.");
93104 }
105+
106+ if (this.getProgram() == null) {
107+ throw new IllegalArgumentException("the program of issuance must be specified.");
108+ }
94109 }
95110
96111 public String getNonce() {
--- a/tx-signer/src/main/java/io/bytom/offline/api/Output.java
+++ b/tx-signer/src/main/java/io/bytom/offline/api/OriginalOutput.java
@@ -2,12 +2,12 @@ package io.bytom.offline.api;
22
33 import io.bytom.offline.common.Utils;
44 import io.bytom.offline.common.VMUtil;
5+import io.bytom.offline.util.AssetIdUtil;
56 import org.bouncycastle.util.encoders.Hex;
67 import java.io.ByteArrayOutputStream;
78 import java.io.IOException;
89
9-public class Output {
10-
10+public class OriginalOutput {
1111 /**
1212 * The number of units of the asset being controlled.
1313 */
@@ -28,27 +28,28 @@ public class Output {
2828 */
2929 private String id;
3030
31- /**
32- * The output's position in a transaction's list of outputs.
33- */
34- private Integer position;
31+ StateData stateData = new StateData();
32+
33+ public OriginalOutput() {
34+ }
3535
36- public Output(String assetID, long amount, String controlProgram) {
36+ public OriginalOutput(String assetID, long amount, String controlProgram) {
3737 this.assetId = assetID;
3838 this.amount = amount;
3939 this.controlProgram = controlProgram;
4040 }
4141
42- public static Output newRetireOutput(String assetID, long amount, String arbitrary) {
43- String retireProgram = Hex.toHexString(new byte[]{VMUtil.OP_FAIL}) + Hex.toHexString(VMUtil.pushDataBytes(Hex.decode(arbitrary)));
44- return new Output(assetID, amount, retireProgram);
42+ public OriginalOutput(String rawAssetDefinition,String program) {
43+ this.assetId = AssetIdUtil.computeAssetID(rawAssetDefinition,program);
44+ this.controlProgram = program;
4545 }
4646
4747 public byte[] serializeOutput() throws IOException {
4848 ByteArrayOutputStream stream = new ByteArrayOutputStream();
49-
50- //assetVersion
51- Utils.writeVarint(1, stream); //AssetVersion是否默认为1
49+ // asset version
50+ Utils.writeVarint(1, stream);
51+ //outputType
52+ Utils.writeVarint(0, stream); //outputType
5253 //outputCommit
5354 ByteArrayOutputStream outputCommitSteam = new ByteArrayOutputStream();
5455 //assetId
@@ -59,6 +60,8 @@ public class Output {
5960 Utils.writeVarint(1, outputCommitSteam); //db中获取vm_version
6061 //controlProgram
6162 Utils.writeVarStr(Hex.decode(controlProgram), outputCommitSteam);
63+ //stateData
64+ Utils.writeVarList(this.stateData.toByteArray(), outputCommitSteam);
6265
6366 Utils.writeExtensibleString(outputCommitSteam.toByteArray(), stream);
6467
@@ -67,6 +70,7 @@ public class Output {
6770 return stream.toByteArray();
6871 }
6972
73+
7074 public Long getAmount() {
7175 return amount;
7276 }
@@ -99,11 +103,7 @@ public class Output {
99103 this.id = id;
100104 }
101105
102- public Integer getPosition() {
103- return position;
104- }
105-
106- public void setPosition(Integer position) {
107- this.position = position;
106+ public void appendStateData(String stateDataStr){
107+ stateData.appendStateData(stateDataStr);
108108 }
109109 }
--- a/tx-signer/src/main/java/io/bytom/offline/api/SpendInput.java
+++ b/tx-signer/src/main/java/io/bytom/offline/api/SpendInput.java
@@ -19,6 +19,8 @@ public class SpendInput extends BaseInput {
1919
2020 private BIPProtocol bipProtocol = BIPProtocol.BIP44;
2121
22+ StateData stateData = new StateData();
23+
2224 public SpendInput() {}
2325
2426 public SpendInput(String assetID, long amount, String controlProgram) {
@@ -40,7 +42,7 @@ public class SpendInput extends BaseInput {
4042 Hash sourceID = new Hash(this.sourceID);
4143 ValueSource src = new ValueSource(sourceID, assetAmount, this.sourcePosition);
4244
43- OutputEntry prevOut = new OutputEntry(src, pro, 0);
45+ Output prevOut = new Output(src, pro, 0,stateData.toByteArray());
4446 Hash prevOutID = prevOut.entryID();
4547 entryMap.put(prevOutID, prevOut);
4648 return new Spend(prevOutID, index);
@@ -82,6 +84,7 @@ public class SpendInput extends BaseInput {
8284 // vm version
8385 Utils.writeVarint(1, spendCommitSteam);
8486 Utils.writeVarStr(Hex.decode(getProgram()), spendCommitSteam);
87+ Utils.writeVarList(stateData.toByteArray(), spendCommitSteam);
8588 Utils.writeExtensibleString(spendCommitSteam.toByteArray(), stream);
8689 return stream.toByteArray();
8790 }
@@ -129,4 +132,8 @@ public class SpendInput extends BaseInput {
129132 public void setBipProtocol(BIPProtocol bipProtocol) {
130133 this.bipProtocol = bipProtocol;
131134 }
135+
136+ public void appendStateData(String stateDataStr){
137+ stateData.appendStateData(stateDataStr);
138+ }
132139 }
\ No newline at end of file
--- /dev/null
+++ b/tx-signer/src/main/java/io/bytom/offline/api/StateData.java
@@ -0,0 +1,26 @@
1+package io.bytom.offline.api;
2+
3+import org.bouncycastle.util.encoders.Hex;
4+
5+import java.util.ArrayList;
6+import java.util.List;
7+
8+public class StateData {
9+ private List<String> stateData;
10+
11+ public StateData() {
12+ stateData = new ArrayList<>();
13+ }
14+
15+ public byte[][] toByteArray() {
16+ byte[][] byteArray = new byte[stateData.size()][];
17+ for (int i = 0; i < stateData.size(); i++) {
18+ byteArray[i] = Hex.decode(stateData.get(i));
19+ }
20+ return byteArray;
21+ }
22+
23+ public void appendStateData(String stateDataStr) {
24+ stateData.add(stateDataStr);
25+ }
26+}
--- a/tx-signer/src/main/java/io/bytom/offline/api/Transaction.java
+++ b/tx-signer/src/main/java/io/bytom/offline/api/Transaction.java
@@ -41,7 +41,7 @@ public class Transaction {
4141 /**
4242 * List of specified outputs for a transaction.
4343 */
44- private List<Output> outputs;
44+ private List<OriginalOutput> outputs;
4545
4646 public Transaction(Builder builder) {
4747 this.inputs = builder.inputs;
@@ -64,7 +64,7 @@ public class Transaction {
6464 private Integer timeRange;
6565
6666 private List<BaseInput> inputs;
67- private List<Output> outputs;
67+ private List<OriginalOutput> outputs;
6868
6969 public Builder() {
7070 this.inputs = new ArrayList<>();
@@ -76,7 +76,7 @@ public class Transaction {
7676 return this;
7777 }
7878
79- public Builder addOutput(Output output) {
79+ public Builder addOutput(OriginalOutput output) {
8080 this.outputs.add(output);
8181 return this;
8282 }
@@ -86,12 +86,17 @@ public class Transaction {
8686 return this;
8787 }
8888
89+ public Builder setSize(int size) {
90+ this.size = size;
91+ return this;
92+ }
93+
8994 public Transaction build() {
9095 return new Transaction(this);
9196 }
9297 }
9398
94- private void sign() {
99+ public void sign() {
95100 for (BaseInput input : inputs) {
96101 try {
97102 input.buildWitness(txID);
@@ -117,7 +122,7 @@ public class Transaction {
117122 }
118123
119124 Utils.writeVarint(outputs.size(), stream);
120- for (Output output : outputs) {
125+ for (OriginalOutput output : outputs) {
121126 stream.write(output.serializeOutput());
122127 }
123128 } catch (IOException e) {
@@ -167,7 +172,7 @@ public class Transaction {
167172
168173 List<Hash> resultIDList = new ArrayList<>();
169174 for (int i = 0; i < outputs.size(); i++) {
170- Output output = outputs.get(i);
175+ OriginalOutput output = outputs.get(i);
171176
172177 AssetAmount amount = new AssetAmount(new AssetID(output.getAssetId()), output.getAmount());
173178 ValueSource src = new ValueSource(muxID, amount, i);
@@ -178,7 +183,7 @@ public class Transaction {
178183 resultID = addEntry(entryMap, retirement);
179184 } else {
180185 Program program = new Program(1, Hex.decode(output.getControlProgram()));
181- OutputEntry oup = new OutputEntry(src, program, i);
186+ Output oup = new Output(src, program, i,output.stateData.toByteArray());
182187 resultID = addEntry(entryMap, oup);
183188 }
184189
@@ -225,7 +230,7 @@ public class Transaction {
225230 return inputs;
226231 }
227232
228- public List<Output> getOutputs() {
233+ public List<OriginalOutput> getOutputs() {
229234 return outputs;
230235 }
231236 }
--- /dev/null
+++ b/tx-signer/src/main/java/io/bytom/offline/api/VetoInput.java
@@ -0,0 +1,108 @@
1+package io.bytom.offline.api;
2+
3+import io.bytom.offline.common.Utils;
4+import io.bytom.offline.types.*;
5+import org.bouncycastle.util.encoders.Hex;
6+
7+import java.io.ByteArrayOutputStream;
8+import java.io.IOException;
9+import java.util.Map;
10+
11+public class VetoInput extends BaseInput{
12+ private String sourceID;
13+
14+ private Integer sourcePosition;
15+
16+ private Boolean change;
17+
18+ private Integer controlProgramIndex;
19+
20+ private byte[] vote;
21+
22+ StateData stateData = new StateData();
23+
24+ @Override
25+ public InputEntry toInputEntry(Map<Hash, Entry> entryMap, int index) {
26+ Program pro = new Program(this.getVmVersion(), Hex.decode(this.getProgram()));
27+ AssetAmount assetAmount = this.getAssetAmount();
28+ Hash sourceID = new Hash(this.sourceID);
29+ ValueSource src = new ValueSource(sourceID, assetAmount, this.sourcePosition);
30+
31+ Vote prevOut = new Vote(src, pro, 0,this.vote,stateData.toByteArray());
32+ Hash prevOutID = prevOut.entryID();
33+ entryMap.put(prevOutID, prevOut);
34+ return new Veto(prevOutID, index);
35+ }
36+
37+ @Override
38+ public void buildWitness(String txID) throws Exception {
39+
40+ }
41+
42+ @Override
43+ public byte[] serializeInputCommitment() throws IOException {
44+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
45+ Utils.writeVarint(Veto_INPUT_TYPE, stream);
46+
47+ ByteArrayOutputStream spendCommitSteam = new ByteArrayOutputStream();
48+ spendCommitSteam.write(Hex.decode(sourceID));
49+ spendCommitSteam.write(Hex.decode(getAssetId()));
50+ Utils.writeVarint(getAmount(), spendCommitSteam);
51+ Utils.writeVarint(sourcePosition, spendCommitSteam);
52+ // vm version
53+ Utils.writeVarint(1, spendCommitSteam);
54+ Utils.writeVarStr(Hex.decode(getProgram()), spendCommitSteam);
55+ Utils.writeVarList(stateData.toByteArray(), spendCommitSteam);
56+ Utils.writeExtensibleString(spendCommitSteam.toByteArray(), stream);
57+ Utils.writeVarStr(this.vote,stream);
58+ return stream.toByteArray();
59+ }
60+
61+ @Override
62+ public byte[] serializeInputWitness() throws IOException {
63+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
64+ Utils.writeVarList(witnessComponent.toByteArray(), stream);
65+ return stream.toByteArray();
66+ }
67+
68+ public String getSourceID() {
69+ return sourceID;
70+ }
71+
72+ public void setSourceID(String sourceID) {
73+ this.sourceID = sourceID;
74+ }
75+
76+ public Integer getSourcePosition() {
77+ return sourcePosition;
78+ }
79+
80+ public void setSourcePosition(Integer sourcePosition) {
81+ this.sourcePosition = sourcePosition;
82+ }
83+
84+ public Boolean getChange() {
85+ return change;
86+ }
87+
88+ public void setChange(Boolean change) {
89+ this.change = change;
90+ }
91+
92+ public Integer getControlProgramIndex() {
93+ return controlProgramIndex;
94+ }
95+
96+ public void setControlProgramIndex(Integer controlProgramIndex) {
97+ this.controlProgramIndex = controlProgramIndex;
98+ }
99+
100+ public byte[] getVote() {
101+ return vote;
102+ }
103+
104+ public void setVote(byte[] vote) {
105+ this.vote = vote;
106+ }
107+
108+}
--- /dev/null
+++ b/tx-signer/src/main/java/io/bytom/offline/types/Coinbase.java
@@ -0,0 +1,50 @@
1+package io.bytom.offline.types;
2+
3+import java.io.ByteArrayOutputStream;
4+import java.util.Map;
5+
6+public class Coinbase extends InputEntry{
7+ private Hash coinbaseOutputID;
8+
9+ private int ordinal;
10+
11+ private ValueDestination witnessDestination;
12+
13+ private String arbitrary;
14+
15+ public Coinbase(Hash coinbaseOutputID, int ordinal) {
16+ this.coinbaseOutputID = coinbaseOutputID;
17+ this.ordinal = ordinal;
18+ }
19+
20+ public Coinbase(String arbitrary) {
21+ this.arbitrary = arbitrary;
22+ }
23+
24+
25+ @Override
26+ public String typ() {
27+ return "coinbase1";
28+ }
29+
30+ @Override
31+ public void writeForHash(ByteArrayOutputStream out) {
32+ System.out.println("write for hash");
33+ System.out.println(this.arbitrary);
34+ mustWriteForHash(out,this.arbitrary);
35+ }
36+
37+ @Override
38+ public void setDestination(Hash id, long pos, Map<Hash, Entry> entryMap) {
39+// OutputEntry spendOutput = (OutputEntry) entryMap.get(this.coinbaseOutputID);
40+// this.witnessDestination = new ValueDestination(id, spendOutput.getSource().getValue(), pos);
41+ }
42+
43+ public String getArbitrary() {
44+ return arbitrary;
45+ }
46+
47+ public void setArbitrary(String arbitrary) {
48+ this.arbitrary = arbitrary;
49+ }
50+}
--- /dev/null
+++ b/tx-signer/src/main/java/io/bytom/offline/types/Output.java
@@ -0,0 +1,30 @@
1+package io.bytom.offline.types;
2+
3+import java.io.ByteArrayOutputStream;
4+
5+public class Output extends OutputEntry {
6+ public Output() {
7+ this.source = new ValueSource();
8+ this.controlProgram = new Program();
9+ }
10+
11+
12+ public Output(ValueSource source, Program controlProgram, Integer ordinal, byte[][] stateData) {
13+ this.source = source;
14+ this.controlProgram = controlProgram;
15+ this.ordinal = ordinal;
16+ this.stateData = stateData;
17+ }
18+
19+ @Override
20+ public String typ() {
21+ return "originalOutput1";
22+ }
23+
24+ @Override
25+ public void writeForHash(ByteArrayOutputStream out) {
26+ mustWriteForHash(out, this.source);
27+ mustWriteForHash(out, this.controlProgram);
28+ mustWriteForHash(out, this.stateData);
29+ }
30+}
--- a/tx-signer/src/main/java/io/bytom/offline/types/OutputEntry.java
+++ b/tx-signer/src/main/java/io/bytom/offline/types/OutputEntry.java
@@ -2,36 +2,15 @@ package io.bytom.offline.types;
22
33 import java.io.ByteArrayOutputStream;
44
5-public class OutputEntry extends Entry {
5+public abstract class OutputEntry extends Entry {
6+ protected ValueSource source;
67
7- private ValueSource source;
8+ protected Program controlProgram;
89
9- private Program controlProgram;
10+ protected Integer ordinal;
1011
11- private Integer ordinal;
12+ protected byte[][] stateData;
1213
13- public OutputEntry() {
14- this.source = new ValueSource();
15- this.controlProgram = new Program();
16- }
17-
18-
19- public OutputEntry(ValueSource source, Program controlProgram, Integer ordinal) {
20- this.source = source;
21- this.controlProgram = controlProgram;
22- this.ordinal = ordinal;
23- }
24-
25- @Override
26- public String typ() {
27- return "output1";
28- }
29-
30- @Override
31- public void writeForHash(ByteArrayOutputStream out) {
32- mustWriteForHash(out, this.source);
33- mustWriteForHash(out, this.controlProgram);
34- }
3514
3615 public ValueSource getSource() {
3716 return source;
--- a/tx-signer/src/main/java/io/bytom/offline/types/ValueSource.java
+++ b/tx-signer/src/main/java/io/bytom/offline/types/ValueSource.java
@@ -11,12 +11,18 @@ public class ValueSource {
1111
1212 public ValueSource() {}
1313
14+ public ValueSource(Hash ref, AssetAmount value) {
15+ this.ref = ref;
16+ this.value = value;
17+ }
18+
1419 public ValueSource(Hash ref, AssetAmount value, long position) {
1520 this.ref = ref;
1621 this.value = value;
1722 this.position = position;
1823 }
1924
25+
2026 public Hash getRef() {
2127 return ref;
2228 }
--- /dev/null
+++ b/tx-signer/src/main/java/io/bytom/offline/types/Veto.java
@@ -0,0 +1,31 @@
1+package io.bytom.offline.types;
2+
3+import java.io.ByteArrayOutputStream;
4+import java.util.Map;
5+
6+public class Veto extends InputEntry{
7+ private Hash spentOutputID;
8+ private ValueDestination witnessDestination;
9+
10+
11+ public Veto(Hash spentOutputID, int ordinal) {
12+ this.spentOutputID = spentOutputID;
13+ this.ordinal = ordinal;
14+ }
15+
16+ @Override
17+ public String typ() {
18+ return "vetoInput1";
19+ }
20+
21+ @Override
22+ public void writeForHash(ByteArrayOutputStream out) {
23+ mustWriteForHash(out,this.spentOutputID);
24+ }
25+
26+ @Override
27+ public void setDestination(Hash id, long pos, Map<Hash, Entry> entryMap) {
28+ OutputEntry spendOutput = (OutputEntry) entryMap.get(this.spentOutputID);
29+ this.witnessDestination = new ValueDestination(id, spendOutput.getSource().getValue(), pos);
30+ }
31+}
--- /dev/null
+++ b/tx-signer/src/main/java/io/bytom/offline/types/Vote.java
@@ -0,0 +1,37 @@
1+package io.bytom.offline.types;
2+
3+import java.io.ByteArrayOutputStream;
4+
5+public class Vote extends OutputEntry{
6+ private byte[] vote;
7+
8+ public Vote(ValueSource source, Program controlProgram, Integer ordinal,byte[] vote, byte[][] stateData) {
9+ this.source = source;
10+ this.controlProgram = controlProgram;
11+ this.ordinal = ordinal;
12+ this.vote = vote;
13+ this.stateData = stateData;
14+ }
15+
16+ @Override
17+ public String typ() {
18+ return "voteOutput1";
19+ }
20+
21+ @Override
22+ public void writeForHash(ByteArrayOutputStream out) {
23+ mustWriteForHash(out,this.source);
24+ mustWriteForHash(out,this.controlProgram);
25+ mustWriteForHash(out,this.vote);
26+ mustWriteForHash(out,this.stateData);
27+ }
28+
29+ public byte[] getVote() {
30+ return vote;
31+ }
32+
33+ public void setVote(byte[] vote) {
34+ this.vote = vote;
35+ }
36+
37+}
--- /dev/null
+++ b/tx-signer/src/main/java/io/bytom/offline/util/AssetIdUtil.java
@@ -0,0 +1,20 @@
1+package io.bytom.offline.util;
2+
3+import io.bytom.offline.types.AssetDefinition;
4+import io.bytom.offline.types.Hash;
5+import io.bytom.offline.types.Program;
6+import org.bouncycastle.util.encoders.Hex;
7+
8+import java.io.ByteArrayOutputStream;
9+
10+public class AssetIdUtil {
11+ public static String computeAssetID(String rawAssetDefinition,String controlProgram){
12+ byte[] hashBytes = SHA3Util.hashSha256(Hex.decode(rawAssetDefinition));
13+ Hash assetDefHash = new Hash(hashBytes);
14+ Program program = new Program(1,Hex.decode(controlProgram));
15+ AssetDefinition assetDefinition = new AssetDefinition(assetDefHash, program);
16+ ByteArrayOutputStream out = new ByteArrayOutputStream();
17+ assetDefinition.writeForHash(out);
18+ return Hex.toHexString(SHA3Util.hashSha256(out.toByteArray()));
19+ }
20+}
--- a/tx-signer/src/test/java/io/bytom/offline/api/AppTest.java
+++ /dev/null
@@ -1,128 +0,0 @@
1-package io.bytom.offline.api;
2-
3-import org.junit.Test;
4-
5-public class AppTest {
6- String rootKey = "38d2c44314c401b3ea7c23c54e12c36a527aee46a7f26b82443a46bf40583e439dea25de09b0018b35a741d8cd9f6ec06bc11db49762617485f5309ab72a12d4";
7- String btmAssetID = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
8-
9-
10- @Test
11- public void testSpendBIP44() {
12- SpendInput input = new SpendInput();
13- input.setAssetId(btmAssetID);
14- input.setAmount(9800000000L);
15- input.setProgram("0014cb9f2391bafe2bc1159b2c4c8a0f17ba1b4dd94e");
16- input.setSourcePosition(2);
17- input.setSourceID("4b5cb973f5bef4eadde4c89b92ee73312b940e84164da0594149554cc8a2adea");
18- input.setChange(true);
19- input.setControlProgramIndex(457);
20- input.setKeyIndex(1);
21- input.setRootPrivateKey("4864bae85cf38bfbb347684abdbc01e311a24f99e2c7fe94f3c071d9c83d8a5a349722316972e382c339b79b7e1d83a565c6b3e7cf46847733a47044ae493257");
22-
23- Transaction tx = new Transaction.Builder()
24- .addInput(input)
25- .addOutput(new Output(btmAssetID, 8800000000L, "0014a82f02bc37bc5ed87d5f9fca02f8a6a7d89cdd5c"))
26- .addOutput(new Output(btmAssetID, 900000000L, "00200824e931fb806bd77fdcd291aad3bd0a4493443a4120062bd659e64a3e0bac66"))
27- .setTimeRange(0)
28- .build();
29-
30- String rawTransaction = tx.rawTransaction();
31- assert rawTransaction.equals("070100010160015e4b5cb973f5bef4eadde4c89b92ee73312b940e84164da0594149554cc8a2adeaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80c480c1240201160014cb9f2391bafe2bc1159b2c4c8a0f17ba1b4dd94e6302401cb779288be890a28c5209036da1a27d9fe74a51c38e0a10db4817bcf4fd05f68580239eea7dcabf19f144c77bf13d3674b5139aa51a99ba58118386c190af0e20bcbe020b05e1b7d0825953d92bf47897be08cd7751a37adb95d6a2e5224f55ab02013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80b095e42001160014a82f02bc37bc5ed87d5f9fca02f8a6a7d89cdd5c000149ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80d293ad03012200200824e931fb806bd77fdcd291aad3bd0a4493443a4120062bd659e64a3e0bac6600");
32- }
33-
34- @Test
35- public void testSpendBIP32() {
36- SpendInput input = new SpendInput(btmAssetID, 11718900000L, "0014085a02ecdf934a56343aa59a3dec9d9feb86ee43");
37- input.setSourceID("5ac79a73db78e5c9215b37cb752f0147d1157c542bb4884908ceb97abc33fe0a");
38- input.setSourcePosition(0);
39- input.setRootPrivateKey("4864bae85cf38bfbb347684abdbc01e311a24f99e2c7fe94f3c071d9c83d8a5a349722316972e382c339b79b7e1d83a565c6b3e7cf46847733a47044ae493257");
40- input.setChange(true);
41- input.setKeyIndex(1);
42- input.setBipProtocol(BIPProtocol.BIP32);
43- input.setControlProgramIndex(447);
44-
45- Transaction tx = new Transaction.Builder()
46- .addInput(input)
47- .addOutput(new Output(btmAssetID, 1718900000L, "001409a0961e9b592a944ca3ded0ef9403fdb25b3793"))
48- .addOutput(new Output(btmAssetID, 9900000000L, "00145ade29df622cc68d0473aa1a20fb89690451c66e"))
49- .setTimeRange(0)
50- .build();
51-
52- String rawTx = tx.rawTransaction();
53- assert rawTx.equals("070100010160015e5ac79a73db78e5c9215b37cb752f0147d1157c542bb4884908ceb97abc33fe0affffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0f280d42b0001160014085a02ecdf934a56343aa59a3dec9d9feb86ee43630240e37864ef905e943deb97e58b861c97f04f07c1d33b1ce4f1b6edddff0c8956a57d86fc922c45446cd38ea613fc3c9b7d5a2596f3dca7a7212f6da55b9515110420a29601468f08c57ca9c383d28736a9d5c7737cd483126d8db3d85490fe497b3502013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0aad1b3060116001409a0961e9b592a944ca3ded0ef9403fdb25b379300013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8086d8f024011600145ade29df622cc68d0473aa1a20fb89690451c66e00");
54- }
55-
56- //issue asset
57- @Test
58- public void testIssue() {
59- IssuanceInput issuanceInput = new IssuanceInput();
60- issuanceInput.setAssetId("7b38dc897329a288ea31031724f5c55bcafec80468a546955023380af2faad14");
61- issuanceInput.setAmount(100000000000L);
62- issuanceInput.setProgram("ae2054a71277cc162eb3eb21b5bd9fe54402829a53b294deaed91692a2cd8a081f9c5151ad");
63- issuanceInput.setNonce("ac9d5a527f5ab00a");
64- issuanceInput.setKeyIndex(5);
65- issuanceInput.setRawAssetDefinition("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d");
66- issuanceInput.setRootPrivateKey("4864bae85cf38bfbb347684abdbc01e311a24f99e2c7fe94f3c071d9c83d8a5a349722316972e382c339b79b7e1d83a565c6b3e7cf46847733a47044ae493257");
67-
68- SpendInput spendInput = new SpendInput(btmAssetID, 9800000000L, "0014cb9f2391bafe2bc1159b2c4c8a0f17ba1b4dd94e");
69- spendInput.setBipProtocol(BIPProtocol.BIP32);
70- spendInput.setKeyIndex(1);
71- spendInput.setChange(true);
72- spendInput.setSourceID("4b5cb973f5bef4eadde4c89b92ee73312b940e84164da0594149554cc8a2adea");
73- spendInput.setSourcePosition(2);
74- spendInput.setControlProgramIndex(457);
75- spendInput.setRootPrivateKey("4864bae85cf38bfbb347684abdbc01e311a24f99e2c7fe94f3c071d9c83d8a5a349722316972e382c339b79b7e1d83a565c6b3e7cf46847733a47044ae493257");
76-
77- Transaction tx = new Transaction.Builder()
78- .addInput(issuanceInput)
79- .addInput(spendInput)
80- .addOutput(new Output("7b38dc897329a288ea31031724f5c55bcafec80468a546955023380af2faad14", 100000000000L, "001437e1aec83a4e6587ca9609e4e5aa728db7007449"))
81- .addOutput(new Output(btmAssetID, 9700000000L, "00148be1104e04734e5edaba5eea2e85793896b77c56"))
82- .setTimeRange(0)
83- .build();
84-
85- String rawTx = tx.rawTransaction();
86- assert rawTx.equals("0701000201300008ac9d5a527f5ab00a7b38dc897329a288ea31031724f5c55bcafec80468a546955023380af2faad1480d0dbc3f402b001467b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d0125ae2054a71277cc162eb3eb21b5bd9fe54402829a53b294deaed91692a2cd8a081f9c5151ad01401ba3a3f2d3e9887e20da8d43666cc1602bb5421ffea9d2b4d7df9816fc174a43b25fb00db4775b10b679a8b5f8aa28555ebb8fb49f6275d43283daf8f5ac340d0160015e4b5cb973f5bef4eadde4c89b92ee73312b940e84164da0594149554cc8a2adeaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80c480c1240201160014cb9f2391bafe2bc1159b2c4c8a0f17ba1b4dd94e630240341c875fc815dc13ad811c9aa7c7af28a5c78765f77fd5a36dac263278fd605ae0553e34a1e645148370b7b397142ddbcd67ba33483279ab9894169b51e4f101201381d35e235813ad1e62f9a602c82abee90565639cc4573568206b55bcd2aed902013e7b38dc897329a288ea31031724f5c55bcafec80468a546955023380af2faad1480d0dbc3f4020116001437e1aec83a4e6587ca9609e4e5aa728db700744900013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8082a99124011600148be1104e04734e5edaba5eea2e85793896b77c5600");
87- }
88-
89-
90- //retire asset
91- @Test
92- public void testRetire() {
93- String arbitrary = "77656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c";
94- String assetId1 = "207265909236260b30942a6b00e30ceb769e0e58156b6482bac64117619c9dcf";
95-
96- SpendInput input1 = new SpendInput(btmAssetID, 289100000L, "0014f1dc52048f439ac7fd74f8106a21da78f00de48f");
97- input1.setRootPrivateKey(rootKey);
98- input1.setChange(true);
99- input1.setControlProgramIndex(41);
100- input1.setSourceID("0b2cff11d1d056d95237a5f2d06059e5395e86f60e69c1e8201ea624911c0c65");
101- input1.setKeyIndex(1);
102- input1.setSourcePosition(0);
103-
104- SpendInput input2 = new SpendInput(assetId1, 70000000000L, "0014bb8a039726df1b649738e9973db14a4b4fd4becf");
105- input2.setRootPrivateKey(rootKey);
106- input2.setChange(true);
107- input2.setControlProgramIndex(26);
108- input2.setSourceID("be0ac837e832c34a02968e54dab4f95cbeceb9fb01cd378310f6ea32219ee29b");
109- input2.setKeyIndex(1);
110- input2.setSourcePosition(1);
111-
112- Output output1 = new Output(btmAssetID, 279100000L, "001414d362694eacfa110dc20dec77d610d22340f95b");
113- Output output2 = Output.newRetireOutput(assetId1, 10000000000L, arbitrary);
114- Output output3 = new Output(assetId1, 60000000000L, "0014bb8a039726df1b649738e9973db14a4b4fd4becf");
115-
116- Transaction transaction = new Transaction.Builder()
117- .addInput(input1)
118- .addInput(input2)
119- .addOutput(output1)
120- .addOutput(output2)
121- .addOutput(output3)
122- .setTimeRange(2000000)
123- .build();
124-
125- String rawTransaction = transaction.rawTransaction();
126- assert rawTransaction.equals("070180897a020160015e0b2cff11d1d056d95237a5f2d06059e5395e86f60e69c1e8201ea624911c0c65ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0a1ed89010001160014f1dc52048f439ac7fd74f8106a21da78f00de48f6302401660121218ab96d9f22cce712541ca34c53f4da40450669854341ca9624ad1cf10d1bfc96449fad5406224afd253ccfbdeab683f7ec7f9ee8f45e47a0c58500f2031ecc1bdd5fb9b40016358340b87646ea39faf55c0c105205cfdfdc6184725f40161015fbe0ac837e832c34a02968e54dab4f95cbeceb9fb01cd378310f6ea32219ee29b207265909236260b30942a6b00e30ceb769e0e58156b6482bac64117619c9dcf80f8cce284020101160014bb8a039726df1b649738e9973db14a4b4fd4becf630240d7b7f1c2ca1048fd6798234f2a1e895762f83e802507a008eff52605611b67390a74eaf228b76f5589ff109b2c20eaa65fad6de2e5ab8a25b54267b607df970b20a71547e1064b5edaad92cdce6b0ace832836ba28fdeaf0b83010bed247fe927c03013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f48a85010116001414d362694eacfa110dc20dec77d610d22340f95b00014b207265909236260b30942a6b00e30ceb769e0e58156b6482bac64117619c9dcf80c8afa02501246a2277656c636f6d65efbc8ce6aca2e8bf8ee69da5e588b0e58e9fe5ad90e4b896e7958c00013e207265909236260b30942a6b00e30ceb769e0e58156b6482bac64117619c9dcf80b09dc2df0101160014bb8a039726df1b649738e9973db14a4b4fd4becf00");
127- }
128-}
--- /dev/null
+++ b/tx-signer/src/test/java/io/bytom/offline/api/TransactionTest.java
@@ -0,0 +1,74 @@
1+package io.bytom.offline.api;
2+
3+import io.bytom.offline.util.AssetIdUtil;
4+import org.junit.Test;
5+
6+public class TransactionTest {
7+ String btmAssetID = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
8+
9+ @Test
10+ public void testIssuance() {
11+ String rawAssetDefinition = "7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022676f6c64222c0a20202271756f72756d223a20312c0a20202272656973737565223a202266616c7365222c0a20202273796d626f6c223a2022474f4c44220a7d";
12+ String issuanceProgram = "0204bfcda069ae2000cf50143dac994b9cfc1a2c45a4332ecefbbb15824b9f1a537f0b49fd9f44b45151ad";
13+ System.out.println(AssetIdUtil.computeAssetID(rawAssetDefinition,issuanceProgram));
14+ IssuanceInput issuanceInput = new IssuanceInput("0541db69c21dc827092ddbc5673f5c1f0a09d3112da2a67c6644ec1be3fa38b3",2543541111111L,"0204bfcda069ae2000cf50143dac994b9cfc1a2c45a4332ecefbbb15824b9f1a537f0b49fd9f44b45151ad");
15+ issuanceInput.setVmVersion(1);
16+ issuanceInput.setRootPrivateKey("b0cc39f8a4b9539fcc8f05c0df21563155767bfc6f2c4b801738eb831589d84afe549d3a89e8223762445a0f3bea5c192675636846f75f1455c6a23d30a37023");
17+ issuanceInput.setKeyIndex(3);
18+ issuanceInput.setRawAssetDefinition("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022676f6c64222c0a20202271756f72756d223a20312c0a20202272656973737565223a202266616c7365222c0a20202273796d626f6c223a2022474f4c44220a7d");
19+ issuanceInput.setNonce("");
20+
21+ SpendInput spendInput = new SpendInput();
22+ spendInput.setAssetId(btmAssetID);
23+ spendInput.setAmount(2853881270l);
24+ spendInput.setSourceID("0b75ee155f60160ac14e038eaf7c67c820d77096a615ab00c1a3d9b52f9f246c");
25+ spendInput.setSourcePosition(0);
26+ spendInput.setChange(false);
27+ spendInput.setVmVersion(1);
28+ spendInput.setProgram("0014e933e5a0545c63ff2c28eaedb47c831cac3b16cf");
29+ spendInput.setControlProgramIndex(2);
30+ spendInput.setRootPrivateKey("b0cc39f8a4b9539fcc8f05c0df21563155767bfc6f2c4b801738eb831589d84afe549d3a89e8223762445a0f3bea5c192675636846f75f1455c6a23d30a37023");
31+ spendInput.setKeyIndex(1);
32+
33+ OriginalOutput issuanceOutput = new OriginalOutput("0541db69c21dc827092ddbc5673f5c1f0a09d3112da2a67c6644ec1be3fa38b3",2543541111111L,"00145894d753c19d8fccce04db88f54751340ad8ca4f");
34+ OriginalOutput output = new OriginalOutput(btmAssetID,2753881270L,"0014b0b9455c1f77476b96858927d98e823d680ce889");
35+
36+ Transaction tx = new Transaction.Builder()
37+ .addInput(issuanceInput)
38+ .addInput(spendInput)
39+ .addOutput(issuanceOutput)
40+ .addOutput(output)
41+ .setTimeRange(0)
42+ .setSize(0)
43+ .build();
44+
45+ String rawTransaction = tx.rawTransaction();
46+ System.out.println(rawTransaction);
47+ }
48+
49+ @Test
50+ public void testSpendBIP44() {
51+ SpendInput spendInput = new SpendInput();
52+ spendInput.setAssetId(btmAssetID);
53+ spendInput.setAmount(2873881270l);
54+ spendInput.setSourceID("6dd143552ff8fde887e65eb7c387ff77265d270dfc76d6488a0185476f66c601");
55+ spendInput.setSourcePosition(0);
56+ spendInput.setChange(false);
57+ spendInput.setVmVersion(1);
58+ spendInput.setProgram("0014e933e5a0545c63ff2c28eaedb47c831cac3b16cf");
59+ spendInput.setControlProgramIndex(2);
60+ spendInput.setRootPrivateKey("b0cc39f8a4b9539fcc8f05c0df21563155767bfc6f2c4b801738eb831589d84afe549d3a89e8223762445a0f3bea5c192675636846f75f1455c6a23d30a37023");
61+ spendInput.setKeyIndex(1);
62+
63+
64+ OriginalOutput output = new OriginalOutput(btmAssetID,2773881270l,"0014b0b9455c1f77476b96858927d98e823d680ce889");
65+ Transaction tx = new Transaction.Builder()
66+ .addInput(spendInput)
67+ .addOutput(output)
68+ .setTimeRange(0)
69+ .setSize(0)
70+ .build();
71+ System.out.println(tx.rawTransaction());
72+ System.out.println(tx.getTxID());
73+ }
74+}
--- /dev/null
+++ b/tx-signer/src/test/java/io/bytom/offline/api/TxInputTest.java
@@ -0,0 +1,147 @@
1+package io.bytom.offline.api;
2+
3+import com.amazonaws.util.StringUtils;
4+import com.google.crypto.tink.subtle.Hex;
5+import org.junit.Test;
6+
7+import java.io.IOException;
8+
9+import static org.junit.Assert.assertEquals;
10+
11+public class TxInputTest {
12+ @Test
13+ public void testSpendInput() throws IOException {
14+ SpendInput input = new SpendInput();
15+ input.setAssetId("fe9791d71b67ee62515e08723c061b5ccb952a80d804417c8aeedf7f633c524a");
16+ input.setAmount(254354);
17+ input.setSourceID("fad5195a0c8e3b590b86a3c0a95e7529565888508aecca96e9aeda633002f409");
18+ input.setSourcePosition(3);
19+ input.setVmVersion(1);
20+ input.setProgram(Hex.encode("spendProgram".getBytes()));
21+ input.appendStateData(Hex.encode("stateData".getBytes()));
22+ input.appendWitnessComponent(Hex.encode("arguments1".getBytes()));
23+ input.appendWitnessComponent(Hex.encode("arguments2".getBytes()));
24+
25+ byte[] serializeInputCommitment = input.serializeInput();
26+ String wantStr= StringUtils.join("",
27+ "01", // asset version
28+ "5f", // input commitment length
29+ "01", // spend type flag
30+ "5d", // spend commitment length
31+ "fad5195a0c8e3b590b86a3c0a95e7529565888508aecca96e9aeda633002f409", // source id
32+ "fe9791d71b67ee62515e08723c061b5ccb952a80d804417c8aeedf7f633c524a", // assetID
33+ "92c30f", // amount
34+ "03", // source position
35+ "01", // vm version
36+ "0c", // spend program length
37+ "7370656e6450726f6772616d", // spend program
38+ "0109", // state length
39+ "737461746544617461", // state
40+ "17", // witness length
41+ "02", // argument array length
42+ "0a", // first argument length
43+ "617267756d656e747331", // first argument data
44+ "0a", // second argument length
45+ "617267756d656e747332" // second argument data
46+ );
47+
48+ assertEquals(wantStr,Hex.encode(serializeInputCommitment));
49+ }
50+
51+ @Test
52+ public void testIssuanceInput() throws IOException {
53+ IssuanceInput issuanceInput = new IssuanceInput();
54+ issuanceInput.setAmount(254354L);
55+ issuanceInput.setVmVersion(1);
56+ issuanceInput.setProgram(Hex.encode("issuanceProgram".getBytes()));
57+ issuanceInput.setNonce(Hex.encode("nonce".getBytes()));
58+ issuanceInput.setRawAssetDefinition(Hex.encode("assetDefinition".getBytes()));
59+ issuanceInput.appendWitnessComponent(Hex.encode("arguments1".getBytes()));
60+ issuanceInput.appendWitnessComponent(Hex.encode("arguments2".getBytes()));
61+
62+ byte[] serializeInputCommitment = issuanceInput.serializeInput();
63+ String wantStr= StringUtils.join("",
64+ "01", // asset version
65+ "2a", // serialization length
66+ "00", // issuance type flag
67+ "05", // nonce length
68+ "6e6f6e6365", // nonce
69+ "a69849e11add96ac7053aad22ba2349a4abf5feb0475a0afcadff4e128be76cf", // assetID
70+ "92c30f", // amount
71+ "38", // input witness length
72+ "0f", // asset definition length
73+ "6173736574446566696e6974696f6e", // asset definition
74+ "01", // vm version
75+ "0f", // issuanceProgram length
76+ "69737375616e636550726f6772616d", // issuance program
77+ "02", // argument array length
78+ "0a", // first argument length
79+ "617267756d656e747331", // first argument data
80+ "0a", // second argument length
81+ "617267756d656e747332" // second argument data
82+ );
83+
84+ assertEquals(wantStr,Hex.encode(serializeInputCommitment));
85+ }
86+
87+ @Test
88+ public void testVetoInput() throws IOException {
89+ VetoInput vetoInput = new VetoInput();
90+ vetoInput.setSourceID("fad5195a0c8e3b590b86a3c0a95e7529565888508aecca96e9aeda633002f409");
91+ vetoInput.setAssetId("fe9791d71b67ee62515e08723c061b5ccb952a80d804417c8aeedf7f633c524a");
92+ vetoInput.setSourcePosition(3);
93+ vetoInput.setAmount(254354L);
94+ vetoInput.setVmVersion(1);
95+ vetoInput.setProgram(Hex.encode("spendProgram".getBytes()));
96+ vetoInput.setVote("af594006a40837d9f028daabb6d589df0b9138daefad5683e5233c2646279217294a8d532e60863bcf196625a35fb8ceeffa3c09610eb92dcfb655a947f13269".getBytes());
97+ vetoInput.appendWitnessComponent(Hex.encode("arguments1".getBytes()));
98+ vetoInput.appendWitnessComponent(Hex.encode("arguments2".getBytes()));
99+
100+
101+ byte[] serializeInputCommitment = vetoInput.serializeInput();
102+
103+ String wantStr= StringUtils.join("",
104+ "01", // asset version
105+ "d701", // input commitment length
106+ "03", // veto type flag
107+ "53", // veto commitment length
108+ "fad5195a0c8e3b590b86a3c0a95e7529565888508aecca96e9aeda633002f409", // source id
109+ "fe9791d71b67ee62515e08723c061b5ccb952a80d804417c8aeedf7f633c524a", // assetID
110+ "92c30f", // amount
111+ "03", // source position
112+ "01", // vm version
113+ "0c", // veto program length
114+ "7370656e6450726f6772616d", // veto program
115+ "00", // state length
116+ "8001", //xpub length
117+ "6166353934303036613430383337643966303238646161626236643538396466306239313338646165666164353638336535323333633236343632373932313732393461386435333265363038363362636631393636323561333566623863656566666133633039363130656239326463666236353561393437663133323639", //voter xpub
118+ "17", // witness length
119+ "02", // argument array length
120+ "0a", // first argument length
121+ "617267756d656e747331", // first argument data
122+ "0a", // second argument length
123+ "617267756d656e747332" // second argument data
124+ );
125+
126+ assertEquals(wantStr,Hex.encode(serializeInputCommitment));
127+ }
128+
129+ @Test
130+ public void testCoinbaseInput() throws IOException {
131+ CoinbaseInput coinbaseInput = new CoinbaseInput();
132+ coinbaseInput.setArbitrary(Hex.encode("arbitrary".getBytes()));
133+
134+ byte[] serializeInputCommitment = coinbaseInput.serializeInput();
135+
136+ String wantStr= StringUtils.join("",
137+ "01", // asset version
138+ "0b", // input commitment length
139+ "02", // coinbase type flag
140+ "09", // arbitrary length
141+ "617262697472617279", // arbitrary data
142+ "00" // witness length
143+ );
144+
145+ assertEquals(wantStr,Hex.encode(serializeInputCommitment));
146+ }
147+}
--- /dev/null
+++ b/tx-signer/src/test/java/io/bytom/offline/api/TxOutputTest.java
@@ -0,0 +1,58 @@
1+package io.bytom.offline.api;
2+
3+import com.amazonaws.util.StringUtils;
4+import com.google.crypto.tink.subtle.Hex;
5+import org.junit.Test;
6+
7+import java.io.IOException;
8+
9+import static org.junit.Assert.assertEquals;
10+
11+public class TxOutputTest {
12+ String assetID = "81756fdab39a17163b0ce582ee4ee256fb4d1e156c692b997d608a42ecb38d47";
13+ @Test
14+ public void SerializationOriginalTxOutputTest() throws IOException {
15+ OriginalOutput output = new OriginalOutput(assetID,254354L,Hex.encode("TestSerializationTxOutput".getBytes()));
16+ output.appendStateData(Hex.encode("stateData".getBytes()));
17+
18+ byte[] serializeOutputCommitment = output.serializeOutput();
19+ String wantStr= StringUtils.join("",
20+ "01", // asset version
21+ "00", // output type
22+ "49", // serialization length
23+ "81756fdab39a17163b0ce582ee4ee256fb4d1e156c692b997d608a42ecb38d47", // assetID
24+ "92c30f", // amount
25+ "01", // version
26+ "19", // control program length
27+ "5465737453657269616c697a6174696f6e54784f7574707574", // control program
28+ "0109", // state data length
29+ "737461746544617461", // state data
30+ "00" // witness length
31+ );
32+
33+ assertEquals(wantStr,Hex.encode(serializeOutputCommitment));
34+ }
35+
36+ @Test
37+ public void SerializationVetoOutputTest() throws IOException {
38+ OriginalOutput output = new OriginalOutput(assetID,254354L,Hex.encode("TestSerializationTxOutput".getBytes()));
39+ output.appendStateData(Hex.encode("stateData".getBytes()));
40+
41+ byte[] serializeOutputCommitment = output.serializeOutput();
42+ String wantStr= StringUtils.join("",
43+ "01", // asset version
44+ "00", // output type
45+ "49", // serialization length
46+ "81756fdab39a17163b0ce582ee4ee256fb4d1e156c692b997d608a42ecb38d47", // assetID
47+ "92c30f", // amount
48+ "01", // version
49+ "19", // control program length
50+ "5465737453657269616c697a6174696f6e54784f7574707574", // control program
51+ "0109", // state data length
52+ "737461746544617461", // state data
53+ "00" // witness length
54+ );
55+
56+ assertEquals(wantStr,Hex.encode(serializeOutputCommitment));
57+ }
58+}
Afficher sur ancien navigateur de dépôt.