Skip to content

Commit 4a24672

Browse files
authoredFeb 7, 2025··
Merge pull request #35 from mlabs-haskell/marcusbfs/integration-fixes
Fixes related to CTL integration
2 parents 5da387d + 6a78bfd commit 4a24672

File tree

14 files changed

+427
-28
lines changed

14 files changed

+427
-28
lines changed
 

‎.github/workflows/main.yml

+3
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,6 @@ jobs:
4646

4747
- name: Run API tests
4848
run: npm run test-api
49+
50+
- name: Run implementation tests
51+
run: npm run test-implementation

‎conway-cddl/yaml/conway.yaml

+35
Original file line numberDiff line numberDiff line change
@@ -2236,12 +2236,32 @@ ScriptAll:
22362236
fields:
22372237
- name: native_scripts
22382238
type: NativeScripts
2239+
methods:
2240+
serialize: null
2241+
extra_methods: |
2242+
serialize(writer: CBORWriter): void {
2243+
let ns = new NativeScripts(true, false);
2244+
for (let i = 0; i < this._native_scripts.len(); i++) {
2245+
ns.add(this._native_scripts.get(i));
2246+
}
2247+
ns.serialize(writer);
2248+
}
22392249
22402250
ScriptAny:
22412251
type: record_fragment
22422252
fields:
22432253
- name: native_scripts
22442254
type: NativeScripts
2255+
methods:
2256+
serialize: null
2257+
extra_methods: |
2258+
serialize(writer: CBORWriter): void {
2259+
let ns = new NativeScripts(true, false);
2260+
for (let i = 0; i < this._native_scripts.len(); i++) {
2261+
ns.add(this._native_scripts.get(i));
2262+
}
2263+
ns.serialize(writer);
2264+
}
22452265
22462266
ScriptNOfK:
22472267
type: record_fragment
@@ -2250,6 +2270,17 @@ ScriptNOfK:
22502270
type: number
22512271
- name: native_scripts
22522272
type: NativeScripts
2273+
methods:
2274+
serialize: null
2275+
extra_methods: |
2276+
serialize(writer: CBORWriter): void {
2277+
writer.writeInt(BigInt(this._n));
2278+
let ns = new NativeScripts(true, false);
2279+
for (let i = 0; i < this._native_scripts.len(); i++) {
2280+
ns.add(this._native_scripts.get(i));
2281+
}
2282+
ns.serialize(writer);
2283+
}
22532284
22542285
TimelockStart:
22552286
type: record_fragment
@@ -2503,6 +2534,10 @@ DataCost:
25032534
fields:
25042535
- name: coins_per_byte
25052536
type: BigNum
2537+
extra_methods: |
2538+
static new_coins_per_byte(coins_per_byte: BigNum) {
2539+
return new DataCost(coins_per_byte);
2540+
}
25062541
25072542
OutputDatum:
25082543
type: tagged_record

‎conway-cddl/yaml/custom/bigint.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ CSLBigInt:
1515
return this.toJsValue().toString();
1616
}
1717
18+
to_json(): String {
19+
return "\"" + this.to_str() + "\"";
20+
}
21+
22+
toJSON(): String {
23+
return this.to_json()
24+
}
25+
1826
static zero(): CSLBigInt {
1927
return new CSLBigInt(0n);
2028
}

‎conway-cddl/yaml/custom/bignum.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ BigNum:
2020
return this.toJsValue().toString();
2121
}
2222
23+
to_json(): String {
24+
return "\"" + this.to_str() + "\"";
25+
}
26+
27+
toJSON(): String {
28+
return this.to_json();
29+
}
30+
2331
static zero(): BigNum {
2432
return new BigNum(0n);
2533
}

‎conway-cddl/yaml/custom/custom_model.yaml

+65
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,68 @@ Costmdls:
3939
}
4040
return result;
4141
}
42+
43+
language_views_encoding(): Uint8Array {
44+
// Compare two byte arrays lexicographically
45+
function compareBytes(a: Uint8Array, b: Uint8Array): number {
46+
const minLen = Math.min(a.length, b.length);
47+
for (let i = 0; i < minLen; i++) {
48+
if (a[i] < b[i]) return -1;
49+
if (a[i] > b[i]) return 1;
50+
}
51+
return a.length - b.length;
52+
}
53+
54+
function keyLen(lang: Language): number {
55+
if (lang.kind() === LanguageKind.plutus_v1) {
56+
const w = new CBORWriter();
57+
w.writeBytes(lang.to_bytes());
58+
return w.getBytes().length;
59+
} else {
60+
return lang.to_bytes().length;
61+
}
62+
}
63+
64+
const keys = this._items.map(([k, _]) => k);
65+
66+
// keys must be in canonical ordering first
67+
keys.sort((lhs, rhs) => {
68+
const lhsLen = keyLen(lhs);
69+
const rhsLen = keyLen(rhs);
70+
if (lhsLen !== rhsLen) {
71+
return lhsLen - rhsLen;
72+
}
73+
return compareBytes(lhs.to_bytes(), rhs.to_bytes());
74+
});
75+
76+
const writer = new CBORWriter();
77+
writer.writeMapTag(keys.length);
78+
79+
for (let i = 0; i < keys.length; i++) {
80+
const key = keys[i];
81+
const costModel = this.get(key);
82+
if (!costModel) {
83+
throw new Error(
84+
"No cost model found for key in language_views_encoding.",
85+
);
86+
}
87+
88+
if (key.kind() === LanguageKind.plutus_v1) {
89+
writer.writeBytes(key.to_bytes());
90+
91+
const subWriter = new CBORWriter();
92+
subWriter.writeArray(
93+
costModel["items"],
94+
(sw, costInt) => costInt.serialize(sw),
95+
false,
96+
);
97+
98+
writer.writeBytes(subWriter.getBytes());
99+
} else {
100+
key.serialize(writer);
101+
costModel.serialize(writer);
102+
}
103+
}
104+
105+
return writer.getBytes();
106+
}

‎conway-cddl/yaml/custom/redeemers.yaml

+12
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,18 @@ Redeemer:
8787
static new(tag: RedeemerTag, index: BigNum, data: PlutusData, ex_units: ExUnits) {
8888
return new Redeemer(new RedeemersArrayItem(tag, index, data, ex_units));
8989
}
90+
tag(): RedeemerTag {
91+
return this.inner.tag();
92+
}
93+
index(): BigNum {
94+
return this.inner.index();
95+
}
96+
data(): PlutusData {
97+
return this.inner.data();
98+
}
99+
ex_units(): ExUnits {
100+
return this.inner.ex_units();
101+
}
90102
accessor: redeemerArrayItem
91103

92104
RedeemersArray:

‎src/address/byron.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export class ByronAddress {
9090

9191
byron_protocol_magic(): number {
9292
return (
93-
this._attributes._protocol_magic || NetworkInfo.mainnet().protcol_magic()
93+
this._attributes._protocol_magic || NetworkInfo.mainnet().protocol_magic()
9494
);
9595
}
9696

@@ -100,11 +100,9 @@ export class ByronAddress {
100100

101101
network_id(): number {
102102
switch (this.byron_protocol_magic()) {
103-
case NetworkInfo.testnet_preprod().protcol_magic():
103+
case NetworkInfo.testnet_preprod().protocol_magic():
104104
return NetworkInfo.testnet_preprod().network_id();
105-
case NetworkInfo.testnet_preview().protcol_magic():
106-
return NetworkInfo.testnet_preview().network_id();
107-
case NetworkInfo.mainnet().protcol_magic():
105+
case NetworkInfo.mainnet().protocol_magic():
108106
return NetworkInfo.mainnet().network_id();
109107
default:
110108
throw new Error(

‎src/address/network_info.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export class NetworkInfo {
1111
return this._network_id;
1212
}
1313

14-
protcol_magic(): number {
14+
protocol_magic(): number {
1515
return this._protocol_magic;
1616
}
1717

‎src/fee/index.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ function multiply_unit_interval_by_bignum(
6868
export function calculate_exunits_ceil_cost(
6969
exUnits: ExUnits,
7070
exUnitPrices: ExUnitPrices,
71-
): BigInt {
71+
): BigNum {
7272
const memPrice: UnitInterval = exUnitPrices.mem_price();
7373
const stepsPrice: UnitInterval = exUnitPrices.step_price();
7474

@@ -79,19 +79,19 @@ export function calculate_exunits_ceil_cost(
7979
);
8080
const totalCostFraction = add_fractions(memRatio, stepsRatio);
8181

82-
return ceil_division(totalCostFraction);
82+
return BigNum.from_str(ceil_division(totalCostFraction).to_str());
8383
}
8484

8585
export function min_script_fee(
8686
tx: Transaction,
8787
exUnitPrices: ExUnitPrices,
88-
): BigInt {
88+
): BigNum {
8989
const redeemers = tx.witness_set().redeemers();
9090
if (redeemers) {
9191
const totalExUnits = redeemers.total_ex_units();
9292
return calculate_exunits_ceil_cost(totalExUnits, exUnitPrices);
9393
}
94-
return BigInt.zero();
94+
return BigNum.zero();
9595
}
9696

9797

@@ -100,7 +100,7 @@ function tier_ref_script_fee(
100100
sizeIncrement: number,
101101
baseFee: Fraction,
102102
totalSize: number,
103-
): BigInt {
103+
): BigNum {
104104

105105
if (is_fraction_negative_or_zero(multiplier) || sizeIncrement === 0) {
106106
throw new Error("Size increment and multiplier must be positive");
@@ -145,13 +145,13 @@ function tier_ref_script_fee(
145145
acc = add_fractions(acc, partialTierFee);
146146
}
147147

148-
return toBigIntFloor(acc);
148+
return BigNum.from_str(toBigIntFloor(acc).to_str());
149149
}
150150

151151
export function min_ref_script_fee(
152152
totalRefScriptsSize: number,
153153
refScriptBigNumsPerByte: UnitInterval,
154-
): BigInt {
154+
): BigNum {
155155
const multiplier: Fraction = {
156156
numerator: new BigInt(12n),
157157
denominator: new BigInt(10n),

‎src/generated.ts

+122-13
Original file line numberDiff line numberDiff line change
@@ -1367,6 +1367,14 @@ export class BigNum {
13671367
return this.toJsValue().toString();
13681368
}
13691369

1370+
to_json(): String {
1371+
return '"' + this.to_str() + '"';
1372+
}
1373+
1374+
toJSON(): String {
1375+
return this.to_json();
1376+
}
1377+
13701378
static zero(): BigNum {
13711379
return new BigNum(0n);
13721380
}
@@ -2212,6 +2220,14 @@ export class CSLBigInt {
22122220
return this.toJsValue().toString();
22132221
}
22142222

2223+
to_json(): String {
2224+
return '"' + this.to_str() + '"';
2225+
}
2226+
2227+
toJSON(): String {
2228+
return this.to_json();
2229+
}
2230+
22152231
static zero(): CSLBigInt {
22162232
return new CSLBigInt(0n);
22172233
}
@@ -3940,6 +3956,71 @@ export class Costmdls {
39403956
}
39413957
return result;
39423958
}
3959+
3960+
language_views_encoding(): Uint8Array {
3961+
// Compare two byte arrays lexicographically
3962+
function compareBytes(a: Uint8Array, b: Uint8Array): number {
3963+
const minLen = Math.min(a.length, b.length);
3964+
for (let i = 0; i < minLen; i++) {
3965+
if (a[i] < b[i]) return -1;
3966+
if (a[i] > b[i]) return 1;
3967+
}
3968+
return a.length - b.length;
3969+
}
3970+
3971+
function keyLen(lang: Language): number {
3972+
if (lang.kind() === LanguageKind.plutus_v1) {
3973+
const w = new CBORWriter();
3974+
w.writeBytes(lang.to_bytes());
3975+
return w.getBytes().length;
3976+
} else {
3977+
return lang.to_bytes().length;
3978+
}
3979+
}
3980+
3981+
const keys = this._items.map(([k, _]) => k);
3982+
3983+
// keys must be in canonical ordering first
3984+
keys.sort((lhs, rhs) => {
3985+
const lhsLen = keyLen(lhs);
3986+
const rhsLen = keyLen(rhs);
3987+
if (lhsLen !== rhsLen) {
3988+
return lhsLen - rhsLen;
3989+
}
3990+
return compareBytes(lhs.to_bytes(), rhs.to_bytes());
3991+
});
3992+
3993+
const writer = new CBORWriter();
3994+
writer.writeMapTag(keys.length);
3995+
3996+
for (let i = 0; i < keys.length; i++) {
3997+
const key = keys[i];
3998+
const costModel = this.get(key);
3999+
if (!costModel) {
4000+
throw new Error(
4001+
"No cost model found for key in language_views_encoding.",
4002+
);
4003+
}
4004+
4005+
if (key.kind() === LanguageKind.plutus_v1) {
4006+
writer.writeBytes(key.to_bytes());
4007+
4008+
const subWriter = new CBORWriter();
4009+
subWriter.writeArray(
4010+
costModel["items"],
4011+
(sw, costInt) => costInt.serialize(sw),
4012+
false,
4013+
);
4014+
4015+
writer.writeBytes(subWriter.getBytes());
4016+
} else {
4017+
key.serialize(writer);
4018+
costModel.serialize(writer);
4019+
}
4020+
}
4021+
4022+
return writer.getBytes();
4023+
}
39434024
}
39444025

39454026
export class Credentials {
@@ -5040,6 +5121,10 @@ export class DataCost {
50405121
clone(path: string[]): DataCost {
50415122
return DataCost.from_bytes(this.to_bytes(), path);
50425123
}
5124+
5125+
static new_coins_per_byte(coins_per_byte: BigNum) {
5126+
return new DataCost(coins_per_byte);
5127+
}
50435128
}
50445129

50455130
export class DataHash {
@@ -13087,6 +13172,18 @@ export class Redeemer {
1308713172
) {
1308813173
return new Redeemer(new RedeemersArrayItem(tag, index, data, ex_units));
1308913174
}
13175+
tag(): RedeemerTag {
13176+
return this.inner.tag();
13177+
}
13178+
index(): BigNum {
13179+
return this.inner.index();
13180+
}
13181+
data(): PlutusData {
13182+
return this.inner.data();
13183+
}
13184+
ex_units(): ExUnits {
13185+
return this.inner.ex_units();
13186+
}
1309013187
}
1309113188

1309213189
export enum RedeemerTagKind {
@@ -14344,10 +14441,6 @@ export class ScriptAll {
1434414441
return new ScriptAll(native_scripts);
1434514442
}
1434614443

14347-
serialize(writer: CBORWriter): void {
14348-
this._native_scripts.serialize(writer);
14349-
}
14350-
1435114444
// no-op
1435214445
free(): void {}
1435314446

@@ -14376,6 +14469,14 @@ export class ScriptAll {
1437614469
clone(path: string[]): ScriptAll {
1437714470
return ScriptAll.from_bytes(this.to_bytes(), path);
1437814471
}
14472+
14473+
serialize(writer: CBORWriter): void {
14474+
let ns = new NativeScripts(true, false);
14475+
for (let i = 0; i < this._native_scripts.len(); i++) {
14476+
ns.add(this._native_scripts.get(i));
14477+
}
14478+
ns.serialize(writer);
14479+
}
1437914480
}
1438014481

1438114482
export class ScriptAny {
@@ -14406,10 +14507,6 @@ export class ScriptAny {
1440614507
return new ScriptAny(native_scripts);
1440714508
}
1440814509

14409-
serialize(writer: CBORWriter): void {
14410-
this._native_scripts.serialize(writer);
14411-
}
14412-
1441314510
// no-op
1441414511
free(): void {}
1441514512

@@ -14438,6 +14535,14 @@ export class ScriptAny {
1443814535
clone(path: string[]): ScriptAny {
1443914536
return ScriptAny.from_bytes(this.to_bytes(), path);
1444014537
}
14538+
14539+
serialize(writer: CBORWriter): void {
14540+
let ns = new NativeScripts(true, false);
14541+
for (let i = 0; i < this._native_scripts.len(); i++) {
14542+
ns.add(this._native_scripts.get(i));
14543+
}
14544+
ns.serialize(writer);
14545+
}
1444114546
}
1444214547

1444314548
export class ScriptDataHash {
@@ -14693,11 +14798,6 @@ export class ScriptNOfK {
1469314798
return new ScriptNOfK(n, native_scripts);
1469414799
}
1469514800

14696-
serialize(writer: CBORWriter): void {
14697-
writer.writeInt(BigInt(this._n));
14698-
this._native_scripts.serialize(writer);
14699-
}
14700-
1470114801
// no-op
1470214802
free(): void {}
1470314803

@@ -14729,6 +14829,15 @@ export class ScriptNOfK {
1472914829
clone(path: string[]): ScriptNOfK {
1473014830
return ScriptNOfK.from_bytes(this.to_bytes(), path);
1473114831
}
14832+
14833+
serialize(writer: CBORWriter): void {
14834+
writer.writeInt(BigInt(this._n));
14835+
let ns = new NativeScripts(true, false);
14836+
for (let i = 0; i < this._native_scripts.len(); i++) {
14837+
ns.add(this._native_scripts.get(i));
14838+
}
14839+
ns.serialize(writer);
14840+
}
1473214841
}
1473314842

1473414843
export class ScriptPubkey {

‎src/hash/index.ts

+56
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,74 @@ import { blake2b } from "@noble/hashes/blake2b";
22
import {
33
AuxiliaryData,
44
AuxiliaryDataHash,
5+
Costmdls,
56
DataHash,
67
PlutusData,
8+
PlutusList,
9+
PrivateKey,
10+
Redeemers,
11+
ScriptDataHash,
12+
TransactionBody,
13+
TransactionHash,
14+
Vkey,
15+
Vkeywitness,
716
} from "../generated";
817

918
export function hash_plutus_data(plutus_data: PlutusData): DataHash {
1019
const bytes = plutus_data.to_bytes();
1120
return DataHash.new(blake2b(bytes, { dkLen: 32 }));
1221
}
1322

23+
export function make_vkey_witness(
24+
tx_body_hash: TransactionHash,
25+
sk: PrivateKey
26+
): Vkeywitness {
27+
const sig = sk.sign(tx_body_hash.to_bytes());
28+
return Vkeywitness.new(Vkey.new(sk.to_public()), sig);
29+
}
30+
1431
export function hash_auxiliary_data(
1532
auxiliary_data: AuxiliaryData,
1633
): AuxiliaryDataHash {
1734
const bytes = auxiliary_data.to_bytes();
1835
return AuxiliaryDataHash.new(blake2b(bytes, { dkLen: 32 }));
1936
}
37+
38+
export function hash_transaction(
39+
tx_body: TransactionBody,
40+
): TransactionHash {
41+
const bytes = tx_body.to_bytes();
42+
return TransactionHash.new(blake2b(bytes, { dkLen: 32 }));
43+
}
44+
45+
export function hash_script_data(
46+
redeemers: Redeemers,
47+
cost_models: Costmdls,
48+
datums: PlutusList | undefined
49+
): ScriptDataHash {
50+
const arr: number[] = [];
51+
52+
// If there are no redeemers and some datums, use the [ A0 | datums | A0 ] format
53+
if (redeemers.len() === 0 && datums !== undefined) {
54+
55+
// A0 = CBOR empty map
56+
arr.push(0xA0);
57+
// push datums.to_set_bytes()
58+
arr.push(...datums.as_set().to_bytes());
59+
60+
// A0 = another CBOR empty map
61+
arr.push(0xA0);
62+
} else {
63+
// Otherwise: [ redeemers | datums | language views ]
64+
arr.push(...redeemers.to_bytes());
65+
66+
if (datums !== undefined) {
67+
arr.push(...datums.as_set().to_bytes());
68+
}
69+
70+
arr.push(...cost_models.language_views_encoding());
71+
}
72+
73+
const buf = new Uint8Array(arr);
74+
return ScriptDataHash.new(blake2b(buf, { dkLen: 32 }));
75+
}

‎src/lib/bip32-ed25519/index.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ export function getRandomBytes(len: number): Uint8Array {
1313
}
1414

1515
export function sign(msg: Uint8Array, secretKey: Uint8Array) {
16-
return nacl.sign.detached(msg, secretKey);
16+
// Generate the 64-byte keypair from the 32-byte key:
17+
const keyPair = nacl.sign.keyPair.fromSeed(secretKey);
18+
return nacl.sign.detached(msg, keyPair.secretKey);
1719
}
1820

1921
export function verify(

‎tests/bip32-ed25519/bip32-ed25519.test.ts

+23
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,29 @@ describe("signExtended", () => {
3838
});
3939
});
4040

41+
42+
describe("sign", () => {
43+
let privateKey = CSL.PrivateKey.generate_ed25519();
44+
let msg = new Uint8Array([1, 2, 3]);
45+
46+
test("signature must be same as CSL", () => {
47+
expect(thisLib.sign(msg, privateKey.as_bytes())).toEqual(
48+
privateKey.sign(msg).to_bytes(),
49+
);
50+
});
51+
52+
test("signature should verify", () => {
53+
let signature = thisLib.sign(msg, privateKey.as_bytes());
54+
expect(
55+
nacl.sign.detached.verify(
56+
msg,
57+
signature,
58+
privateKey.to_public().as_bytes(),
59+
),
60+
).toEqual(true);
61+
});
62+
});
63+
4164
describe("secretToExtended", () => {
4265
let regressionKeys = [
4366
"4428f1b59d357c10bca5ae134b767359d1f8f66fde851503b56f297cf599f456",

‎tests/hash/hash.test.ts

+81-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
import {
22
BigNum,
33
ConstrPlutusData,
4+
Costmdls,
5+
Ed25519KeyHash,
6+
NativeScript,
47
PlutusData,
58
PlutusList,
9+
Redeemers,
10+
ScriptPubkey,
611
} from "../../src/generated";
7-
import { hash_plutus_data } from "../../src/hash";
12+
import { hash_plutus_data, hash_script_data } from "../../src/hash";
813

914
describe("hash_plutus_data Tests", () => {
1015
test("Hash of ConstrPlutusData with tag 0 and empty list", () => {
@@ -50,3 +55,78 @@ describe("hash_plutus_data Tests", () => {
5055
expect(hashHex).toBe(expectedHash);
5156
});
5257
});
58+
59+
describe("hash_script_data Tests", () => {
60+
test("Known plutus data hash", () => {
61+
62+
const redeemers = Redeemers.from_hex("a182000182d87980821a006acfc01ab2d05e00");
63+
const costmdls = Costmdls.from_hex("a10098a61a0003236119032c01011903e819023b00011903e8195e7104011903e818201a0001ca761928eb041959d818641959d818641959d818641959d818641959d818641959d81864186418641959d81864194c5118201a0002acfa182019b551041a000363151901ff00011a00015c3518201a000797751936f404021a0002ff941a0006ea7818dc0001011903e8196ff604021a0003bd081a00034ec5183e011a00102e0f19312a011a00032e801901a5011a0002da781903e819cf06011a00013a34182019a8f118201903e818201a00013aac0119e143041903e80a1a00030219189c011a00030219189c011a0003207c1901d9011a000330001901ff0119ccf3182019fd40182019ffd5182019581e18201940b318201a00012adf18201a0002ff941a0006ea7818dc0001011a00010f92192da7000119eabb18201a0002ff941a0006ea7818dc0001011a0002ff941a0006ea7818dc0001011a000c504e197712041a001d6af61a0001425b041a00040c660004001a00014fab18201a0003236119032c010119a0de18201a00033d7618201979f41820197fb8182019a95d1820197df718201995aa18201a0374f693194a1f0a");
64+
const plist = PlutusList.from_hex("9fd8799fd8799f581ca183bf86925f66c579a3745c9517744399679b090927b8f6e2f2e1bb4f6164617065416d616e734576616e73ffd8799f581c9a4e855293a0b9af5e50935a331d83e7982ab5b738ea0e6fc0f9e6564e4652414d455f38333030325f4c30ff581cbea1c521df58f4eeef60c647e5ebd88c6039915409f9fd6454a476b9ffff");
65+
66+
const hash = hash_script_data(redeemers, costmdls, plist);
67+
68+
expect(hash.to_hex()).toBe("e77f547d8249947bf0af31c432fcfff9c1872b2502b3f34d8107002255695e07");
69+
});
70+
71+
test("Known plutus data hash 2", () => {
72+
73+
const redeemers = Redeemers.from_hex("a182000182d87a808219ef741a01160878");
74+
const costmdls = Costmdls.from_hex("a10098a61a0003236119032c01011903e819023b00011903e8195e7104011903e818201a0001ca761928eb041959d818641959d818641959d818641959d818641959d818641959d81864186418641959d81864194c5118201a0002acfa182019b551041a000363151901ff00011a00015c3518201a000797751936f404021a0002ff941a0006ea7818dc0001011903e8196ff604021a0003bd081a00034ec5183e011a00102e0f19312a011a00032e801901a5011a0002da781903e819cf06011a00013a34182019a8f118201903e818201a00013aac0119e143041903e80a1a00030219189c011a00030219189c011a0003207c1901d9011a000330001901ff0119ccf3182019fd40182019ffd5182019581e18201940b318201a00012adf18201a0002ff941a0006ea7818dc0001011a00010f92192da7000119eabb18201a0002ff941a0006ea7818dc0001011a0002ff941a0006ea7818dc0001011a000c504e197712041a001d6af61a0001425b041a00040c660004001a00014fab18201a0003236119032c010119a0de18201a00033d7618201979f41820197fb8182019a95d1820197df718201995aa18201a0374f693194a1f0a");
75+
const plist = PlutusList.from_hex("9fd8799f581c45f6a506a49a38263c4a8bbb2e1e369dd8732fb1f9a281f3e88383871a03938700581cee8e37676f6ebb8e031dff493f88ff711d24aa68666a09d61f1d3fb34f43727970746f44696e6f3036333039ffff");
76+
77+
const hash = hash_script_data(redeemers, costmdls, plist);
78+
79+
expect(hash.to_hex()).toBe("f3ae8e52bff4c7b8d803469ee61eabf37e96e89f8a3bb80115ad068ab5dff598");
80+
});
81+
82+
test("Known plutus data hash with no datums", () => {
83+
84+
const redeemers = Redeemers.from_hex("a182000082d87980821a000cdcf41a0eab3111");
85+
const costmdls = Costmdls.from_hex("a10198af1a0003236119032c01011903e819023b00011903e8195e7104011903e818201a0001ca761928eb041959d818641959d818641959d818641959d818641959d818641959d81864186418641959d81864194c5118201a0002acfa182019b551041a000363151901ff00011a00015c3518201a000797751936f404021a0002ff941a0006ea7818dc0001011903e8196ff604021a0003bd081a00034ec5183e011a00102e0f19312a011a00032e801901a5011a0002da781903e819cf06011a00013a34182019a8f118201903e818201a00013aac0119e143041903e80a1a00030219189c011a00030219189c011a0003207c1901d9011a000330001901ff0119ccf3182019fd40182019ffd5182019581e18201940b318201a00012adf18201a0002ff941a0006ea7818dc0001011a00010f92192da7000119eabb18201a0002ff941a0006ea7818dc0001011a0002ff941a0006ea7818dc0001011a0011b22c1a0005fdde00021a000c504e197712041a001d6af61a0001425b041a00040c660004001a00014fab18201a0003236119032c010119a0de18201a00033d7618201979f41820197fb8182019a95d1820197df718201995aa18201a0223accc0a1a0374f693194a1f0a1a02515e841980b30a");
86+
const plist = undefined;
87+
88+
const hash = hash_script_data(redeemers, costmdls, plist);
89+
90+
expect(hash.to_hex()).toBe("5b235dbfaa999fb3616da9903d9affd09c7f2121c2d50db7ece0a9fb8587a038");
91+
});
92+
93+
test("No redeemers", () => {
94+
95+
const redeemers = Redeemers.new();
96+
const costmdls = Costmdls.new();
97+
const plist = PlutusList.from_hex("9fd8799fd8799fd8799f581c7fbb4763847b9ec49a132d5359bd86aaecde9275a03aef294ffb79d0ffd8799fd8799fd8799f581cfa34f3b651ecb6a75834c80dc1fd162feb1d1b4cdcef0d065a5785aaffffffffd8799fd8799f581c7fbb4763847b9ec49a132d5359bd86aaecde9275a03aef294ffb79d0ffd8799fd8799fd8799f581cfa34f3b651ecb6a75834c80dc1fd162feb1d1b4cdcef0d065a5785aaffffffffd87a80d8799fd8799f4040ff1a059eb214ff1a001e84801a001e8480ffff");
98+
99+
const hash = hash_script_data(redeemers, costmdls, plist);
100+
101+
expect(hash.to_hex()).toBe("fd53a28a846ae6ccf8b221d03d4af122b0b3c442089c05b87e3d86c6792b3ef0");
102+
});
103+
104+
});
105+
106+
describe("Native scripts hash Tests", () => {
107+
test("Test 1", () => {
108+
109+
const keyhash = Ed25519KeyHash.from_bytes(new Uint8Array([
110+
143, 180, 186, 93, 223, 42, 243, 7, 81, 98, 86, 125, 97, 69, 110, 52, 130, 243, 244, 98,
111+
246, 13, 33, 212, 128, 168, 136, 40,
112+
]));
113+
114+
expect(keyhash.to_hex()).toBe("8fb4ba5ddf2af3075162567d61456e3482f3f462f60d21d480a88828");
115+
116+
const script = NativeScript.new_script_pubkey(ScriptPubkey.new(keyhash));
117+
118+
expect(script.hash().to_hex()).toBe("187b8d3ddcb24013097c003da0b8d8f7ddcf937119d8f59dccd05a0f");
119+
});
120+
121+
test("Test 2", () => {
122+
const script = NativeScript.from_hex("8202838200581c01efb5788e8713c844dfd32b2e91de1e309fefffd555f827cc9ee1648200581c02efb5788e8713c844dfd32b2e91de1e309fefffd555f827cc9ee1648200581c03efb5788e8713c844dfd32b2e91de1e309fefffd555f827cc9ee164")
123+
124+
expect(script.hash().to_hex()).toBe("64f4c8d2f8fb87aab8dadd5c850920e97b1dc23cb735095832df0259");
125+
});
126+
127+
test("Test 3", () => {
128+
const script = NativeScript.from_hex("82028383030182820418848200581c03efb5788e8713c844dfd32b2e91de1e309fefffd555f827cc9ee164820182820518848200581c01efb5788e8713c844dfd32b2e91de1e309fefffd555f827cc9ee1648202838200581c01efb5788e8713c844dfd32b2e91de1e309fefffd555f827cc9ee1648200581c02efb5788e8713c844dfd32b2e91de1e309fefffd555f827cc9ee1648200581c03efb5788e8713c844dfd32b2e91de1e309fefffd555f827cc9ee164")
129+
130+
expect(script.hash().to_hex()).toBe("44b044989c15957d565bb7242f7e3124c38b0cbaac1e53ef028c860f");
131+
});
132+
});

0 commit comments

Comments
 (0)
Please sign in to comment.