11package org .unicitylabs .sdk .api ;
22
3- import java .util .Arrays ;
4- import java .util .List ;
5- import java .util .Objects ;
63import org .unicitylabs .sdk .crypto .MintSigningService ;
74import org .unicitylabs .sdk .crypto .hash .DataHash ;
8- import org .unicitylabs .sdk .crypto .hash .DataHasher ;
95import org .unicitylabs .sdk .crypto .hash .HashAlgorithm ;
106import org .unicitylabs .sdk .crypto .secp256k1 .SigningService ;
117import org .unicitylabs .sdk .predicate .EncodedPredicate ;
12- import org .unicitylabs .sdk .predicate .Predicate ;
138import org .unicitylabs .sdk .predicate .UnlockScript ;
14- import org .unicitylabs .sdk .predicate .builtin .PayToPublicKeyPredicateUnlockScript ;
9+ import org .unicitylabs .sdk .predicate .builtin .SignaturePredicateUnlockScript ;
1510import org .unicitylabs .sdk .serializer .cbor .CborDeserializer ;
11+ import org .unicitylabs .sdk .serializer .cbor .CborSerializationException ;
1612import org .unicitylabs .sdk .serializer .cbor .CborSerializer ;
1713import org .unicitylabs .sdk .transaction .MintTransaction ;
1814import org .unicitylabs .sdk .transaction .Transaction ;
1915import org .unicitylabs .sdk .util .HexConverter ;
2016
17+ import java .util .Arrays ;
18+ import java .util .List ;
19+ import java .util .Objects ;
20+
2121/**
2222 * Certification data.
2323 */
2424public class CertificationData {
25+ public static final long CBOR_TAG = 39031 ;
26+ private static final int VERSION = 1 ;
2527
26- private final Predicate lockScript ;
28+ private final EncodedPredicate lockScript ;
2729 private final DataHash sourceStateHash ;
2830 private final DataHash transactionHash ;
2931 private final byte [] unlockScript ;
3032
3133 CertificationData (
32- Predicate lockScript ,
33- DataHash sourceStateHash ,
34- DataHash transactionHash ,
35- byte [] unlockScript
34+ EncodedPredicate lockScript ,
35+ DataHash sourceStateHash ,
36+ DataHash transactionHash ,
37+ byte [] unlockScript
3638 ) {
3739 this .lockScript = lockScript ;
3840 this .sourceStateHash = sourceStateHash ;
3941 this .transactionHash = transactionHash ;
4042 this .unlockScript = Arrays .copyOf (unlockScript , unlockScript .length );
4143 }
4244
45+ public int getVersion () {
46+ return CertificationData .VERSION ;
47+ }
48+
4349 /**
4450 * Get lock script of certified transaction output.
4551 *
4652 * @return lock script
4753 */
48- public Predicate getLockScript () {
54+ public EncodedPredicate getLockScript () {
4955 return this .lockScript ;
5056 }
5157
@@ -83,13 +89,22 @@ public byte[] getUnlockScript() {
8389 * @return CertificationData
8490 */
8591 public static CertificationData fromCbor (byte [] bytes ) {
86- List <byte []> data = CborDeserializer .decodeArray (bytes );
92+ CborDeserializer .CborTag tag = CborDeserializer .decodeTag (bytes );
93+ if (tag .getTag () != CertificationData .CBOR_TAG ) {
94+ throw new CborSerializationException (String .format ("Invalid CBOR tag: %s" , tag .getTag ()));
95+ }
96+ List <byte []> data = CborDeserializer .decodeArray (tag .getData (), 5 );
97+
98+ int version = CborDeserializer .decodeUnsignedInteger (data .get (0 )).asInt ();
99+ if (version != CertificationData .VERSION ) {
100+ throw new CborSerializationException (String .format ("Unsupported version: %s" , version ));
101+ }
87102
88103 return new CertificationData (
89- EncodedPredicate .fromCbor (data .get (0 )),
90- new DataHash (HashAlgorithm .SHA256 , CborDeserializer .decodeByteString (data .get (1 ))),
91- new DataHash (HashAlgorithm .SHA256 , CborDeserializer .decodeByteString (data .get (2 ))),
92- CborDeserializer .decodeByteString (data .get (3 ))
104+ EncodedPredicate .fromCbor (data .get (1 )),
105+ new DataHash (HashAlgorithm .SHA256 , CborDeserializer .decodeByteString (data .get (2 ))),
106+ new DataHash (HashAlgorithm .SHA256 , CborDeserializer .decodeByteString (data .get (3 ))),
107+ CborDeserializer .decodeByteString (data .get (4 ))
93108 );
94109 }
95110
@@ -101,12 +116,14 @@ public static CertificationData fromCbor(byte[] bytes) {
101116 * @return certification data
102117 */
103118 public static CertificationData fromMintTransaction (MintTransaction transaction ) {
119+ Objects .requireNonNull (transaction , "transaction cannot be null" );
120+
104121 SigningService signingService = MintSigningService .create (transaction .getTokenId ());
105122
106123 return CertificationData .fromTransaction (
107- transaction ,
108- PayToPublicKeyPredicateUnlockScript .create (transaction , signingService ).getSignature ()
109- .encode ()
124+ transaction ,
125+ SignaturePredicateUnlockScript .create (transaction , signingService ).getSignature ()
126+ .encode ()
110127 );
111128 }
112129
@@ -119,6 +136,8 @@ public static CertificationData fromMintTransaction(MintTransaction transaction)
119136 * @return certification data
120137 */
121138 public static CertificationData fromTransaction (Transaction transaction , UnlockScript unlockScript ) {
139+ Objects .requireNonNull (unlockScript , "unlockScript cannot be null" );
140+
122141 return CertificationData .fromTransaction (transaction , unlockScript .encode ());
123142 }
124143
@@ -131,36 +150,32 @@ public static CertificationData fromTransaction(Transaction transaction, UnlockS
131150 * @return certification data
132151 */
133152 public static CertificationData fromTransaction (Transaction transaction , byte [] unlockScript ) {
153+ Objects .requireNonNull (transaction , "transaction cannot be null" );
154+ Objects .requireNonNull (unlockScript , "unlockScript cannot be null" );
155+
134156 return new CertificationData (
135- transaction .getLockScript (),
136- transaction .getSourceStateHash (),
137- transaction .calculateTransactionHash (),
138- unlockScript
157+ transaction .getLockScript (),
158+ transaction .getSourceStateHash (),
159+ transaction .calculateTransactionHash (),
160+ unlockScript
139161 );
140162 }
141163
142- /**
143- * Calculate leaf value for Merkle tree.
144- *
145- * @return leaf value
146- */
147- public DataHash calculateLeafValue () {
148- return new DataHasher (HashAlgorithm .SHA256 )
149- .update (this .toCbor ())
150- .digest ();
151- }
152-
153164 /**
154165 * Serialize certification data to CBOR bytes.
155166 *
156167 * @return CBOR bytes
157168 */
158169 public byte [] toCbor () {
159- return CborSerializer .encodeArray (
160- EncodedPredicate .fromPredicate (this .getLockScript ()).toCbor (),
161- CborSerializer .encodeByteString (this .sourceStateHash .getData ()),
162- CborSerializer .encodeByteString (this .transactionHash .getData ()),
163- CborSerializer .encodeByteString (this .unlockScript )
170+ return CborSerializer .encodeTag (
171+ CertificationData .CBOR_TAG ,
172+ CborSerializer .encodeArray (
173+ CborSerializer .encodeUnsignedInteger (CertificationData .VERSION ),
174+ this .lockScript .toCbor (),
175+ CborSerializer .encodeByteString (this .sourceStateHash .getData ()),
176+ CborSerializer .encodeByteString (this .transactionHash .getData ()),
177+ CborSerializer .encodeByteString (this .unlockScript )
178+ )
164179 );
165180 }
166181
@@ -170,17 +185,22 @@ public boolean equals(Object o) {
170185 return false ;
171186 }
172187 CertificationData that = (CertificationData ) o ;
173- return this .lockScript .isEqualTo (that .lockScript )
174- && Objects .equals (this .sourceStateHash , that .sourceStateHash )
175- && Objects .equals (this .transactionHash , that .transactionHash )
176- && Arrays .equals (this .unlockScript , that .unlockScript );
188+ return Objects .equals (this .lockScript , that .lockScript )
189+ && Objects .equals (this .sourceStateHash , that .sourceStateHash )
190+ && Objects .equals (this .transactionHash , that .transactionHash )
191+ && Arrays .equals (this .unlockScript , that .unlockScript );
192+ }
193+
194+ @ Override
195+ public int hashCode () {
196+ return Objects .hash (this .lockScript , this .sourceStateHash , this .transactionHash , Arrays .hashCode (this .unlockScript ));
177197 }
178198
179199 @ Override
180200 public String toString () {
181201 return String .format (
182- "CertificationData{lockScript=%s, sourceStateHash=%s, transactionHash=%s, unlockScript=%s}" ,
183- this .lockScript , this .sourceStateHash , this .transactionHash ,
184- HexConverter .encode (this .unlockScript ));
202+ "CertificationData{lockScript=%s, sourceStateHash=%s, transactionHash=%s, unlockScript=%s}" ,
203+ this .lockScript , this .sourceStateHash , this .transactionHash ,
204+ HexConverter .encode (this .unlockScript ));
185205 }
186206}
0 commit comments