3 import io.bytom.common.DerivePrivateKey;
4 import io.bytom.common.ExpandedPrivateKey;
5 import io.bytom.common.Signer;
6 import io.bytom.common.Utils;
7 import io.bytom.types.*;
8 import io.bytom.util.SHA3Util;
9 import org.bouncycastle.util.encoders.Hex;
10 import java.io.ByteArrayOutputStream;
11 import java.io.IOException;
12 import java.security.SecureRandom;
15 public class IssuanceInput extends BaseInput {
19 private String rawAssetDefinition;
21 public IssuanceInput() {}
23 public IssuanceInput(String assetID, Long amount, String issuanceProgram) {
24 this.setAssetId(assetID);
25 this.setAmount(amount);
26 this.setProgram(issuanceProgram);
29 public IssuanceInput(String assetID, Long amount, String issuanceProgram, String nonce, String rawAssetDefinition) {
30 this(assetID, amount, issuanceProgram);
32 this.rawAssetDefinition = rawAssetDefinition;
36 public InputEntry convertInputEntry(Map<Hash, Entry> entryMap, int index) {
37 if (this.nonce == null) {
38 SecureRandom sr = new SecureRandom();
39 byte[] randBytes = new byte[8];
40 sr.nextBytes(randBytes);
41 this.nonce = Hex.toHexString(randBytes);
44 Hash nonceHash = new Hash(SHA3Util.hashSha256(Hex.decode(this.nonce)));
45 Hash assetDefHash = new Hash(this.rawAssetDefinition);
46 AssetAmount value = this.getAssetAmount();
48 Program pro = new Program(this.getVmVersion(), Hex.decode(this.getProgram()));
49 return new Issue(nonceHash, value, index, new AssetDefinition(assetDefHash, pro));
53 public byte[] serializeInput() throws IOException {
54 ByteArrayOutputStream stream = new ByteArrayOutputStream();
56 Utils.writeVarint(1, stream);
58 ByteArrayOutputStream issueInfo = new ByteArrayOutputStream();
59 Utils.writeVarint(ISSUANCE_INPUT_TYPE, issueInfo);
60 Utils.writeVarStr(Hex.decode(nonce), issueInfo);
61 issueInfo.write(Hex.decode(getAssetId()));
62 Utils.writeVarint(getAmount(), issueInfo);
63 stream.write(issueInfo.toByteArray().length);
64 stream.write(issueInfo.toByteArray());
66 ByteArrayOutputStream issueInfo1 = new ByteArrayOutputStream();
67 Utils.writeVarint(1, issueInfo1);
68 Utils.writeVarStr(Hex.decode(rawAssetDefinition), issueInfo1);
70 Utils.writeVarint(1, issueInfo1);
71 Utils.writeVarStr(Hex.decode(getProgram()), issueInfo1);
74 ByteArrayOutputStream witnessStream = new ByteArrayOutputStream();
76 int witnessSize = witnessComponent.size();
78 Utils.writeVarint(witnessSize, witnessStream);
79 for (int i = 0; i < witnessSize; i++) {
80 String witness = witnessComponent.getWitness(i);
81 Utils.writeVarStr(Hex.decode(witness), witnessStream);
83 issueInfo1.write(witnessStream.toByteArray());
84 stream.write(issueInfo1.toByteArray().length - 1);
85 stream.write(issueInfo1.toByteArray());
86 return stream.toByteArray();
90 public void buildWitness(String txID) throws Exception {
91 String rootPrivateKey = witnessComponent.getRootPrivateKey();
92 byte[] childPrivateKey = DerivePrivateKey.bip32derivePrvKey(rootPrivateKey, getKeyIndex(), AssetKeySpace);
94 byte[] message = Utils.hashFn(Hex.decode(getInputID()), Hex.decode(txID));
95 byte[] expandedPrivateKey = ExpandedPrivateKey.expandedPrivateKey(childPrivateKey);
96 byte[] sig = Signer.ed25519InnerSign(expandedPrivateKey, message);
98 witnessComponent.appendWitness(Hex.toHexString(sig));
102 public void validate() {
105 throw new IllegalArgumentException("the nonce of issuance input must be specified.");
107 if (rawAssetDefinition == null) {
108 throw new IllegalArgumentException("the nonce of issuance input must be specified.");
112 public String getNonce() {
116 public void setNonce(String nonce) {
120 public String getRawAssetDefinition() {
121 return rawAssetDefinition;
124 public void setRawAssetDefinition(String rawAssetDefinition) {
125 this.rawAssetDefinition = rawAssetDefinition;