diff --git a/tvm/exit-codes/.gitignore b/tvm/exit-codes/.gitignore new file mode 100644 index 0000000..cf94e93 --- /dev/null +++ b/tvm/exit-codes/.gitignore @@ -0,0 +1,23 @@ +node_modules +temp +build +dist +.DS_Store +package.ts + +# VS Code +.vscode/* +.history/ +*.vsix + +# IDEA files +.idea + +# VIM +Session.vim +.vim/ + +# Other private editor folders +.nvim/ +.emacs/ +.helix/ diff --git a/tvm/exit-codes/.prettierignore b/tvm/exit-codes/.prettierignore new file mode 100644 index 0000000..378eac2 --- /dev/null +++ b/tvm/exit-codes/.prettierignore @@ -0,0 +1 @@ +build diff --git a/tvm/exit-codes/.prettierrc b/tvm/exit-codes/.prettierrc new file mode 100644 index 0000000..24a6660 --- /dev/null +++ b/tvm/exit-codes/.prettierrc @@ -0,0 +1,7 @@ +{ + "printWidth": 120, + "tabWidth": 4, + "singleQuote": true, + "bracketSpacing": true, + "semi": true +} diff --git a/tvm/exit-codes/README.md b/tvm/exit-codes/README.md new file mode 100644 index 0000000..c57e3f0 --- /dev/null +++ b/tvm/exit-codes/README.md @@ -0,0 +1,31 @@ +# TVM Exit Codes Examples + +This repository contains examples of different exit codes for TON blockchain documentation. + +## Project structure + +- `contracts` - source code of all the smart contracts of the project, each demonstrating a specific exit code. +- `wrappers` - wrapper classes (implementing `Contract` from ton-core) for the contracts, including any [de]serialization primitives and compilation functions. +- `tests` - tests for the contracts that verify the correct exit codes are returned. +- `build` - compiled contracts. + +## Exit Codes + +This project demonstrates various exit codes that can occur during smart contract execution in TVM: + +- **Compute Phase Exit Codes**: 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, -14 +- **Action Phase Exit Codes**: 33, 34 + +Each contract file (e.g., `2.tolk`, `3.tolk`) demonstrates how to trigger and handle a specific exit code. + +## How to use + +### Build + +`npx blueprint build` or `yarn blueprint build` + +### Test + +`npx blueprint test` or `yarn blueprint test` + +Tests verify that each contract correctly returns the corresponding exit code when executed. diff --git a/tvm/exit-codes/contracts/-14.tolk b/tvm/exit-codes/contracts/-14.tolk new file mode 100644 index 0000000..92e4e54 --- /dev/null +++ b/tvm/exit-codes/contracts/-14.tolk @@ -0,0 +1,6 @@ +import "@stdlib/gas-payments"; + +fun onInternalMessage() { + setGasLimit(100); +} + diff --git a/tvm/exit-codes/contracts/10.tolk b/tvm/exit-codes/contracts/10.tolk new file mode 100644 index 0000000..880e808 --- /dev/null +++ b/tvm/exit-codes/contracts/10.tolk @@ -0,0 +1,25 @@ +import "@stdlib/tvm-dicts"; + +fun touch(y: T): void asm "NOP" // so that the compiler doesn't remove instructions +fun cast(y: T): U asm "NOP" +fun cell?.addIntToIDict(mutate self, key: int, number: int): void { + return self.iDictSetBuilder(32, key, beginCell().storeInt(number, 32)); +} + +fun onInternalMessage() { + var dict = createEmptyDict(); + dict.addIntToIDict(0, 0); + dict.addIntToIDict(1, 1); + + // The Int to Int dictionary is being misinterpreted as a map + val m: map = cast(dict); + + try { + // And the error happens only when we touch it + touch(m.get(0).isFound); + } catch (exitCode) { + // exitCode is 10 + assert (exitCode == 10) throw 1111; + } +} + diff --git a/tvm/exit-codes/contracts/11.tolk b/tvm/exit-codes/contracts/11.tolk new file mode 100644 index 0000000..d30ff82 --- /dev/null +++ b/tvm/exit-codes/contracts/11.tolk @@ -0,0 +1,12 @@ +fun sendMessage(msg: cell, mode: int): void asm "SENDMSG" + +fun onInternalMessage() { + try { + // fails in the Compute phase when the message is ill-formed + sendMessage(beginCell().endCell(), 0); + } catch (exitCode) { + // exitCode is 11 + assert (exitCode == 11) throw 1111; + } +} + diff --git a/tvm/exit-codes/contracts/2.tolk b/tvm/exit-codes/contracts/2.tolk new file mode 100644 index 0000000..1688a21 --- /dev/null +++ b/tvm/exit-codes/contracts/2.tolk @@ -0,0 +1,11 @@ +fun drop(): void asm "DROP" + +fun onInternalMessage() { + try { + repeat(100){ + drop(); + } + } catch(exitCode) { + assert (exitCode == 2) throw 1111; + } +} diff --git a/tvm/exit-codes/contracts/3.tolk b/tvm/exit-codes/contracts/3.tolk new file mode 100644 index 0000000..f05cb29 --- /dev/null +++ b/tvm/exit-codes/contracts/3.tolk @@ -0,0 +1,19 @@ +// Remember kids, don't try to overflow the stack at home! +fun stackOverflow(): void asm +""" + x{} SLICE // s + BLESS // c + 0 SETNUMARGS // c' + 2 PUSHINT // c' 2 + SWAP // 2 c' + 1 -1 SETCONTARGS // ← this blows up +""" + + +fun onInternalMessage() { + try { + stackOverflow(); + } catch(exitCode) { + assert (exitCode == 3) throw 1111; + } +} diff --git a/tvm/exit-codes/contracts/33.tolk b/tvm/exit-codes/contracts/33.tolk new file mode 100644 index 0000000..da056c4 --- /dev/null +++ b/tvm/exit-codes/contracts/33.tolk @@ -0,0 +1,10 @@ +import "@stdlib/gas-payments"; + +fun onInternalMessage() { + // For example, let's attempt to queue the reservation of a specific amount of nanoToncoins + // This won't fail in the compute phase, but will result in exit code 33 in the action phase + repeat (256) { + reserveToncoinsOnBalance(1000000, RESERVE_MODE_AT_MOST); + } +} + diff --git a/tvm/exit-codes/contracts/34.tolk b/tvm/exit-codes/contracts/34.tolk new file mode 100644 index 0000000..5930298 --- /dev/null +++ b/tvm/exit-codes/contracts/34.tolk @@ -0,0 +1,6 @@ +fun onInternalMessage() { + // For example, let's try to send an ill-formed message: + // won't fail in the compute phase, but will result in exit code 34 in the Action phase + sendRawMessage(beginCell().endCell(), 0); +} + diff --git a/tvm/exit-codes/contracts/4.tolk b/tvm/exit-codes/contracts/4.tolk new file mode 100644 index 0000000..fb6d383 --- /dev/null +++ b/tvm/exit-codes/contracts/4.tolk @@ -0,0 +1,29 @@ +fun touch(y: T): void asm "NOP" // so that the compiler doesn't remove instructions +fun pow2(y: int): int asm "POW2" + +fun onInternalMessage() { + var x = -pow2(255) - pow2(255); + var zero = x - x; + + try { + touch(-x); // integer overflow by negation + // since the max positive value is 2^{256} - 1 + } catch(exitCode) { + // exitCode is 4 + assert (exitCode == 4) throw 1111; + } + + try { + touch(x / zero); // division by zero! + } catch (exitCode) { + // exitCode is 4 + assert (exitCode == 4) throw 1111; + } + + try { + touch(x * x * x); // integer overflow! + } catch (exitCode) { + // exitCode is 4 + assert (exitCode == 4) throw 1111; + } +} diff --git a/tvm/exit-codes/contracts/5.tolk b/tvm/exit-codes/contracts/5.tolk new file mode 100644 index 0000000..8afdca2 --- /dev/null +++ b/tvm/exit-codes/contracts/5.tolk @@ -0,0 +1,55 @@ +fun touch(y: T): void asm "NOP" // so that the compiler doesn't remove instructions +fun pow2(y: int): int asm "POW2" + +fun onInternalMessage() { + try { + // Repeat only operates on an inclusive range from 1 to 2^{31} - 1 + // Any valid integer value greater than that causes an error with exit code 5 + repeat (pow2(55)) { + touch("smash. I. must."); + } + } catch(exitCode) { + // exitCode is 5 + assert (exitCode == 5) throw 1111; + } + + try { + // Builder.storeUint() function can only use up to 256 bits, thus 512 is too much: + touch(beginCell().storeUint(-1, 512).toCell()); + } catch (exitCode) { + // exitCode is 5 + assert (exitCode == 5) throw 1111; + } + + try { + touch(beginCell().storeUint(100, 2).toCell()); // maximum value is 2^{2} - 1 = 3 < 100 + } + catch(exitCode) { + // exitCode is 5 + assert (exitCode == 5) throw 1111; + } + + try { + val deployMsg = createMessage({ + bounce: false, + dest: { + workchain: 0, + stateInit: { + code: beginCell().endCell(), + data: beginCell().endCell(), + }, + toShard: { + fixedPrefixLength: pow2(52), // but fixedPrefixLength is uint5 + closeTo: contract.getAddress() + }, + }, + value: 1, + body: beginCell().endCell(), + }); + + deployMsg.send(SEND_MODE_PAY_FEES_SEPARATELY); + } catch (exitCode) { + // exitCode is 5 + assert (exitCode == 5) throw 1111; + } +} diff --git a/tvm/exit-codes/contracts/6.tolk b/tvm/exit-codes/contracts/6.tolk new file mode 100644 index 0000000..229bec2 --- /dev/null +++ b/tvm/exit-codes/contracts/6.tolk @@ -0,0 +1,11 @@ +// There's no such code page, and an attempt to set it fails +fun invalidOpcode(): void asm "42 SETCP" + +fun onInternalMessage() { + try { + invalidOpcode(); + } catch (exitCode) { + // exitCode is 6 + assert (exitCode == 6) throw 1111; + } +} diff --git a/tvm/exit-codes/contracts/7.tolk b/tvm/exit-codes/contracts/7.tolk new file mode 100644 index 0000000..4802c35 --- /dev/null +++ b/tvm/exit-codes/contracts/7.tolk @@ -0,0 +1,13 @@ +fun touch(y: T): void asm "NOP" // so that the compiler doesn't remove instructions +// The actual returned value type doesn't match the declared one +fun typeCheckError(): cell asm "42 PUSHINT"; + +fun onInternalMessage() { + try { + // it isn't cell + touch(typeCheckError().beginParse()); + } catch (exitCode) { + // exitCode is 7 + assert (exitCode == 7) throw 1111; + } +} \ No newline at end of file diff --git a/tvm/exit-codes/contracts/8.tolk b/tvm/exit-codes/contracts/8.tolk new file mode 100644 index 0000000..b190c5c --- /dev/null +++ b/tvm/exit-codes/contracts/8.tolk @@ -0,0 +1,34 @@ +fun touch(y: T): void asm "NOP" // so that the compiler doesn't remove instructions + +fun onInternalMessage() { + // Too many bits + try { + val data = beginCell() + .storeInt(0, 250) + .storeInt(0, 250) + .storeInt(0, 250) + .storeInt(0, 250) + .storeInt(0, 24) // 1024 bits! + .toCell(); + touch(data); + } catch (exitCode) { + // exitCode is 8 + assert (exitCode == 8) throw 1111; + } + + // Too many refs + try { + val data = beginCell() + .storeRef(beginCell().endCell()) + .storeRef(beginCell().endCell()) + .storeRef(beginCell().endCell()) + .storeRef(beginCell().endCell()) + .storeRef(beginCell().endCell()) // 5 refs! + .toCell(); + touch(data); + } catch (exitCode) { + // exitCode is 8 + assert (exitCode == 8) throw 1111; + } +} + diff --git a/tvm/exit-codes/contracts/9.tolk b/tvm/exit-codes/contracts/9.tolk new file mode 100644 index 0000000..492588d --- /dev/null +++ b/tvm/exit-codes/contracts/9.tolk @@ -0,0 +1,20 @@ +fun touch(y: T): void asm "NOP" // so that the compiler doesn't remove instructions + +fun onInternalMessage() { + // Too few bits + try { + touch(beginCell().endCell().beginParse().loadInt(1)); // 0 bits! + } catch (exitCode) { + // exitCode is 9 + assert (exitCode == 9) throw 1111; + } + + // Too few refs + try { + touch(beginCell().endCell().beginParse().loadRef()); // 0 refs! + } catch (exitCode) { + // exitCode is 9 + assert (exitCode == 9) throw 1111; + } +} + diff --git a/tvm/exit-codes/jest.config.ts b/tvm/exit-codes/jest.config.ts new file mode 100644 index 0000000..b4ae0bf --- /dev/null +++ b/tvm/exit-codes/jest.config.ts @@ -0,0 +1,12 @@ +import type { Config } from 'jest'; + +const config: Config = { + preset: 'ts-jest', + globalSetup: './jest.setup.ts', + cache: false, // disabled caching to prevent old Tact files from being used after a rebuild + testEnvironment: '@ton/sandbox/jest-environment', + testPathIgnorePatterns: ['/node_modules/', '/dist/'], + reporters: ['default', ['@ton/sandbox/jest-reporter', {}]], +}; + +export default config; diff --git a/tvm/exit-codes/jest.setup.ts b/tvm/exit-codes/jest.setup.ts new file mode 100644 index 0000000..6359ede --- /dev/null +++ b/tvm/exit-codes/jest.setup.ts @@ -0,0 +1,5 @@ +import { buildAllTact } from '@ton/blueprint'; + +export default async function () { + await buildAllTact(); +} diff --git a/tvm/exit-codes/package.json b/tvm/exit-codes/package.json new file mode 100644 index 0000000..813958d --- /dev/null +++ b/tvm/exit-codes/package.json @@ -0,0 +1,31 @@ +{ + "name": "Example", + "version": "0.0.1", + "scripts": { + "bp": "blueprint", + "start": "blueprint run", + "build": "blueprint build", + "test": "jest --verbose", + "release": "blueprint pack && npm publish --access public" + }, + "dependencies": { + "@ton/core": "~0" + }, + "devDependencies": { + "@tact-lang/compiler": ">=1.6.13 <2.0.0", + "@ton-community/func-js": ">=0.10.0", + "@ton/blueprint": ">=0.40.0", + "@ton/crypto": "^3.3.0", + "@ton/sandbox": ">=0.37.0", + "@ton/test-utils": ">=0.11.0", + "@ton/tolk-js": "^1.2.0", + "@ton/ton": ">=15.3.1 <16.0.0", + "@types/jest": "^30.0.0", + "@types/node": "^22.17.2", + "jest": "^30.0.5", + "prettier": "^3.6.2", + "ts-jest": "^29.4.1", + "ts-node": "^10.9.2", + "typescript": "^5.9.2" + } +} diff --git a/tvm/exit-codes/tests/main.spec.ts b/tvm/exit-codes/tests/main.spec.ts new file mode 100644 index 0000000..dc7650e --- /dev/null +++ b/tvm/exit-codes/tests/main.spec.ts @@ -0,0 +1,44 @@ +import { Blockchain } from '@ton/sandbox'; +import { toNano } from '@ton/core'; +import '@ton/test-utils'; +import { compile } from '@ton/blueprint'; +import { SimpleContract, simpleContractConfigToCell } from '../wrappers/main'; + +describe('Exit codes', () => { + const computeExitCodes = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, -14]; + + const actionExitCodes = [33, 34]; + + it.each([...computeExitCodes, ...actionExitCodes])(`should return exit code %s`, async (exitCode) => { + const blockchain = await Blockchain.create(); + const deployer = await blockchain.treasury('deployer'); + const code = await compile(`${exitCode}`); + const contract = blockchain.openContract( + SimpleContract.createFromInit({ code, data: simpleContractConfigToCell({}) }, 0), + ); + + const result = await contract.sendDeploy(deployer.getSender(), toNano('10')); + + if (actionExitCodes.includes(exitCode)) { + expect(result.transactions).toHaveTransaction({ + to: contract.address, + deploy: true, + success: false, + actionResultCode: exitCode, + }); + } else if (exitCode === -14) { + expect(result.transactions).toHaveTransaction({ + to: contract.address, + deploy: true, + success: false, + exitCode: -14, + }); + } else { + expect(result.transactions).toHaveTransaction({ + to: contract.address, + deploy: true, + success: true, + }); + } + }); +}); diff --git a/tvm/exit-codes/tsconfig.json b/tvm/exit-codes/tsconfig.json new file mode 100644 index 0000000..9ca3cc9 --- /dev/null +++ b/tvm/exit-codes/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2020", + "outDir": "dist", + "module": "commonjs", + "declaration": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true + } +} diff --git a/tvm/exit-codes/wrappers/-14.compile.ts b/tvm/exit-codes/wrappers/-14.compile.ts new file mode 100644 index 0000000..4867a87 --- /dev/null +++ b/tvm/exit-codes/wrappers/-14.compile.ts @@ -0,0 +1,9 @@ +import { CompilerConfig } from '@ton/blueprint'; + +export const compile: CompilerConfig = { + lang: 'tolk', + entrypoint: 'contracts/-14.tolk', + withStackComments: true, // Fift output will contain comments, if you wish to debug its output + withSrcLineComments: true, // Fift output will contain .tolk lines as comments + experimentalOptions: '', // you can pass experimental compiler options here +}; diff --git a/tvm/exit-codes/wrappers/10.compile.ts b/tvm/exit-codes/wrappers/10.compile.ts new file mode 100644 index 0000000..befa5bc --- /dev/null +++ b/tvm/exit-codes/wrappers/10.compile.ts @@ -0,0 +1,9 @@ +import { CompilerConfig } from '@ton/blueprint'; + +export const compile: CompilerConfig = { + lang: 'tolk', + entrypoint: 'contracts/10.tolk', + withStackComments: true, // Fift output will contain comments, if you wish to debug its output + withSrcLineComments: true, // Fift output will contain .tolk lines as comments + experimentalOptions: '', // you can pass experimental compiler options here +}; diff --git a/tvm/exit-codes/wrappers/11.compile.ts b/tvm/exit-codes/wrappers/11.compile.ts new file mode 100644 index 0000000..b0f1cf3 --- /dev/null +++ b/tvm/exit-codes/wrappers/11.compile.ts @@ -0,0 +1,9 @@ +import { CompilerConfig } from '@ton/blueprint'; + +export const compile: CompilerConfig = { + lang: 'tolk', + entrypoint: 'contracts/11.tolk', + withStackComments: true, // Fift output will contain comments, if you wish to debug its output + withSrcLineComments: true, // Fift output will contain .tolk lines as comments + experimentalOptions: '', // you can pass experimental compiler options here +}; diff --git a/tvm/exit-codes/wrappers/2.compile.ts b/tvm/exit-codes/wrappers/2.compile.ts new file mode 100644 index 0000000..bee6274 --- /dev/null +++ b/tvm/exit-codes/wrappers/2.compile.ts @@ -0,0 +1,9 @@ +import { CompilerConfig } from '@ton/blueprint'; + +export const compile: CompilerConfig = { + lang: 'tolk', + entrypoint: 'contracts/2.tolk', + withStackComments: true, // Fift output will contain comments, if you wish to debug its output + withSrcLineComments: true, // Fift output will contain .tolk lines as comments + experimentalOptions: '', // you can pass experimental compiler options here +}; diff --git a/tvm/exit-codes/wrappers/3.compile.ts b/tvm/exit-codes/wrappers/3.compile.ts new file mode 100644 index 0000000..88011dd --- /dev/null +++ b/tvm/exit-codes/wrappers/3.compile.ts @@ -0,0 +1,9 @@ +import { CompilerConfig } from '@ton/blueprint'; + +export const compile: CompilerConfig = { + lang: 'tolk', + entrypoint: 'contracts/3.tolk', + withStackComments: true, // Fift output will contain comments, if you wish to debug its output + withSrcLineComments: true, // Fift output will contain .tolk lines as comments + experimentalOptions: '', // you can pass experimental compiler options here +}; diff --git a/tvm/exit-codes/wrappers/33.compile.ts b/tvm/exit-codes/wrappers/33.compile.ts new file mode 100644 index 0000000..17993c4 --- /dev/null +++ b/tvm/exit-codes/wrappers/33.compile.ts @@ -0,0 +1,9 @@ +import { CompilerConfig } from '@ton/blueprint'; + +export const compile: CompilerConfig = { + lang: 'tolk', + entrypoint: 'contracts/33.tolk', + withStackComments: true, // Fift output will contain comments, if you wish to debug its output + withSrcLineComments: true, // Fift output will contain .tolk lines as comments + experimentalOptions: '', // you can pass experimental compiler options here +}; diff --git a/tvm/exit-codes/wrappers/34.compile.ts b/tvm/exit-codes/wrappers/34.compile.ts new file mode 100644 index 0000000..b34ce9b --- /dev/null +++ b/tvm/exit-codes/wrappers/34.compile.ts @@ -0,0 +1,9 @@ +import { CompilerConfig } from '@ton/blueprint'; + +export const compile: CompilerConfig = { + lang: 'tolk', + entrypoint: 'contracts/34.tolk', + withStackComments: true, // Fift output will contain comments, if you wish to debug its output + withSrcLineComments: true, // Fift output will contain .tolk lines as comments + experimentalOptions: '', // you can pass experimental compiler options here +}; diff --git a/tvm/exit-codes/wrappers/4.compile.ts b/tvm/exit-codes/wrappers/4.compile.ts new file mode 100644 index 0000000..b5b1b83 --- /dev/null +++ b/tvm/exit-codes/wrappers/4.compile.ts @@ -0,0 +1,9 @@ +import { CompilerConfig } from '@ton/blueprint'; + +export const compile: CompilerConfig = { + lang: 'tolk', + entrypoint: 'contracts/4.tolk', + withStackComments: true, // Fift output will contain comments, if you wish to debug its output + withSrcLineComments: true, // Fift output will contain .tolk lines as comments + experimentalOptions: '', // you can pass experimental compiler options here +}; diff --git a/tvm/exit-codes/wrappers/5.compile.ts b/tvm/exit-codes/wrappers/5.compile.ts new file mode 100644 index 0000000..d105115 --- /dev/null +++ b/tvm/exit-codes/wrappers/5.compile.ts @@ -0,0 +1,9 @@ +import { CompilerConfig } from '@ton/blueprint'; + +export const compile: CompilerConfig = { + lang: 'tolk', + entrypoint: 'contracts/5.tolk', + withStackComments: true, // Fift output will contain comments, if you wish to debug its output + withSrcLineComments: true, // Fift output will contain .tolk lines as comments + experimentalOptions: '', // you can pass experimental compiler options here +}; diff --git a/tvm/exit-codes/wrappers/6.compile.ts b/tvm/exit-codes/wrappers/6.compile.ts new file mode 100644 index 0000000..f08ce69 --- /dev/null +++ b/tvm/exit-codes/wrappers/6.compile.ts @@ -0,0 +1,9 @@ +import { CompilerConfig } from '@ton/blueprint'; + +export const compile: CompilerConfig = { + lang: 'tolk', + entrypoint: 'contracts/6.tolk', + withStackComments: true, // Fift output will contain comments, if you wish to debug its output + withSrcLineComments: true, // Fift output will contain .tolk lines as comments + experimentalOptions: '', // you can pass experimental compiler options here +}; diff --git a/tvm/exit-codes/wrappers/7.compile.ts b/tvm/exit-codes/wrappers/7.compile.ts new file mode 100644 index 0000000..c8a70d0 --- /dev/null +++ b/tvm/exit-codes/wrappers/7.compile.ts @@ -0,0 +1,9 @@ +import { CompilerConfig } from '@ton/blueprint'; + +export const compile: CompilerConfig = { + lang: 'tolk', + entrypoint: 'contracts/7.tolk', + withStackComments: true, // Fift output will contain comments, if you wish to debug its output + withSrcLineComments: true, // Fift output will contain .tolk lines as comments + experimentalOptions: '', // you can pass experimental compiler options here +}; diff --git a/tvm/exit-codes/wrappers/8.compile.ts b/tvm/exit-codes/wrappers/8.compile.ts new file mode 100644 index 0000000..63b681d --- /dev/null +++ b/tvm/exit-codes/wrappers/8.compile.ts @@ -0,0 +1,9 @@ +import { CompilerConfig } from '@ton/blueprint'; + +export const compile: CompilerConfig = { + lang: 'tolk', + entrypoint: 'contracts/8.tolk', + withStackComments: true, // Fift output will contain comments, if you wish to debug its output + withSrcLineComments: true, // Fift output will contain .tolk lines as comments + experimentalOptions: '', // you can pass experimental compiler options here +}; diff --git a/tvm/exit-codes/wrappers/9.compile.ts b/tvm/exit-codes/wrappers/9.compile.ts new file mode 100644 index 0000000..d8c1da6 --- /dev/null +++ b/tvm/exit-codes/wrappers/9.compile.ts @@ -0,0 +1,9 @@ +import { CompilerConfig } from '@ton/blueprint'; + +export const compile: CompilerConfig = { + lang: 'tolk', + entrypoint: 'contracts/9.tolk', + withStackComments: true, // Fift output will contain comments, if you wish to debug its output + withSrcLineComments: true, // Fift output will contain .tolk lines as comments + experimentalOptions: '', // you can pass experimental compiler options here +}; diff --git a/tvm/exit-codes/wrappers/main.ts b/tvm/exit-codes/wrappers/main.ts new file mode 100644 index 0000000..3d411c8 --- /dev/null +++ b/tvm/exit-codes/wrappers/main.ts @@ -0,0 +1,36 @@ +import { Address, beginCell, Cell, Contract, contractAddress, ContractProvider, Sender, SendMode } from '@ton/core'; + +export type SimpleContractConfig = {}; + +export function simpleContractConfigToCell(config: SimpleContractConfig): Cell { + return beginCell().endCell(); +} + +export class SimpleContract implements Contract { + constructor( + readonly address: Address, + readonly init?: { code: Cell; data: Cell }, + ) {} + + static createFromAddress(address: Address) { + return new SimpleContract(address); + } + + static createFromInit(init: { code: Cell; data: Cell }, workchain = 0) { + return new SimpleContract(contractAddress(workchain, init), init); + } + + static createFromConfig(config: SimpleContractConfig, code: Cell, workchain = 0) { + const data = simpleContractConfigToCell(config); + const init = { code, data }; + return new SimpleContract(contractAddress(workchain, init), init); + } + + async sendDeploy(provider: ContractProvider, via: Sender, value: bigint) { + await provider.internal(via, { + value, + sendMode: SendMode.PAY_GAS_SEPARATELY, + body: beginCell().endCell(), + }); + } +}