Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added README.md #6

Merged
merged 10 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 119 additions & 4 deletions README.md
Shvandre marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,7 +1,122 @@
# TACT template project
# Jetton (Fungible Token) Implementation in Tact

This project has ready to use TACT compiler, typescript + jest with ton-contract-executor, example how to do tests.
## Overview

## Licence
This project includes a complete setup for working with Tact-based Jetton smart contracts. It provides:

MIT
- A pre-configured Tact compiler.
- Smart contracts written in the Tact language.
- TypeScript + Jest testing environment with `@ton/sandbox`.

## Goals

This implementation is fully compatible with the following TON standards:
- [TEP-64](https://github.com/ton-blockchain/TEPs/blob/master/text/0064-token-data-standard.md),
- [TEP-74](https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md),
- [TEP-89](https://github.com/ton-blockchain/TEPs/blob/master/text/0089-jetton-wallet-discovery.md).

You can use this implementation as an alternative to the reference Jetton contracts available in the [TON Blockchain repository](https://github.com/ton-blockchain/token-contract).

## Getting Started

### 1. Install Dependencies

Run the following command to install all required dependencies:

```bash
yarn install
```

### 2. Build Contracts

Compile the smart contracts with:

```bash
yarn build
```

### 3. Deploy Contracts

Customize your Jetton by editing the `contract.deploy.ts` file. This file also includes a detailed deployment guide. Deploy the contracts with:

```bash
yarn deploy
```

### 4. Test Contracts

Run tests in the `@ton/sandbox` environment:

```bash
yarn test
```

## Jetton Architecture

If you’re new to Jettons, read the [TON Jettons Processing](https://docs.ton.org/develop/dapps/asset-processing/jettons).

## Project Structure

Smart contracts, their tests and the deployment script are located in the `sources/` directory:

```
sources/
│ # Contracts and auxiliary Tact code
├── jetton_minter.tact
├── jetton_wallet.tact
├── messages.tact
│ # Tests
├── contract.spec.ts
│ # Deployment script
├── contract.deploy.ts
│ # Miscellaneous utility things
│ # used for tests and deployments
├── contract.read.ts
└── utils/
```

Note, that tests and the deployment script require the compiled contracts to be present in the `sources/output/` directory.

The configuration for the Tact compiler is in `tact.config.json` in the root of the repository. In most cases you won't need to change this file.

## Smart Contracts Structure

The main smart contract is `jetton_minter.tact`, it imports `messages.tact` and `jetton_wallet.tact`. With the default configuration of `tact.config.json` targeting `jetton_minter.tact`, they're all compiled automatically.

### Inherited traits

Jetton Minter uses only *OwnableTransferable*, which is inherited from the *Ownable* trait. Jetton Wallet only uses the *Ownable* trait. All these traits come from the Tact's [standard libraries](https://docs.tact-lang.org/ref/standard-libraries/).

Schemes of inheritance and imports:

```mermaid
graph LR
B[jetton_minter.tact] -->|import| A[messages.tact]
C[jetton_wallet.tact] -->|import| A[messages.tact]
B[jetton_minter.tact] -->|import| C[jetton_wallet.tact]

C[jetton_wallet.tact] -->|uses| E[ownable]
B[jetton_minter.tact] -->|uses| F[ownableTransferable]
F[ownableTransferable] -->|inherits| E[ownable]

class E,F ownableStyle;

classDef ownableStyle stroke-width:2,rx:25,ry:25;

```

Read more about those traits in the [Tact standard library](https://docs.tact-lang.org/ref/standard-libraries/).

## Best Practices

- For guidance on interacting with Jettons using Tact, read the [Jetton cookbook](https://docs.tact-lang.org/cookbook/jettons/).
- Be cautious of fake messages sent by scammers. Read [security best practices](https://docs.tact-lang.org/book/security-best-practices/) to protect yourself from fraudulent activities.
- Always consult the [official Tact documentation](https://docs.tact-lang.org/) for additional resources and support.

## License

This project is licensed under the MIT License.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"dependencies": {
"@aws-crypto/sha256-js": "^5.2.0",
"@nowarp/misti": "~0.5.0",
"@tact-lang/compiler": "~1.5.0",
"@tact-lang/compiler": "^1.5.0",
"@tact-lang/deployer": "^0.2.0",
"@tact-lang/ton-abi": "^0.0.3",
"@tact-lang/ton-jest": "^0.0.4",
Expand All @@ -26,6 +26,7 @@
"dotenv": "^16.4.5",
"enquirer": "^2.3.6",
"jest": "^29.3.1",
"misti": "^0.0.21",
"open": "^8.4.0",
"prando": "^6.0.1",
"prettier": "^2.5.1",
Expand Down
11 changes: 7 additions & 4 deletions sources/contract.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,16 @@ describe("JettonMinter", () => {
notDeployer = await blockchain.treasury('notDeployer');

defaultContent = beginCell().endCell();
let msg: Deploy = {
$$type: "Deploy",
queryId: 0n,
let msg: TokenUpdateContent = {
$$type: "TokenUpdateContent",
content: defaultContent,
}


jettonMinter = blockchain.openContract(await JettonMinter.fromInit(deployer.address, defaultContent));

//We send Update content to deploy the contract, because it is not automatically deployed after blockchain.openContract
//And to deploy it we should send any message. But update content message with same content does not affect anything. That is why I chose it.
const deployResult = await jettonMinter.send(deployer.getSender(), {value: toNano("0.1")}, msg);

expect(deployResult.transactions).toHaveTransaction({
Expand Down Expand Up @@ -553,7 +556,7 @@ describe("JettonMinter", () => {
let sendResult = await deployerJettonWallet.sendTransfer(deployer.getSender(), sentAmount,
sentAmount, someAddress,
deployer.address, null, forwardAmount, forwardPayload);
printTransactionFees(sendResult.transactions);

expect(sendResult.transactions).toHaveTransaction({
from: deployer.address,
to: deployerJettonWallet.address,
Expand Down
2 changes: 1 addition & 1 deletion sources/jetton_minter.tact
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct JettonMasterState {
jettonWalletCode: Cell;
}

contract JettonMinter with OwnableTransferable, Deployable {
contract JettonMinter with OwnableTransferable {
totalSupply: Int as coins;
mintable: Bool;
owner: Address;
Expand Down
Loading