UNPKG

@ton/core

Version:

Core TypeScript library that implements low level primitives for TON blockchain.

246 lines (216 loc) 14.7 kB
/** * Copyright (c) Whales Corp. * All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import { deserializeBoc, serializeBoc } from "./serialization"; import fs from 'fs'; import { beginCell } from "../Builder"; import { CellType } from "../CellType"; import { exoticPruned } from "./exoticPruned"; import { Cell } from "../Cell"; const wallets: string[] = [ 'B5EE9C72410101010044000084FF0020DDA4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED5441FDF089', 'B5EE9C724101010100530000A2FF0020DD2082014C97BA9730ED44D0D70B1FE0A4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED54D0E2786F', 'B5EE9C7241010101005F0000BAFF0020DD2082014C97BA218201339CBAB19C71B0ED44D0D31FD70BFFE304E0A4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED54B5B86E42', 'B5EE9C724101010100570000AAFF0020DD2082014C97BA9730ED44D0D70B1FE0A4F2608308D71820D31FD31F01F823BBF263ED44D0D31FD3FFD15131BAF2A103F901541042F910F2A2F800029320D74A96D307D402FB00E8D1A4C8CB1FCBFFC9ED54A1370BB6', 'B5EE9C724101010100630000C2FF0020DD2082014C97BA218201339CBAB19C71B0ED44D0D31FD70BFFE304E0A4F2608308D71820D31FD31F01F823BBF263ED44D0D31FD3FFD15131BAF2A103F901541042F910F2A2F800029320D74A96D307D402FB00E8D1A4C8CB1FCBFFC9ED54044CD7A1', 'B5EE9C724101010100620000C0FF0020DD2082014C97BA9730ED44D0D70B1FE0A4F2608308D71820D31FD31FD31FF82313BBF263ED44D0D31FD31FD3FFD15132BAF2A15144BAF2A204F901541055F910F2A3F8009320D74A96D307D402FB00E8D101A4C8CB1FCB1FCBFFC9ED543FBE6EE0', 'B5EE9C724101010100710000DEFF0020DD2082014C97BA218201339CBAB19F71B0ED44D0D31FD31F31D70BFFE304E0A4F2608308D71820D31FD31FD31FF82313BBF263ED44D0D31FD31FD3FFD15132BAF2A15144BAF2A204F901541055F910F2A3F8009320D74A96D307D402FB00E8D101A4C8CB1FCB1FCBFFC9ED5410BD6DAD' ]; describe('boc', () => { it('should parse wallet code', () => { for (let w of wallets) { let c = deserializeBoc(Buffer.from(w, 'hex'))[0]; let b = serializeBoc(c, { idx: false, crc32: true }); let c2 = deserializeBoc(b)[0]; expect(c2.equals(c)).toBe(true); } }); it('should parse largeBoc.txt', () => { let boc = Buffer.from(fs.readFileSync(__dirname + '/__testdata__/largeBoc.txt', 'utf8'), 'base64'); let c = deserializeBoc(boc)[0]; serializeBoc(c, { idx: false, crc32: true }); }); it('should parse manyCells.txt', () => { let boc = Buffer.from(fs.readFileSync(__dirname + '/__testdata__/manyCells.txt', 'utf8'), 'base64'); let c = deserializeBoc(boc)[0]; let b = serializeBoc(c, { idx: false, crc32: true }); let c2 = deserializeBoc(b)[0]; expect(c2.equals(c)).toBe(true); }); it('should parse veryLarge.boc', () => { let boc = fs.readFileSync(__dirname + '/__testdata__/veryLarge.boc'); let c = deserializeBoc(boc)[0]; let b = serializeBoc(c, { idx: false, crc32: true }); let c2 = deserializeBoc(b)[0]; expect(c2.equals(c)).toBe(true); }); it('should parse accountState.txt', () => { let boc = Buffer.from(fs.readFileSync(__dirname + '/__testdata__/accountState.txt', 'utf8'), 'base64'); let c = deserializeBoc(boc)[0]; let b = serializeBoc(c, { idx: false, crc32: true }); let c2 = deserializeBoc(b)[0]; expect(c2.equals(c)).toBe(true); }); it('should parse accountProof.txt', () => { let boc = Buffer.from(fs.readFileSync(__dirname + '/__testdata__/accountProof.txt', 'utf8'), 'base64'); let c = deserializeBoc(boc)[0]; let b = serializeBoc(c, { idx: false, crc32: true }); let c2 = deserializeBoc(b)[0]; expect(c2.equals(c)).toBe(true); }); it('should parse configProof.txt', () => { let boc = Buffer.from(fs.readFileSync(__dirname + '/__testdata__/configProof.txt', 'utf8'), 'base64'); let c = deserializeBoc(boc)[0]; let b = serializeBoc(c, { idx: false, crc32: true }); let c2 = deserializeBoc(b)[0]; expect(c2.equals(c)).toBe(true); }); it('should parse accountStateTest.txt', () => { let boc = Buffer.from(fs.readFileSync(__dirname + '/__testdata__/accountStateTest.txt', 'utf8'), 'base64'); let c = deserializeBoc(boc)[0]; let b = serializeBoc(c, { idx: false, crc32: true }); let c2 = deserializeBoc(b)[0]; expect(c2.equals(c)).toBe(true); }); it('should parse accountStateTestPruned.txt', () => { let boc = Buffer.from(fs.readFileSync(__dirname + '/__testdata__/accountStateTestPruned.txt', 'utf8'), 'base64'); let c = deserializeBoc(boc)[0]; let b = serializeBoc(c, { idx: false, crc32: true }); let c2 = deserializeBoc(b)[0]; expect(c2.equals(c)).toBe(true); }); it('should match pruned state', () => { let prunedBoc = Buffer.from(fs.readFileSync(__dirname + '/__testdata__/accountStateTestPruned.txt', 'utf8'), 'base64'); let pruned = deserializeBoc(prunedBoc)[0]; let fullBoc = Buffer.from(fs.readFileSync(__dirname + '/__testdata__/accountStateTest.txt', 'utf8'), 'base64'); let full = deserializeBoc(fullBoc)[0]; expect(pruned.isExotic).toBe(true); expect(pruned.type).toBe(CellType.MerkleProof); let prunedData = pruned.beginParse(true).loadRef(); // Load refs let sc = full.beginParse(); let fullA = sc.loadRef(); let fullB = sc.loadRef(); let sc2 = prunedData.beginParse(); let prunedA = sc2.loadRef(); let prunedB = sc2.loadRef(); let ppA = exoticPruned(prunedA.bits, prunedA.refs); let ppB = exoticPruned(prunedB.bits, prunedB.refs); // Check hashes expect(ppA.pruned[0].hash).toMatchObject(fullA.hash()); expect(ppB.pruned[0].hash).toMatchObject(fullB.hash()); }); it('should serialize single cell with a empty bits', () => { let cell = beginCell().endCell(); expect(cell.toString()).toBe('x{}'); expect(cell.hash().toString('base64')).toBe('lqKW0iTyhcZ77pPDD4owkVfw2qNdxbh+QQt4YwoJz8c='); expect(serializeBoc(cell, { idx: false, crc32: false }).toString('base64')).toBe('te6ccgEBAQEAAgAAAA=='); expect(serializeBoc(cell, { idx: false, crc32: true }).toString('base64')).toBe('te6cckEBAQEAAgAAAEysuc0='); expect(serializeBoc(cell, { idx: true, crc32: false }).toString('base64')).toBe('te6ccoEBAQEAAgACAAA='); expect(serializeBoc(cell, { idx: true, crc32: true }).toString('base64')).toBe('te6ccsEBAQEAAgACAAC4Afhr'); expect(deserializeBoc(Buffer.from('te6ccgEBAQEAAgAAAA==', 'base64'))[0].equals(cell)).toBe(true); expect(deserializeBoc(Buffer.from('te6cckEBAQEAAgAAAEysuc0=', 'base64'))[0].equals(cell)).toBe(true); expect(deserializeBoc(Buffer.from('te6ccoEBAQEAAgACAAA=', 'base64'))[0].equals(cell)).toBe(true); expect(deserializeBoc(Buffer.from('te6ccsEBAQEAAgACAAC4Afhr', 'base64'))[0].equals(cell)).toBe(true); }); it('should serialize single cell with a number of byte-aligned bits', () => { let cell = beginCell().storeUint(123456789, 32).endCell(); expect(cell.toString()).toBe('x{075BCD15}'); expect(cell.hash().toString('base64')).toBe('keNT38owvINaYYHwYjE1R8HYk0c1NSMH72u+/aMJ+1c='); expect(serializeBoc(cell, { idx: false, crc32: false }).toString('base64')).toBe('te6ccgEBAQEABgAACAdbzRU='); expect(serializeBoc(cell, { idx: false, crc32: true }).toString('base64')).toBe('te6cckEBAQEABgAACAdbzRVRblCS'); expect(serializeBoc(cell, { idx: true, crc32: false }).toString('base64')).toBe('te6ccoEBAQEABgAGAAgHW80V'); expect(serializeBoc(cell, { idx: true, crc32: true }).toString('base64')).toBe('te6ccsEBAQEABgAGAAgHW80ViGH1dQ=='); expect(deserializeBoc(Buffer.from('te6ccgEBAQEABgAACAdbzRU=', 'base64'))[0].equals(cell)).toBe(true); expect(deserializeBoc(Buffer.from('te6cckEBAQEABgAACAdbzRVRblCS', 'base64'))[0].equals(cell)).toBe(true); expect(deserializeBoc(Buffer.from('te6ccoEBAQEABgAGAAgHW80V', 'base64'))[0].equals(cell)).toBe(true); expect(deserializeBoc(Buffer.from('te6ccsEBAQEABgAGAAgHW80ViGH1dQ==', 'base64'))[0].equals(cell)).toBe(true); }); it('should serialize single cell with a number of non-aligned bits', () => { let cell = beginCell().storeUint(123456789, 34).endCell(); expect(cell.toString()).toBe('x{01D6F3456_}'); expect(cell.hash().toString('base64')).toBe('Rk+nt8kkAyN9S1v4H0zwFbGs2INwpMHvESvPQbrI6d0='); expect(serializeBoc(cell, { idx: false, crc32: false }).toString('base64')).toBe('te6ccgEBAQEABwAACQHW80Vg'); expect(serializeBoc(cell, { idx: false, crc32: true }).toString('base64')).toBe('te6cckEBAQEABwAACQHW80Vgb11ZoQ=='); expect(serializeBoc(cell, { idx: true, crc32: false }).toString('base64')).toBe('te6ccoEBAQEABwAHAAkB1vNFYA=='); expect(serializeBoc(cell, { idx: true, crc32: true }).toString('base64')).toBe('te6ccsEBAQEABwAHAAkB1vNFYM0Si3w='); expect(deserializeBoc(Buffer.from('te6ccgEBAQEABwAACQHW80Vg', 'base64'))[0].equals(cell)).toBe(true); expect(deserializeBoc(Buffer.from('te6cckEBAQEABwAACQHW80Vgb11ZoQ==', 'base64'))[0].equals(cell)).toBe(true); expect(deserializeBoc(Buffer.from('te6ccoEBAQEABwAHAAkB1vNFYA==', 'base64'))[0].equals(cell)).toBe(true); expect(deserializeBoc(Buffer.from('te6ccsEBAQEABwAHAAkB1vNFYM0Si3w=', 'base64'))[0].equals(cell)).toBe(true); }); it('should serialize single cell with a single reference', () => { let refCell = beginCell() .storeUint(123456789, 32) .endCell(); let cell = beginCell() .storeUint(987654321, 32) .storeRef(refCell) .endCell(); expect(cell.toString()).toBe('x{3ADE68B1}\n x{075BCD15}'); expect(cell.hash().toString('base64')).toBe('goaQYcsXO2c/gd3qvMo3ncEjzpbU7urNQ7hPDo0qC1c='); expect(serializeBoc(cell, { idx: false, crc32: false }).toString('base64')).toBe('te6ccgEBAgEADQABCDreaLEBAAgHW80V'); expect(serializeBoc(cell, { idx: false, crc32: true }).toString('base64')).toBe('te6cckEBAgEADQABCDreaLEBAAgHW80VSW/75w=='); expect(serializeBoc(cell, { idx: true, crc32: false }).toString('base64')).toBe('te6ccoEBAgEADQAHDQEIOt5osQEACAdbzRU='); expect(serializeBoc(cell, { idx: true, crc32: true }).toString('base64')).toBe('te6ccsEBAgEADQAHDQEIOt5osQEACAdbzRUxP4cd'); expect(deserializeBoc(Buffer.from('te6ccgEBAgEADQABCDreaLEBAAgHW80V', 'base64'))[0].equals(cell)).toBe(true); expect(deserializeBoc(Buffer.from('te6cckEBAgEADQABCDreaLEBAAgHW80VSW/75w==', 'base64'))[0].equals(cell)).toBe(true); expect(deserializeBoc(Buffer.from('te6ccoEBAgEADQAABwEIOt5osQEACAdbzRU=', 'base64'))[0].equals(cell)).toBe(true); expect(deserializeBoc(Buffer.from('te6ccsEBAgEADQAHDQEIOt5osQEACAdbzRUxP4cd', 'base64'))[0].equals(cell)).toBe(true); }); it('should serialize single cell with multiple references', () => { let refCell = beginCell() .storeUint(123456789, 32) .endCell(); let cell = beginCell() .storeUint(987654321, 32) .storeRef(refCell) .storeRef(refCell) .storeRef(refCell) .endCell(); expect(cell.toString()).toBe('x{3ADE68B1}\n x{075BCD15}\n x{075BCD15}\n x{075BCD15}'); expect(cell.hash().toString('base64')).toBe('cks0wbfqFZE9/yb0sWMWQGoj0XBOLkUi+aX5xpJ6jjA='); expect(serializeBoc(cell, { idx: false, crc32: false }).toString('base64')).toBe('te6ccgEBAgEADwADCDreaLEBAQEACAdbzRU='); expect(serializeBoc(cell, { idx: false, crc32: true }).toString('base64')).toBe('te6cckEBAgEADwADCDreaLEBAQEACAdbzRWpQD2p'); expect(serializeBoc(cell, { idx: true, crc32: false }).toString('base64')).toBe('te6ccoEBAgEADwAJDwMIOt5osQEBAQAIB1vNFQ=='); expect(serializeBoc(cell, { idx: true, crc32: true }).toString('base64')).toBe('te6ccsEBAgEADwAJDwMIOt5osQEBAQAIB1vNFZz9usI='); expect(deserializeBoc(Buffer.from('te6ccgEBAgEADwADCDreaLEBAQEACAdbzRU=', 'base64'))[0].equals(cell)).toBe(true); expect(deserializeBoc(Buffer.from('te6cckEBAgEADwADCDreaLEBAQEACAdbzRWpQD2p', 'base64'))[0].equals(cell)).toBe(true); expect(deserializeBoc(Buffer.from('te6ccoEBAgEADwAACQMIOt5osQEBAQAIB1vNFQ==', 'base64'))[0].equals(cell)).toBe(true); expect(deserializeBoc(Buffer.from('te6ccsEBAgEADwAJDwMIOt5osQEBAQAIB1vNFZz9usI=', 'base64'))[0].equals(cell)).toBe(true); }); it('should deserialize/serialize library cell', () => { let cell = Cell.fromBase64('te6ccgEBAgEALQABDv8AiNDtHtgBCEICGbgzd5nhZ9WhSM+4juFCvgMYJOtxthFdtTKIH6M/6SM='); expect(cell.toString()).toBe('x{FF0088D0ED1ED8}\n x{0219B8337799E167D5A148CFB88EE142BE031824EB71B6115DB532881FA33FE923}'); expect(serializeBoc(cell, { idx: false, crc32: false }).toString('base64')).toBe('te6ccgEBAgEALQABDv8AiNDtHtgBCEICGbgzd5nhZ9WhSM+4juFCvgMYJOtxthFdtTKIH6M/6SM='); }); it('should deserialize block (#21)', () => { let testCase = fs.readFileSync(__dirname + '/__testdata__/block.txt', 'utf8'); let cell = Cell.fromBase64(testCase); }); it('should hash tx with merkle body', () => { let testCase = JSON.parse(fs.readFileSync(__dirname + '/__testdata__/tx_with_merkle_body.json', 'utf8')); let boc = Buffer.from(testCase.boc, 'hex'); let cell = Cell.fromBoc(boc)[0]; expect(cell.hash().toString('hex')).toBe(testCase.hash); }); it('should deserialize block 2', () => { let testCase = fs.readFileSync(__dirname + '/__testdata__/block2.txt', 'utf8'); let cell = Cell.fromBase64(testCase); expect(cell.hash().toString('hex')).toBe('25e19f8c4574804a8cabade6bab736a27a67f4f6696a8a0feb93b3dfbfab7fcf'); }); it('should serialize boc with index', () => { let cell = beginCell() .storeUint(228, 32) .storeRef(beginCell().storeUint(1337, 32).endCell()) .storeRef(beginCell().storeUint(1338, 32).endCell()) .endCell(); let serialized = cell.toBoc({ idx: true, crc32: false }).toString('hex'); expect(cell.toString()).toBe('x{000000E4}\n x{00000539}\n x{0000053A}'); expect(serialized).toBe('b5ee9c7281010301001400080e140208000000e4010200080000053900080000053a'); }); });