Skip to content

Commit f921352

Browse files
committed
complete decompile
1 parent 1fd9baa commit f921352

File tree

8 files changed

+287
-302
lines changed

8 files changed

+287
-302
lines changed

.eslintignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
node_modules/
22
dist/
33
www/
4+
src/
+99-240
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
// import { parseCalldataField } from '../../src/utils/calldata/requestParser';
2-
// import { decodeCalldataField } from '../../src/utils/calldata/calldataDecoder';
3-
// import assert from '../../src/utils/assert';
4-
// import { CairoFelt } from '../../src/utils/cairoDataTypes/felt';
5-
// import { AbiEnums, AbiStructs } from '../../src/types';
1+
import { DecodeConfig } from '../../src/types';
62

73
import {
84
// Account,
95
BigNumberish,
6+
CairoUint256,
107
// CairoCustomEnum,
118
// CairoOption,
129
// CairoOptionVariant,
@@ -25,261 +22,123 @@ import {
2522
cairo,
2623
// ec,
2724
// hash,
28-
num,
25+
// num,
2926
// selector,
3027
// shortString,
3128
// stark,
3229
// types,
3330
// type Uint512,
3431
} from '../../src';
3532

36-
import { compiledC1v2, compiledHelloSierra, compiledComplexSierra } from '../config/fixtures';
37-
38-
// import { initializeMatcher } from '../../config/schema';
33+
import {
34+
// compiledC1v2,
35+
// compiledHelloSierra,
36+
compiledComplexSierra,
37+
} from '../config/fixtures';
3938

4039
const {
4140
// uint256,
4241
tuple,
4342
// isCairo1Abi
4443
} = cairo;
45-
// const { toHex } = num;
46-
// const { starknetKeccak } = selector;
4744

4845
describe('Cairo 1', () => {
49-
describe('API and contract interactions', () => {
50-
test('myCallData.compile for Cairo 1', async () => {
51-
const myFalseUint256 = { high: 1, low: 23456 }; // wrong order
52-
type Order2 = {
53-
p1: BigNumberish;
54-
p2: BigNumberish[];
55-
};
46+
test('should correctly compile and decompile complex data structures', async () => {
47+
type Order2 = {
48+
p1: BigNumberish;
49+
p2: BigNumberish[];
50+
};
5651

57-
const myOrder2bis: Order2 = {
58-
// wrong order
59-
p2: [234, 467456745457n, '0x56ec'],
60-
p1: '17',
61-
};
62-
const myRawArgsObject: RawArgsObject = {
63-
// wrong order
64-
active: true,
65-
symbol: 'NIT',
66-
initial_supply: myFalseUint256,
67-
recipient: '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a',
68-
decimals: 18,
69-
tupoftup: tuple(tuple(34, '0x5e'), myFalseUint256),
70-
card: myOrder2bis,
71-
longText: 'Bug is back, for ever, here and everywhere',
72-
array1: [100, 101, 102],
73-
array2: [
74-
[200, 201],
75-
[202, 203],
76-
[204, 205],
77-
],
78-
array3: [myOrder2bis, myOrder2bis],
79-
array4: [myFalseUint256, myFalseUint256],
80-
tuple1: tuple(40000n, myOrder2bis, [54, 55n, '0xae'], 'texte'),
81-
name: 'niceToken',
82-
array5: [tuple(251, 40000n), tuple(252, 40001n)],
83-
};
84-
const myRawArgsArray: RawArgsArray = [
85-
'niceToken',
86-
'NIT',
87-
18,
88-
{ low: 23456, high: 1 },
89-
{ p1: '17', p2: [234, 467456745457n, '0x56ec'] },
90-
'0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a',
91-
true,
92-
{ '0': { '0': 34, '1': '0x5e' }, '1': { low: 23456, high: 1 } },
93-
'Bug is back, for ever, here and everywhere',
94-
[100, 101, 102],
95-
[
96-
[200, 201],
97-
[202, 203],
98-
[204, 205],
99-
],
100-
[
101-
{ p1: '17', p2: [234, 467456745457n, '0x56ec'] },
102-
{ p1: '17', p2: [234, 467456745457n, '0x56ec'] },
103-
],
104-
[
105-
{ low: 23456, high: 1 },
106-
{ low: 23456, high: 1 },
107-
],
108-
{
109-
'0': 40000n,
110-
'1': { p1: '17', p2: [234, 467456745457n, '0x56ec'] },
111-
'2': [54, 55n, '0xae'],
112-
'3': 'texte',
113-
},
114-
[
115-
{ '0': 251, '1': 40000n },
116-
{ '0': 252, '1': 40001n },
117-
],
118-
];
52+
const myOrder2bis: Order2 = {
53+
// wrong order
54+
p2: ['abcd', '56ec'],
55+
p1: 'smolstring',
56+
};
11957

120-
const contractCallData: CallData = new CallData(compiledComplexSierra.abi);
121-
const callDataFromObject: Calldata = contractCallData.compile('constructor', myRawArgsObject);
122-
const callDataFromArray: Calldata = contractCallData.compile('constructor', myRawArgsArray);
123-
const expectedResult = [
124-
'2036735872918048433518',
125-
'5130580',
126-
'18',
127-
'23456',
128-
'1',
129-
'17',
130-
'3',
131-
'234',
132-
'467456745457',
133-
'22252',
134-
'3562055384976875123115280411327378123839557441680670463096306030682092229914',
135-
'1',
136-
'34',
137-
'94',
138-
'23456',
139-
'1',
140-
'2',
141-
'117422190885827407409664260607192623408641871979684112605616397634538401380',
142-
'39164769268277364419555941',
143-
'3',
144-
'100',
145-
'101',
146-
'102',
147-
'3',
148-
'2',
149-
'200',
150-
'201',
151-
'2',
152-
'202',
153-
'203',
154-
'2',
155-
'204',
156-
'205',
157-
'2',
158-
'17',
159-
'3',
160-
'234',
161-
'467456745457',
162-
'22252',
163-
'17',
164-
'3',
165-
'234',
166-
'467456745457',
167-
'22252',
168-
'2',
169-
'23456',
170-
'1',
171-
'23456',
172-
'1',
173-
'40000',
174-
'0',
175-
'17',
176-
'3',
177-
'234',
178-
'467456745457',
179-
'22252',
180-
'3',
181-
'54',
182-
'55',
183-
'174',
184-
'499918599269',
185-
'2',
186-
'251',
187-
'40000',
188-
'252',
189-
'40001',
190-
];
191-
expect(callDataFromObject).toStrictEqual(expectedResult);
192-
expect(callDataFromArray).toStrictEqual(expectedResult);
193-
});
58+
const secondUint256: CairoUint256 = new CairoUint256(40000n);
59+
const tempUint256 = { low: 23456n, high: 1n } as CairoUint256;
60+
const thirdUint256: CairoUint256 = new CairoUint256(tempUint256);
61+
const myFalseUint256: CairoUint256 = thirdUint256; // wrong order
19462

195-
test('myCallData.decodeParameters for Cairo 1', async () => {
196-
const Cairo1HelloAbi = compiledHelloSierra;
197-
const Cairo1Abi = compiledC1v2;
198-
const helloCallData = new CallData(Cairo1HelloAbi.abi);
199-
const c1v2CallData = new CallData(Cairo1Abi.abi);
63+
const myRawArgsObject: RawArgsObject = {
64+
// wrong order
65+
active: true,
66+
symbol: 'NIT',
67+
initial_supply: myFalseUint256,
68+
recipient: '0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a',
69+
decimals: 18,
70+
tupoftup: tuple(tuple(34, 94), myFalseUint256),
71+
card: myOrder2bis,
72+
longText: 'Bug is back, for ever, here and everywhere',
73+
array1: [100, 101, 102],
74+
array2: [
75+
[200, 201],
76+
[202, 203],
77+
[204, 205],
78+
],
79+
array3: [myOrder2bis, myOrder2bis],
80+
array4: [myFalseUint256, myFalseUint256],
81+
tuple1: tuple(secondUint256, myOrder2bis, [54, 55, 174], 59),
82+
name: 'niceToken',
83+
array5: [tuple(251, 40000), tuple(252, 40001)],
84+
};
20085

201-
const res2 = helloCallData.decodeParameters('hello::hello::UserData', ['0x123456', '0x1']);
202-
expect(res2).toEqual({ address: 1193046n, is_claimed: true });
203-
const res3 = helloCallData.decodeParameters(
204-
['hello::hello::UserData', 'hello::hello::UserData'],
205-
['0x123456', '0x1', '0x98765', '0x0']
206-
);
207-
expect(res3).toEqual([
208-
{ address: 1193046n, is_claimed: true },
209-
{ address: 624485n, is_claimed: false },
210-
]);
211-
const res4 = helloCallData.decodeParameters('core::integer::u8', ['0x123456']);
212-
expect(res4).toBe(1193046n);
213-
const res5 = helloCallData.decodeParameters('core::bool', ['0x1']);
214-
expect(res5).toBe(true);
215-
const res6 = helloCallData.decodeParameters('core::felt252', ['0x123456']);
216-
expect(res6).toBe(1193046n);
217-
const res7 = helloCallData.decodeParameters('core::integer::u256', ['0x123456', '0x789']);
218-
expect(num.toHex(res7.toString())).toBe('0x78900000000000000000000000000123456');
219-
const res8 = helloCallData.decodeParameters('core::array::Array::<core::integer::u16>', [
220-
'2',
221-
'0x123456',
222-
'0x789',
223-
]);
224-
expect(res8).toEqual([1193046n, 1929n]);
225-
const res9 = helloCallData.decodeParameters('core::array::Span::<core::integer::u16>', [
226-
'2',
227-
'0x123456',
228-
'0x789',
229-
]);
230-
expect(res9).toEqual([1193046n, 1929n]);
231-
const res10 = helloCallData.decodeParameters('(core::felt252, core::integer::u16)', [
232-
'0x123456',
233-
'0x789',
234-
]);
235-
expect(res10).toEqual({ '0': 1193046n, '1': 1929n });
236-
const res11 = helloCallData.decodeParameters('core::starknet::eth_address::EthAddress', [
237-
'0x123456',
238-
]);
239-
expect(res11).toBe(1193046n);
240-
const res12 = helloCallData.decodeParameters(
241-
'core::starknet::contract_address::ContractAddress',
242-
['0x123456']
243-
);
244-
expect(res12).toBe(1193046n);
245-
const res13 = helloCallData.decodeParameters('core::starknet::class_hash::ClassHash', [
246-
'0x123456',
247-
]);
248-
expect(res13).toBe(1193046n);
249-
const res14 = c1v2CallData.decodeParameters('core::option::Option::<core::integer::u8>', [
250-
'0',
251-
'0x12',
252-
]);
253-
expect(res14).toEqual({ Some: 18n, None: undefined });
254-
const res15 = c1v2CallData.decodeParameters(
255-
'core::result::Result::<hello_res_events_newTypes::hello_res_events_newTypes::Order, core::integer::u16>',
256-
['0', '0x12', '0x345']
257-
);
258-
expect(res15).toEqual({ Ok: { p1: 18n, p2: 837n }, Err: undefined });
259-
const res16 = c1v2CallData.decodeParameters(
260-
'hello_res_events_newTypes::hello_res_events_newTypes::MyEnum',
261-
['0', '0x12', '0x5678']
262-
);
263-
expect(res16).toEqual({
264-
variant: {
265-
Response: { p1: 18n, p2: 22136n },
266-
Warning: undefined,
267-
Error: undefined,
268-
},
269-
});
270-
});
271-
});
86+
const myRawArgsArray: RawArgsArray = [
87+
'niceToken',
88+
'NIT',
89+
18,
90+
thirdUint256,
91+
{ p1: '17', p2: ['234', '467456745457', '0x56ec'] },
92+
'0x7e00d496e324876bbc8531f2d9a82bf154d1a04a50218ee74cdd372f75a551a',
93+
true,
94+
{ '0': { '0': 34, '1': 94 }, '1': thirdUint256 },
95+
'Bug is back, for ever, here and everywhere',
96+
['100', '101', '102'],
97+
[
98+
[200, 201],
99+
[202, 203],
100+
[204, 205],
101+
],
102+
[
103+
{ p1: '17', p2: ['234', '467456745457n', '0x56ec'] },
104+
{ p1: '17', p2: ['234', '467456745457n', '0x56ec'] },
105+
],
106+
[thirdUint256, thirdUint256],
107+
{
108+
'0': secondUint256,
109+
'1': { p1: '17', p2: ['234', '467456745457n', '0x56ec'] },
110+
'2': [54, 55, 56],
111+
'3': 59,
112+
},
113+
[
114+
{ '0': 251, '1': 40000 },
115+
{ '0': 252, '1': 40001 },
116+
],
117+
];
272118

273-
test('should correctly compile and decompile complex data structures', async () => {
274-
// const complexData = {
275-
// id: CairoFelt(1),
276-
// name: 'Alice',
277-
// transactions: [{ amount: 100, timestamp: '1625235962' }],
278-
// isActive: true,
279-
// };
119+
const config: DecodeConfig = {
120+
felt: String,
121+
'core::felt252': String,
122+
'core::integer::u8': Number,
123+
'core::integer::u16': Number,
124+
'core::integer::u64': Number,
125+
'core::integer::u128': BigInt,
126+
'core::starknet::contract_address::ContractAddress': String,
127+
longText: String,
128+
};
129+
130+
const cd: CallData = new CallData(compiledComplexSierra.abi);
131+
const compiledDataFromObject: Calldata = cd.compile('constructor', myRawArgsObject);
132+
const compiledDataFromArray: Calldata = cd.compile('constructor', myRawArgsArray);
133+
const decompiledDataFromObject = cd.decompile('constructor', compiledDataFromObject, config);
134+
const decompiledDataFromArray = cd.decompile(
135+
'constructor',
136+
compiledDataFromArray,
137+
config,
138+
true
139+
);
280140

281-
const cd = new CallData(compiledComplexSierra.abi);
282-
const compiledData = cd.compile('calldata', ['0x34a', [1, 3n]]);
283-
console.log(compiledData);
141+
expect(decompiledDataFromObject).toEqual(myRawArgsObject);
142+
expect(decompiledDataFromArray).toEqual(myRawArgsArray);
284143
});
285144
});

src/types/lib/contract/abi.ts

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { Uint256 } from '..';
2+
13
/** ABI */
24
export type Abi = ReadonlyArray<FunctionAbi | EventAbi | StructAbi | any>;
35

@@ -56,3 +58,8 @@ export type LegacyEvent = {
5658
data: EventEntry[];
5759
keys: EventEntry[];
5860
};
61+
62+
type JSCDataType = StringConstructor | NumberConstructor | BigIntConstructor | BooleanConstructor;
63+
export type DecodeConfig = {
64+
[typeName: string]: JSCDataType;
65+
};

0 commit comments

Comments
 (0)